From f8ed49e52ba53a92f5e8f7fd5df5bb1459a12a81 Mon Sep 17 00:00:00 2001 From: Andrew Rumble Date: Wed, 2 Jul 2025 16:44:02 +0100 Subject: [PATCH] consider trustedUsersRegex when choosing to show captcha at login GitOrigin-RevId: 963fe1c40d05fe088a092eb45b12bcddf1f18e7b --- .../src/Features/Captcha/CaptchaMiddleware.js | 4 +- .../web/test/acceptance/src/CaptchaTests.mjs | 53 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/services/web/app/src/Features/Captcha/CaptchaMiddleware.js b/services/web/app/src/Features/Captcha/CaptchaMiddleware.js index 9c93b74cfa..645738c2c7 100644 --- a/services/web/app/src/Features/Captcha/CaptchaMiddleware.js +++ b/services/web/app/src/Features/Captcha/CaptchaMiddleware.js @@ -28,7 +28,9 @@ async function initializeDeviceHistory(req) { async function canSkipCaptcha(req, res) { const trustedUser = - req.body?.email && Settings.recaptcha.trustedUsers.includes(req.body.email) + req.body?.email && + (Settings.recaptcha.trustedUsers.includes(req.body.email) || + Settings.recaptcha.trustedUsersRegex?.test(req.body.email)) if (trustedUser) { return res.json(true) } diff --git a/services/web/test/acceptance/src/CaptchaTests.mjs b/services/web/test/acceptance/src/CaptchaTests.mjs index 10fdcf1626..223fe02cb0 100644 --- a/services/web/test/acceptance/src/CaptchaTests.mjs +++ b/services/web/test/acceptance/src/CaptchaTests.mjs @@ -104,6 +104,59 @@ describe('Captcha', function () { }) }) + describe('trustedUsersRegex', function () { + let resetTrustedUsersRegex + beforeEach(function () { + resetTrustedUsersRegex = Settings.recaptcha.trustedUsersRegex + Settings.recaptcha.trustedUsersRegex = /\+trusted@example\.com$/ + }) + + afterEach(function () { + Settings.recaptcha.trustedUsersRegex = resetTrustedUsersRegex + }) + + describe('when user is trusted, can login without captcha', function () { + let trustedUser + beforeEach(async function () { + trustedUser = new User({ + email: 'acceptance-test+trusted@example.com', + }) + await trustedUser.ensureUserExists() + }) + + it('should be able to skip captcha', async function () { + expect(await canSkipCaptcha(trustedUser.email)).to.equal(true) + }) + + it('should note that the user is trusted', async function () { + const { response, body } = await login( + trustedUser.email, + trustedUser.password, + '' + ) + expectSuccessfulLogin(response, body) + const auditLog = await trustedUser.getAuditLog() + expect(auditLog[0].info).to.deep.equal({ + captcha: 'trusted', + method: 'Password login', + }) + }) + }) + + describe('when user is not trusted', function () { + it('should not be able to skip captcha', async function () { + expect(await canSkipCaptcha(user.email)).to.equal(false) + }) + + it('should not add an audit log entry for trusted user', async function () { + const { response, body } = await login(user.email, user.password, '') + expectBadCaptchaResponse(response, body) + const auditLog = await user.getAuditLog() + expect(auditLog).to.have.lengthOf(0) + }) + }) + }) + describe('deviceHistory', function () { beforeEach('login', async function () { const { response, body } = await loginWithCaptcha('valid')