del(call_index_key($old_cs)); redis()->set(call_index_key($new_cs), $uuid); } } if (isset($updates['email'])) { $old_em = strtolower(trim($me['email'] ?? '')); $new_em = norm_email($updates['email']); $updates['email'] = $new_em; if ($old_em !== $new_em) { if ($old_em !== '') redis()->del(email_index_key($old_em)); redis()->set(email_index_key($new_em), $uuid); } } if (!empty($updates)) { redis()->hMSet(acct_key($uuid), $updates); $me = acct_get($uuid); $msg = 'Saved!'; } } elseif ($action === 'change_password') { $old = (string)($_POST['old_password'] ?? ''); $new = (string)($_POST['new_password'] ?? ''); $new2= (string)($_POST['new_password2'] ?? ''); $hash = (string)($me['password_hash'] ?? ''); if ($old === '' || $new === '') { $msg = 'Fill all fields'; $err = true; } elseif ($new !== $new2) { $msg = 'Passwords do not match'; $err = true; } elseif (strlen($new) < 6) { $msg = 'Password too short (min 6 chars)'; $err = true; } elseif (!password_verify($old, $hash)) { $msg = 'Invalid current password'; $err = true; } else { redis()->hSet(acct_key($uuid), 'password_hash', password_hash($new, PASSWORD_DEFAULT)); $msg = 'Password changed!'; } } } // h() comes from auth/lib/html.php. $call = (string)($me['callsign'] ?? ''); $first = (string)($me['firstname'] ?? ''); $last = (string)($me['lastname'] ?? ''); $short = (string)($me['shortname'] ?? ''); $email = (string)($me['email'] ?? ''); $city = (string)($me['city'] ?? ''); $state = (string)($me['state'] ?? ''); $country = (string)($me['country'] ?? ''); $flags = acct_flags_from($me); $admin = acct_level_from_flags($flags); $email_verified = ((($me['email_verified'] ?? '0')) === '1'); $parts = []; foreach ([1=>'unreg',2=>'reg',4=>'normal',8=>'lvl1',16=>'lvl2',32=>'lvl3'] as $bit => $name) { if ($flags & $bit) $parts[] = $name; } $lvlText = $parts ? implode(', ', $parts) : '-'; $lvlColor = $admin >= 2 ? '#ffc800' : 'rgba(0,255,255,.75)'; $star = $admin >= 2 ? ' ★' : ''; // Callsigns tab (read-only): the account's callsigns (primary + admin-added // extras/club calls) and the nodes where one of them is a listed node admin. // Only site admins can change these lists. $my_calls = acct_all_calls($uuid); $extra_calls = array_values(array_filter(array_map( fn($c) => strtoupper(trim((string)$c)), redis()->sMembers(acct_calls_key($uuid)) ?: [] ))); sort($extra_calls); $admin_nodes = []; $rds = redis(); $cursor = null; do { $res = $rds->scan($cursor, rkey('node_admins:*'), 200); if ($res === false) break; foreach ($res as $key) { $node = substr($key, strlen(rkey('node_admins:'))); $members = $rds->sMembers($key) ?: []; foreach ($my_calls as $c) { if (in_array($c, $members, true)) { $admin_nodes[] = $node; break; } } } } while ($cursor > 0); $admin_nodes = array_values(array_unique($admin_nodes)); sort($admin_nodes); $page_title = 'Profile — Reflector Dashboard'; require __DIR__ . '/header.php'; ?>
UUID:
Identity
Email status ✓ Verified Not verified
Location
'; require __DIR__ . '/footer.php'; ?>