diff --git a/server/routes.js b/server/routes.js index 1d29922..bb8d543 100644 --- a/server/routes.js +++ b/server/routes.js @@ -65,12 +65,22 @@ route('POST', '/api/login', async (req, res) => { if (existing && existing.active === 0) return json(res, 403, { error: 'This account has been deactivated' }); let u = (existing && A.verifyPassword(password, existing.pw_salt, existing.pw_hash)) ? existing : null; + let bzMsg = null; if (!u) { const bz = await BZ.validateLogin(email, password); if (bz.ok) u = provisionFromBizgaze(email, bz); else if (bz.error) return json(res, 503, { error: bz.error }); + else bzMsg = bz.message || null; // BizGaze was configured and rejected the credentials + } + if (!u) { + // Specific feedback where we can be truthful: + if (existing) return json(res, 401, { error: 'Incorrect password. Please try again.' }); + // No local account. BizGaze (the identity provider) doesn't reveal whether an email + // exists, so when it rejects we surface its own message (covers wrong password + + // any lockout warning). Only when BizGaze isn't in play can we say "not registered". + if (bzMsg) return json(res, 401, { error: bzMsg }); + return json(res, 404, { error: 'This email is not registered.' }); } - if (!u) return json(res, 401, { error: 'invalid credentials' }); const tok = A.token(); const ttl = remember ? 1000 * 60 * 60 * 24 * 30 : SESSION_TTL; // 30 days if remembered, else 24h