diff --git a/src/encryptid/server.ts b/src/encryptid/server.ts index 76f05bb..57f4930 100644 --- a/src/encryptid/server.ts +++ b/src/encryptid/server.ts @@ -581,7 +581,7 @@ app.post('/api/register/complete', async (c) => { // Set recovery email if provided during registration if (email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { - await setUserEmail(userId, email); + await setUserEmail(userId, email.trim().toLowerCase()); } // Resolve the RP ID from the caller's origin @@ -1203,7 +1203,7 @@ app.post('/api/account/email/verify', async (c) => { } await markRecoveryTokenUsed(tokenKey); - await setUserEmail(claims.sub as string, email); + await setUserEmail(claims.sub as string, email.trim().toLowerCase()); return c.json({ success: true, email }); }); @@ -1433,8 +1433,9 @@ app.post('/api/recovery/email/set', async (c) => { return c.json({ error: 'Valid email required' }, 400); } - await setUserEmail(payload.sub as string, email); - return c.json({ success: true, email }); + const normalizedEmail = email.trim().toLowerCase(); + await setUserEmail(payload.sub as string, normalizedEmail); + return c.json({ success: true, email: normalizedEmail }); } catch { return c.json({ error: 'Unauthorized' }, 401); } @@ -5441,10 +5442,14 @@ app.post('/oidc/authorize', async (c) => { if (!user) { return c.json({ error: 'User not found' }, 404); } - const userEmail = user.email || user.profile_email; + const userEmail = (user.email || user.profile_email || '').toLowerCase(); if (client.allowedEmails.length > 0) { - if (!userEmail || !client.allowedEmails.includes(userEmail)) { - return c.json({ error: 'access_denied', message: 'You do not have access to this application.' }, 403); + const allowedLower = client.allowedEmails.map((e: string) => e.toLowerCase()); + if (!userEmail) { + return c.json({ error: 'email_required', message: 'Email verification is required for this application.' }, 403); + } + if (!allowedLower.includes(userEmail)) { + return c.json({ error: 'access_denied', message: 'Your email is not authorized for this application.' }, 403); } } @@ -5906,8 +5911,8 @@ function oidcAuthorizePage(appName: string, clientId: string, redirectUri: strin const authorizeResult = await authorizeRes.json(); if (authorizeResult.error) { - if (authorizeResult.error === 'access_denied') { - // Show email verification flow instead of dead-end error + if (authorizeResult.error === 'email_required') { + // User has no verified email — show email verification form loginBtn.style.display = 'none'; statusEl.style.display = 'none'; verifySection.style.display = 'block';