0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-31 22:51:25 -05:00

feat(core): enable forgot password check (#2257)

This commit is contained in:
wangsijie 2022-10-27 11:50:48 +08:00 committed by GitHub
parent b5512b9213
commit 50170cfcbf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 6 deletions

View file

@ -70,7 +70,7 @@ export const mockSignInExperience: SignInExperience = {
},
socialSignInConnectorTargets: ['github', 'facebook', 'wechat'],
signInMode: SignInMode.SignInAndRegister,
forgotPassword: true,
forgotPassword: false,
};
export const mockColor: Color = {

View file

@ -1,5 +1,5 @@
import type { SignInExperience, CreateSignInExperience, TermsOfUse } from '@logto/schemas';
import { SignInMethodState } from '@logto/schemas';
import { ConnectorType, SignInMethodState } from '@logto/schemas';
import {
mockFacebookConnector,
@ -13,6 +13,7 @@ import {
mockSignUp,
mockSignIn,
mockLanguageInfo,
mockAliyunSmsConnector,
} from '@/__mocks__';
import * as signInExpLib from '@/lib/sign-in-experience';
import * as signInLib from '@/lib/sign-in-experience/sign-in';
@ -27,6 +28,7 @@ const logtoConnectors = [
mockGithubConnector,
mockGoogleConnector,
mockWechatConnector,
mockAliyunSmsConnector,
];
const getLogtoConnectors = jest.fn(async () => logtoConnectors);
@ -106,6 +108,18 @@ describe('PATCH /sign-in-exp', () => {
});
});
it('should not allow forgot password without enabled passwordless connector', async () => {
getLogtoConnectors.mockResolvedValueOnce(
logtoConnectors.filter(
({ type }) => type !== ConnectorType.Sms && type !== ConnectorType.Email
)
);
const response = await signInExperienceRequester
.patch('/sign-in-exp')
.send({ forgotPassword: true });
expect(response.status).toEqual(400);
});
it('should succeed to update when the input is valid', async () => {
const termsOfUse: TermsOfUse = { enabled: false };
const socialSignInConnectorTargets = ['github', 'facebook', 'wechat'];
@ -128,7 +142,12 @@ describe('PATCH /sign-in-exp', () => {
signIn: mockSignIn,
forgotPassword: true,
});
const connectors = [mockFacebookConnector, mockGithubConnector, mockWechatConnector];
const connectors = [
mockFacebookConnector,
mockGithubConnector,
mockWechatConnector,
mockAliyunSmsConnector,
];
expect(validateBranding).toHaveBeenCalledWith(mockBranding);
expect(validateLanguageInfo).toHaveBeenCalledWith(mockLanguageInfo);
@ -151,6 +170,7 @@ describe('PATCH /sign-in-exp', () => {
signInMethods: mockSignInMethods,
socialSignInConnectorTargets,
signIn: mockSignIn,
forgotPassword: true,
},
});
});

View file

@ -1,6 +1,7 @@
import { ConnectorType, SignInExperiences } from '@logto/schemas';
import { getLogtoConnectors } from '@/connectors';
import RequestError from '@/errors/RequestError';
import {
validateBranding,
validateLanguageInfo,
@ -15,6 +16,7 @@ import {
findDefaultSignInExperience,
updateDefaultSignInExperience,
} from '@/queries/sign-in-experience';
import assertThat from '@/utils/assert-that';
import type { AuthedRouter } from './types';
@ -37,7 +39,8 @@ export default function signInExperiencesRoutes<T extends AuthedRouter>(router:
/* eslint-disable complexity */
async (ctx, next) => {
const { socialSignInConnectorTargets, ...rest } = ctx.guard.body;
const { branding, languageInfo, termsOfUse, signInMethods, signUp, signIn } = rest;
const { branding, languageInfo, termsOfUse, signInMethods, signUp, signIn, forgotPassword } =
rest;
if (branding) {
validateBranding(branding);
@ -81,6 +84,18 @@ export default function signInExperiencesRoutes<T extends AuthedRouter>(router:
validateSignIn(signIn, signInExperience.signUp, enabledConnectors);
}
if (forgotPassword) {
assertThat(
enabledConnectors.some(
({ type }) => type === ConnectorType.Sms || type === ConnectorType.Email
),
new RequestError({
code: 'sign_in_experiences.enabled_connector_not_found',
type: [ConnectorType.Email, ConnectorType.Sms].join(','),
})
);
}
// Update socialSignInConnectorTargets only when social sign-in is enabled.
const signInExperience =
signInMethods && isEnabled(signInMethods.social)

View file

@ -65,6 +65,7 @@ export const defaultSignInExperience: Readonly<CreateSignInExperience> = {
},
socialSignInConnectorTargets: [],
signInMode: SignInMode.SignInAndRegister,
forgotPassword: false,
};
export const adminConsoleSignInExperience: CreateSignInExperience = {

View file

@ -216,7 +216,7 @@ export const mockSignInExperience: SignInExperience = {
},
socialSignInConnectorTargets: ['BE8QXN0VsrOH7xdWFDJZ9', 'lcXT4o2GSjbV9kg2shZC7'],
signInMode: SignInMode.SignInAndRegister,
forgotPassword: true,
forgotPassword: false,
};
export const mockSignInExperienceSettings: SignInExperienceSettings = {
@ -228,5 +228,5 @@ export const mockSignInExperienceSettings: SignInExperienceSettings = {
secondarySignInMethods: ['email', 'sms', 'social'],
socialConnectors,
signInMode: SignInMode.SignInAndRegister,
forgotPassword: true,
forgotPassword: false,
};