Skip the pointless password prompt before first-time password setup

checkEmailRequest only checked whether the account existed, so a
first-login account (no password set yet) was still sent to the
normal "enter your password" screen before the backend revealed there
was no password to check against — only then did it route to the
create-password step. checkEmailRequest now detects the same
setup-required signal PasswordSetupRequiredError does and skips
straight to it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Suriya
2026-07-21 17:14:14 +05:30
parent f029c09dd7
commit bbcf987488
2 changed files with 29 additions and 7 deletions

View File

@@ -204,11 +204,20 @@ export async function loginRequest(email: string, password: string): Promise<Log
return { row, hasRole: Boolean(row && row[RESPONSE_FIELDS.roleid] != null), email: resolvedEmail };
}
export interface EmailCheckResult {
exists: boolean;
/** True when the account has never had a password set — skip straight to
* the create-password step instead of asking for a password it doesn't
* have yet (see PasswordSetupRequiredError for why this is detectable
* even from this password-less probe request). */
needsSetup: boolean;
userid?: number;
}
/**
* Checks if the email/authname exists and is registered by sending email and configid: 1.
* Returns true if the email exists, false if it is invalid.
*/
export async function checkEmailRequest(email: string): Promise<boolean> {
export async function checkEmailRequest(email: string): Promise<EmailCheckResult> {
const trimmedEmail = email.trim();
let res: Response;
@@ -226,16 +235,24 @@ export async function checkEmailRequest(email: string): Promise<boolean> {
}
const json = (await res.json().catch(() => null)) as
| { code?: number; status?: boolean; message?: string }
| { code?: number; status?: boolean; message?: string; details?: unknown }
| null;
// Account exists but has no password yet — fires regardless of the
// (absent) password in this probe request. See loginRequest's identical
// check for the full explanation.
const details = json?.details as { userid?: number; setup?: boolean } | undefined;
if (json?.code === 409 && details?.setup === true && typeof details.userid === 'number') {
return { exists: true, needsSetup: true, userid: details.userid };
}
// A 409 Invalid Email code means the email does not exist.
if (json && json.status === false && (json.code === 409 || json.message?.trim().toLowerCase() === 'invalid email')) {
return false;
return { exists: false, needsSetup: false };
}
// Any other result (such as 403 Unauthorized email) means the email is registered.
return true;
return { exists: true, needsSetup: false };
}