Stripped from the internal repo: per-box deploy trees, Go services (nodelist/astmeta/proxy/svxdr), deploy/sync scripts and all secrets. Config templates for nginx, PHP-FPM, Redis and tmpfiles live in install/ with CHANGEME placeholders. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
97 lines
3.8 KiB
PHP
97 lines
3.8 KiB
PHP
#!/usr/bin/env php
|
|
<?php
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* svx-mkadmin.php — interaktiv provisionering av ett SvxPortal-konto (t.ex. admin).
|
|
*
|
|
* Återanvänder portalens EGEN auth/lib.php, så redis-anslutning (socket/lösen/db),
|
|
* nyckelprefix, uuid-generering, callsign-normalisering och lösenordshashning
|
|
* (password_hash PASSWORD_DEFAULT) blir identiska med signup.php. Inget hårdkodas.
|
|
*
|
|
* Kör på servern, från prompten:
|
|
* php svx-mkadmin.php
|
|
*
|
|
* Lib-sökväg (default = deployad portal) kan överstyras:
|
|
* SVXPORTAL_LIB=/annan/väg/lib.php php svx-mkadmin.php
|
|
* php svx-mkadmin.php /annan/väg/lib.php
|
|
*/
|
|
|
|
if (PHP_SAPI !== 'cli') { fwrite(STDERR, "Kör från kommandoraden.\n"); exit(1); }
|
|
if (!extension_loaded('redis')) { fwrite(STDERR, "PHP-tillägget 'redis' saknas.\n"); exit(1); }
|
|
|
|
$LIB = getenv('SVXPORTAL_LIB') ?: ($argv[1] ?? '/var/www/html/svxportal/auth/lib.php');
|
|
if (!is_file($LIB)) { fwrite(STDERR, "Hittar inte lib.php: $LIB\n(ange via SVXPORTAL_LIB eller som argument)\n"); exit(1); }
|
|
require $LIB; // ger cfg(), redis(), rkey(), uuidv4(), base_call(), norm_email(), *_key()
|
|
|
|
function ask(string $label, string $def = ''): string {
|
|
fwrite(STDOUT, $label . ($def !== '' ? " [$def]" : '') . ': ');
|
|
$v = rtrim((string)fgets(STDIN), "\n");
|
|
return $v !== '' ? $v : $def;
|
|
}
|
|
function ask_secret(string $label): string {
|
|
fwrite(STDOUT, $label . ': ');
|
|
shell_exec('stty -echo 2>/dev/null');
|
|
$v = rtrim((string)fgets(STDIN), "\n");
|
|
shell_exec('stty echo 2>/dev/null');
|
|
fwrite(STDOUT, "\n");
|
|
return $v;
|
|
}
|
|
function fail(string $msg): void { fwrite(STDERR, "FEL: $msg\n"); exit(1); }
|
|
|
|
$c = cfg()['redis'] ?? [];
|
|
fwrite(STDOUT, "Redis: " . ($c['unix_socket'] ?? ($c['host'] ?? '?')) .
|
|
" prefix='" . ($c['prefix'] ?? '') . "' (från " . $LIB . ")\n\n");
|
|
|
|
$r = redis();
|
|
|
|
/* --- Callsign (samma regler som signup.php) --- */
|
|
$cs = base_call(ask('Callsign'));
|
|
if (strlen($cs) < 3 || strlen($cs) > 10 || !preg_match('/^[A-Z0-9]+$/', $cs)) {
|
|
fail('Callsign måste vara 3-10 tecken A-Z/0-9.');
|
|
}
|
|
if ((string)$r->get(call_index_key($cs)) !== '') fail("Callsign $cs finns redan.");
|
|
|
|
/* --- Profil --- */
|
|
$first = ask('Förnamn');
|
|
$last = ask('Efternamn');
|
|
$email = norm_email(ask('E-post'));
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) fail('Ogiltig e-postadress.');
|
|
if ((string)$r->get(email_index_key($email)) !== '') fail("E-posten $email finns redan.");
|
|
$city = ask('Stad', '');
|
|
$state = ask('Region/State', '');
|
|
$country = ask('Land', '');
|
|
|
|
/* --- Adminnivå (1=vanlig, 2=admin, 3=super; jfr acct_admin_level/require_admin) --- */
|
|
$level = (int)ask('admin_level (1-3)', '3');
|
|
if ($level < 1 || $level > 3) fail('admin_level måste vara 1-3.');
|
|
|
|
/* --- Lösenord (dolt, dubbelt) --- */
|
|
$p1 = ask_secret('Lösenord');
|
|
$p2 = ask_secret('Lösenord igen');
|
|
if ($p1 !== $p2) fail('Lösenorden matchar inte.');
|
|
if (strlen($p1) < 6) fail('Lösenord måste vara minst 6 tecken.');
|
|
|
|
/* --- Skapa konto + index (samma layout som signup.php) --- */
|
|
$uuid = uuidv4();
|
|
$r->hMSet(acct_key($uuid), [
|
|
'callsign' => $cs,
|
|
'firstname' => $first,
|
|
'lastname' => $last,
|
|
'shortname' => $first,
|
|
'email' => $email,
|
|
'city' => $city,
|
|
'state' => $state,
|
|
'country' => $country,
|
|
'password_hash' => password_hash($p1, PASSWORD_DEFAULT),
|
|
'email_verified' => '1', // admin-provisionering: hoppa över mejlverifiering
|
|
'admin_level' => (string)$level,
|
|
'created_at' => (string)time(),
|
|
]);
|
|
$r->set(call_index_key($cs), $uuid);
|
|
$r->set(email_index_key($email), $uuid);
|
|
|
|
fwrite(STDOUT, "\nOK: konto '$cs' skapat (admin_level $level)\n");
|
|
fwrite(STDOUT, " uuid = $uuid\n");
|
|
fwrite(STDOUT, " logga in med callsign eller e-post + lösenordet ovan.\n");
|