feat: 🎸 Show correct login error to user

This commit is contained in:
Jin 2025-03-26 00:13:56 +01:00
parent c1ed471403
commit 8f157e04d4
2 changed files with 42 additions and 42 deletions

View File

@ -18,7 +18,8 @@ function loginPage(req: Request, res: Response) {
res.redirect('/authenticate'); res.redirect('/authenticate');
} else { } else {
res.render('login', { res.render('login', {
failedAuth: false, wrongPassword: false,
wrongTotp: false,
totpEnabled: totp.isTotpEnabled(), totpEnabled: totp.isTotpEnabled(),
assetPath: assetPath, assetPath: assetPath,
appPath: appPath, appPath: appPath,
@ -69,10 +70,16 @@ function login(req: Request, res: Response) {
const submittedPassword = req.body.password; const submittedPassword = req.body.password;
const submittedTotp = req.body.token; const submittedTotp = req.body.token;
if (verifyPassword(submittedPassword)) { // 首先验证密码
if (!verifyPassword(submittedPassword)) {
sendLoginError(req, res, 'password');
return;
}
// 如果密码正确且启用了 TOTP验证 TOTP
if (totp.isTotpEnabled()) { if (totp.isTotpEnabled()) {
if (!verifyTOTP(submittedTotp)) { if (!verifyTOTP(submittedTotp)) {
sendLoginError(req, res); sendLoginError(req, res, 'totp');
return; return;
} }
} }
@ -98,10 +105,6 @@ function login(req: Request, res: Response) {
res.redirect('.'); res.redirect('.');
}); });
} }
else {
sendLoginError(req, res);
}
}
function verifyTOTP(submittedToken: string) { function verifyTOTP(submittedToken: string) {
if (totp.validateTOTP(submittedToken)) return true; if (totp.validateTOTP(submittedToken)) return true;
@ -119,17 +122,18 @@ function verifyPassword(submittedPassword: string) {
return guess_hashed.equals(hashed_password); return guess_hashed.equals(hashed_password);
} }
function sendLoginError(req: Request, res: Response) { function sendLoginError(req: Request, res: Response, errorType: 'password' | 'totp' = 'password') {
// note that logged IP address is usually meaningless since the traffic should come from a reverse proxy // note that logged IP address is usually meaningless since the traffic should come from a reverse proxy
if (totp.isTotpEnabled()) { if (totp.isTotpEnabled()) {
log.info(`WARNING: Wrong password or TOTP from ${req.ip}, rejecting.`); log.info(`WARNING: Wrong ${errorType} from ${req.ip}, rejecting.`);
} else { } else {
log.info(`WARNING: Wrong password from ${req.ip}, rejecting.`); log.info(`WARNING: Wrong password from ${req.ip}, rejecting.`);
} }
res.status(401).render('login', { res.render('login', {
failedAuth: true, wrongPassword: errorType === 'password',
totpEnabled: optionService.getOption('totpEnabled') && totp.checkForTotSecret(), wrongTotp: errorType === 'totp',
totpEnabled: totp.isTotpEnabled(),
assetPath: assetPath, assetPath: assetPath,
appPath: appPath, appPath: appPath,
}); });

View File

@ -41,20 +41,16 @@
</div> </div>
<% } %> <% } %>
<% if (failedAuth) { %> <% if ( wrongPassword ) { %>
<div class="alert alert-warning"> <div class="alert alert-warning">
<%= t("login.incorrect-password") %> <%= t("login.incorrect-password") %>
</div> </div>
<% } %> <% } %>
<% if (failedAuth) { %>
<% if ( totpEnabled ) { %> <% if ( totpEnabled ) { %>
<% if( wrongTotp ) { %>
<div class="alert alert-warning"> <div class="alert alert-warning">
<%= t("login.incorrect-totp") %> <%= t("login.incorrect-totp") %>
</div> </div>
<% }else{ %>
<div class="alert alert-warning">
<%= t("login.incorrect-password") %>
</div>
<% } %> <% } %>
<% } %> <% } %>