Skip to content

Commit 9d8914e

Browse files
authored
feat(core): add email blocklist validation to account API (#7376)
feat(core): add email blocklist validation on account API add email blocklist validation on account API
1 parent 41aeaae commit 9d8914e

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

packages/core/src/routes/account/email-and-phone.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { z } from 'zod';
44

55
import koaGuard from '#src/middleware/koa-guard.js';
66

7+
import { EnvSet } from '../../env-set/index.js';
78
import RequestError from '../../errors/RequestError/index.js';
9+
import { validateEmailAgainstBlocklistPolicy } from '../../libraries/sign-in-experience/email-blocklist-policy.js';
810
import { buildVerificationRecordByIdAndType } from '../../libraries/verification.js';
911
import assertThat from '../../utils/assert-that.js';
1012
import type { UserRouter, RouterInitArgs } from '../types.js';
@@ -46,6 +48,13 @@ export default function emailAndPhoneRoutes<T extends UserRouter>(...args: Route
4648

4749
assertThat(scopes.has(UserScope.Email), 'auth.unauthorized');
4850

51+
// TODO: remove this when the feature is ready @simeng
52+
// Validate email blocklist policy
53+
if (EnvSet.values.isDevFeaturesEnabled) {
54+
const { emailBlocklistPolicy } = await findDefaultSignInExperience();
55+
await validateEmailAgainstBlocklistPolicy(emailBlocklistPolicy, email);
56+
}
57+
4958
// Check new identifier
5059
const newVerificationRecord = await buildVerificationRecordByIdAndType({
5160
type: VerificationType.EmailVerificationCode,

packages/integration-tests/src/tests/api/account/email-and-phone.test.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
updatePrimaryEmail,
1111
updatePrimaryPhone,
1212
} from '#src/api/my-account.js';
13+
import { updateSignInExperience } from '#src/api/sign-in-experience.js';
1314
import {
1415
createAndVerifyVerificationCode,
1516
createVerificationRecordByPassword,
@@ -22,7 +23,7 @@ import {
2223
signInAndGetUserApi,
2324
} from '#src/helpers/profile.js';
2425
import { enableAllPasswordSignInMethods } from '#src/helpers/sign-in-experience.js';
25-
import { generateEmail, generatePhone } from '#src/utils.js';
26+
import { devFeatureTest, generateEmail, generatePhone } from '#src/utils.js';
2627

2728
describe('account (email and phone)', () => {
2829
beforeAll(async () => {
@@ -137,6 +138,36 @@ describe('account (email and phone)', () => {
137138

138139
await deleteDefaultTenantUser(user.id);
139140
});
141+
142+
devFeatureTest.it('should reject the email if the email is in the blocklist', async () => {
143+
const email = generateEmail();
144+
await updateSignInExperience({
145+
emailBlocklistPolicy: {
146+
customBlocklist: [email],
147+
},
148+
});
149+
150+
const { user, username, password } = await createDefaultTenantUserWithPassword();
151+
const api = await signInAndGetUserApi(username, password, {
152+
scopes: [UserScope.Profile, UserScope.Email],
153+
});
154+
155+
const verificationRecordId = await createVerificationRecordByPassword(api, password);
156+
const newVerificationRecordId = await createAndVerifyVerificationCode(api, {
157+
type: SignInIdentifier.Email,
158+
value: email,
159+
});
160+
161+
await expectRejects(
162+
updatePrimaryEmail(api, email, verificationRecordId, newVerificationRecordId),
163+
{
164+
code: 'session.email_blocklist.email_not_allowed',
165+
status: 422,
166+
}
167+
);
168+
169+
await deleteDefaultTenantUser(user.id);
170+
});
140171
});
141172

142173
describe('DELETE /my-account/primary-email', () => {

0 commit comments

Comments
 (0)