|
1 | | -import etapiTokenService from "./etapi_tokens.js"; |
2 | | -import log from "./log.js"; |
3 | | -import sqlInit from "./sql_init.js"; |
4 | | -import { isElectron } from "./utils.js"; |
5 | | -import passwordEncryptionService from "./encryption/password_encryption.js"; |
| 1 | +import type { NextFunction, Request, Response } from "express"; |
| 2 | + |
| 3 | +import attributes from "./attributes.js"; |
6 | 4 | import config from "./config.js"; |
7 | 5 | import passwordService from "./encryption/password.js"; |
8 | | -import totp from "./totp.js"; |
| 6 | +import passwordEncryptionService from "./encryption/password_encryption.js"; |
| 7 | +import recoveryCodeService from "./encryption/recovery_codes.js"; |
| 8 | +import etapiTokenService from "./etapi_tokens.js"; |
| 9 | +import log from "./log.js"; |
9 | 10 | import openID from "./open_id.js"; |
10 | 11 | import options from "./options.js"; |
11 | | -import attributes from "./attributes.js"; |
12 | | -import type { NextFunction, Request, Response } from "express"; |
| 12 | +import sqlInit from "./sql_init.js"; |
| 13 | +import totp from "./totp.js"; |
| 14 | +import { isElectron } from "./utils.js"; |
13 | 15 |
|
14 | 16 | let noAuthentication = false; |
15 | 17 | refreshAuth(); |
@@ -161,9 +163,27 @@ function checkCredentials(req: Request, res: Response, next: NextFunction) { |
161 | 163 | if (!passwordEncryptionService.verifyPassword(password)) { |
162 | 164 | res.setHeader("Content-Type", "text/plain").status(401).send("Incorrect password"); |
163 | 165 | log.info(`WARNING: Wrong password from ${req.ip}, rejecting.`); |
164 | | - } else { |
165 | | - next(); |
| 166 | + return; |
| 167 | + } |
| 168 | + |
| 169 | + // Verify TOTP if enabled |
| 170 | + if (totp.isTotpEnabled()) { |
| 171 | + const totpToken = req.headers["trilium-totp"] || ""; |
| 172 | + if (typeof totpToken !== "string" || !totpToken) { |
| 173 | + res.setHeader("Content-Type", "text/plain").status(401).send("TOTP token is required"); |
| 174 | + log.info(`WARNING: Missing TOTP token from ${req.ip}, rejecting.`); |
| 175 | + return; |
| 176 | + } |
| 177 | + |
| 178 | + // Accept TOTP code or recovery code |
| 179 | + if (!totp.validateTOTP(totpToken) && !recoveryCodeService.verifyRecoveryCode(totpToken)) { |
| 180 | + res.setHeader("Content-Type", "text/plain").status(401).send("Incorrect TOTP token"); |
| 181 | + log.info(`WARNING: Wrong TOTP token from ${req.ip}, rejecting.`); |
| 182 | + return; |
| 183 | + } |
166 | 184 | } |
| 185 | + |
| 186 | + next(); |
167 | 187 | } |
168 | 188 |
|
169 | 189 | export default { |
|
0 commit comments