diff --git a/packages/core/src/routes/sign-in-experience/index.test.ts b/packages/core/src/routes/sign-in-experience/index.test.ts index b4101bd7b..947b66414 100644 --- a/packages/core/src/routes/sign-in-experience/index.test.ts +++ b/packages/core/src/routes/sign-in-experience/index.test.ts @@ -184,4 +184,52 @@ describe('PATCH /sign-in-exp', () => { }, }); }); + + it('should guard support email field format', async () => { + const exception = await signInExperienceRequester + .patch('/sign-in-exp') + .send({ supportEmail: 'invalid' }); + + expect(exception).toMatchObject({ + status: 400, + }); + + const supportEmail = 'support@logto.io'; + + const response = await signInExperienceRequester.patch('/sign-in-exp').send({ + supportEmail, + }); + + expect(response).toMatchObject({ + status: 200, + body: { + ...mockSignInExperience, + supportEmail, + }, + }); + }); + + it('should guard support website URL field format', async () => { + const exception = await signInExperienceRequester + .patch('/sign-in-exp') + .send({ supportWebsiteUrl: 'invalid' }); + + expect(exception).toMatchObject({ + status: 400, + }); + + const supportWebsiteUrl = 'https://logto.io'; + + const response = await signInExperienceRequester.patch('/sign-in-exp').send({ + supportWebsiteUrl, + }); + + expect(response).toMatchObject({ + status: 200, + body: { + ...mockSignInExperience, + supportWebsiteUrl, + }, + }); + }); }); diff --git a/packages/core/src/routes/sign-in-experience/index.ts b/packages/core/src/routes/sign-in-experience/index.ts index de6586701..cc38ddb8f 100644 --- a/packages/core/src/routes/sign-in-experience/index.ts +++ b/packages/core/src/routes/sign-in-experience/index.ts @@ -49,11 +49,19 @@ export default function signInExperiencesRoutes( koaGuard({ query: z.object({ removeUnusedDemoSocialConnector: z.string().optional() }), body: SignInExperiences.createGuard - .omit({ id: true, termsOfUseUrl: true, privacyPolicyUrl: true }) + .omit({ + id: true, + termsOfUseUrl: true, + privacyPolicyUrl: true, + supportEmail: true, + supportWebsiteUrl: true, + }) .merge( object({ termsOfUseUrl: string().url().optional().nullable().or(literal('')), privacyPolicyUrl: string().url().optional().nullable().or(literal('')), + supportEmail: string().email().optional().nullable().or(literal('')), + supportWebsiteUrl: string().url().optional().nullable().or(literal('')), }) ) .partial(), diff --git a/packages/integration-tests/src/tests/api/sign-in-experience.test.ts b/packages/integration-tests/src/tests/api/sign-in-experience.test.ts index 8aab8fa2d..7329ee752 100644 --- a/packages/integration-tests/src/tests/api/sign-in-experience.test.ts +++ b/packages/integration-tests/src/tests/api/sign-in-experience.test.ts @@ -36,6 +36,8 @@ describe('admin console sign-in experience', () => { factors: [], }, singleSignOnEnabled: true, + supportEmail: 'contact@logto.io', + supportWebsiteUrl: 'https://logto.io', }; const updatedSignInExperience = await updateSignInExperience(newSignInExperience);