- cja_admin + cja_admin_log tables (dedicated single-admin tier + audit trail) - AdminAuth controller: /api/adminauth login/logout/me, session-based, rate-limited, every attempt logged - set-admin-password CLI (bcrypt, run manually so the password never enters an agent context) - requireAdmin() guard for future privileged console endpoints - agent env scaffold (git-ignored) Foundation only — no agent runner or features yet. Preview/publish, media, and the dashboard come in phases 1-3 per agents/console/PLAN.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DoFYZY9gkGPNDqZ7NuEa9a
35 lines
1.1 KiB
PHP
35 lines
1.1 KiB
PHP
<?php
|
|
/**
|
|
* Set (or reset) the console admin password. Run it yourself so the password
|
|
* never enters an agent's context:
|
|
*
|
|
* php api/cli/set-admin-password.php <username> <password>
|
|
*
|
|
* Upserts on username. The plaintext is hashed with bcrypt and never stored.
|
|
*/
|
|
|
|
require __DIR__ . '/../vendor/autoload.php';
|
|
require __DIR__ . '/../config.php';
|
|
|
|
$username = $argv[1] ?? '';
|
|
$password = $argv[2] ?? '';
|
|
|
|
if ($username === '' || $password === '') {
|
|
fwrite(STDERR, "usage: php api/cli/set-admin-password.php <username> <password>\n");
|
|
exit(1);
|
|
}
|
|
if (strlen($password) < 12) {
|
|
fwrite(STDERR, "Refusing: use at least 12 characters.\n");
|
|
exit(1);
|
|
}
|
|
|
|
$hash = password_hash($password, PASSWORD_DEFAULT);
|
|
|
|
$existing = Db::getValue('SELECT admin_id FROM cja_admin WHERE username = ?', [$username]);
|
|
if ($existing) {
|
|
Db::update('cja_admin', ['password_hash' => $hash], 'admin_id = ?', [$existing]);
|
|
echo " updated password for '{$username}'\n";
|
|
} else {
|
|
Db::insert('cja_admin', ['username' => $username, 'password_hash' => $hash]);
|
|
echo " created admin '{$username}'\n";
|
|
}
|