| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #!/usr/bin/env php
- <?php
- declare(strict_types=1);
- use App\App\Container;
- use App\Domain\Auth\Role;
- use App\Domain\Auth\TokenHasher;
- use App\Domain\Auth\TokenIssuer;
- use App\Domain\Auth\TokenKind;
- use App\Infrastructure\Auth\ServiceTokenBootstrap;
- use App\Infrastructure\Auth\TokenRecord;
- use App\Infrastructure\Auth\TokenRepository;
- require __DIR__ . '/../vendor/autoload.php';
- $argv = $_SERVER['argv'] ?? [];
- $command = $argv[1] ?? null;
- $phinxBin = __DIR__ . '/../vendor/bin/phinx';
- $phinxConfig = __DIR__ . '/../config/phinx.php';
- $run = static function (string $phinxCommand) use ($phinxBin, $phinxConfig): never {
- $cmd = sprintf(
- '%s %s --configuration=%s',
- escapeshellarg($phinxBin),
- $phinxCommand,
- escapeshellarg($phinxConfig)
- );
- passthru($cmd, $exitCode);
- exit($exitCode);
- };
- /**
- * @param array<int, string> $argv
- */
- $flag = static function (array $argv, string $name): ?string {
- $prefix = '--' . $name . '=';
- foreach ($argv as $arg) {
- if (str_starts_with($arg, $prefix)) {
- return substr($arg, strlen($prefix));
- }
- }
- return null;
- };
- /**
- * @param array<int, string> $argv
- */
- $hasFlag = static function (array $argv, string $name): bool {
- return in_array('--' . $name, $argv, true);
- };
- switch ($command) {
- case 'db:migrate':
- $run('migrate');
- // no break
- case 'db:rollback':
- $run('rollback');
- // no break
- case 'db:seed':
- $run('seed:run');
- // no break
- case 'auth:bootstrap-service-token':
- $container = Container::build();
- /** @var ServiceTokenBootstrap $boot */
- $boot = $container->get(ServiceTokenBootstrap::class);
- /** @var string $rawToken */
- $rawToken = $container->get('settings.ui_service_token');
- $boot->bootstrap($rawToken);
- exit(0);
- case 'auth:create-token':
- $kindArg = $flag($argv, 'kind') ?? '';
- $roleArg = $flag($argv, 'role');
- $quiet = $hasFlag($argv, 'quiet');
- $kind = TokenKind::tryFrom($kindArg);
- if ($kind === null) {
- fwrite(STDERR, "Unknown --kind: {$kindArg}. Admin tokens are the only kind supported here.\n");
- exit(1);
- }
- if ($kind === TokenKind::Service) {
- fwrite(STDERR, "Refusing to create a service token via this command. Use UI_SERVICE_TOKEN + auth:bootstrap-service-token.\n");
- exit(1);
- }
- if ($kind === TokenKind::Reporter || $kind === TokenKind::Consumer) {
- fwrite(STDERR, "Reporter/consumer tokens are bound to records and are issued via M04 endpoints, not this CLI.\n");
- exit(1);
- }
- // kind=admin from here on.
- $role = $roleArg !== null ? Role::tryFrom(strtolower($roleArg)) : null;
- if ($role === null) {
- fwrite(STDERR, "Admin tokens require --role=viewer|operator|admin.\n");
- exit(1);
- }
- $container = Container::build();
- /** @var TokenIssuer $issuer */
- $issuer = $container->get(TokenIssuer::class);
- /** @var TokenHasher $hasher */
- $hasher = $container->get(TokenHasher::class);
- /** @var TokenRepository $repo */
- $repo = $container->get(TokenRepository::class);
- $raw = $issuer->issue(TokenKind::Admin);
- $hash = $hasher->hash($raw);
- $repo->create(new TokenRecord(
- id: null,
- kind: TokenKind::Admin,
- hash: $hash,
- prefix: substr($raw, 0, 8),
- reporterId: null,
- consumerId: null,
- role: $role,
- expiresAt: null,
- revokedAt: null,
- lastUsedAt: null,
- ));
- if ($quiet) {
- fwrite(STDOUT, $raw);
- } else {
- fwrite(STDOUT, $raw . "\n");
- fwrite(STDERR, "Created admin token (role={$role->value}). The token is only shown once.\n");
- }
- exit(0);
- case null:
- case '--help':
- case '-h':
- fwrite(STDOUT, <<<TXT
- Usage: console <command>
- Commands:
- db:migrate Run Phinx migrations
- db:rollback Roll back the most recent migration
- db:seed Run all seeders idempotently
- auth:bootstrap-service-token Provision UI_SERVICE_TOKEN row in api_tokens
- auth:create-token --kind=admin --role=admin|operator|viewer [--quiet]
- Create an admin token; raw token printed to stdout
- TXT);
- exit(0);
- default:
- fwrite(STDERR, "Unknown command: {$command}\n");
- exit(1);
- }
|