Username is required: blocking first step on every sign-in until one is saved

showOnboard(required) has no skip and no dismiss; a suggestion from the email
prefix is prefilled (GET /api/my/username-suggest, made unique); the member
area does not render until the username exists. Welcome tour and login ad still
run once for invite arrivals afterwards. Wallet-only sessions are unaffected.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-12 15:32:42 -05:00
parent 6996186061
commit a385fbf4c2
3 changed files with 35 additions and 10 deletions
+11
View File
@@ -1108,6 +1108,17 @@ const server = http.createServer(async (req, res) => {
const r = await promos.setActive(b.code, !!b.active);
return json(res, r.error ? 400 : 200, r);
}
// -- username suggestion for the required first step (Marty, 2026-09-12): email prefix, cleaned, unique
if (p === '/api/my/username-suggest' && req.method === 'GET') {
const s = await auth.fromRequest(req);
if (!s || !s.email) return json(res, 401, { error: 'Sign in first.' });
let base = String(s.email).split('@')[0].toLowerCase().replace(/[^a-z0-9_]/g, '').slice(0, 18);
if (!/[a-z]/.test(base)) base = 'member' + base;
if (base.length < 3) base = (base + 'xyz').slice(0, 3);
let pick = base;
for (let i = 2; i < 100 && await accounts.byUsername(pick); i++) pick = base.slice(0, 20 - String(i).length) + i;
return json(res, 200, { suggest: pick });
}
if (p === '/api/my/tank' && req.method === 'GET') {
const s = await auth.fromRequest(req);
if (!s || !s.email) return json(res, 401, { error: 'Sign in first.' });