mirror of
https://github.com/logto-io/logto.git
synced 2025-02-03 21:48:55 -05:00
refactor(core): move GET /sign-in-settings out of sessionRouter (#875)
This commit is contained in:
parent
3b048a80a3
commit
e9e7efdc92
5 changed files with 122 additions and 60 deletions
|
@ -11,6 +11,7 @@ import resourceRoutes from '@/routes/resource';
|
|||
import sessionRoutes from '@/routes/session';
|
||||
import settingRoutes from '@/routes/setting';
|
||||
import signInExperiencesRoutes from '@/routes/sign-in-experience';
|
||||
import signInSettingsRoutes from '@/routes/sign-in-settings';
|
||||
import statusRoutes from '@/routes/status';
|
||||
import swaggerRoutes from '@/routes/swagger';
|
||||
|
||||
|
@ -25,6 +26,7 @@ const createRouters = (provider: Provider) => {
|
|||
sessionRoutes(sessionRouter, provider);
|
||||
|
||||
const anonymousRouter: AnonymousRouter = new Router();
|
||||
signInSettingsRoutes(anonymousRouter);
|
||||
statusRoutes(anonymousRouter);
|
||||
swaggerRoutes(anonymousRouter);
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ import { User } from '@logto/schemas';
|
|||
import { Provider } from 'oidc-provider';
|
||||
|
||||
import {
|
||||
mockSignInExperience,
|
||||
mockUser,
|
||||
mockAliyunDmConnectorInstance,
|
||||
mockAliyunSmsConnectorInstance,
|
||||
|
@ -15,7 +14,6 @@ import {
|
|||
} from '@/__mocks__';
|
||||
import { ConnectorType } from '@/connectors/types';
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import * as signInExperienceQueries from '@/queries/sign-in-experience';
|
||||
import { createRequester } from '@/utils/test-utils';
|
||||
|
||||
import sessionRoutes from './session';
|
||||
|
@ -912,41 +910,6 @@ describe('sessionRoutes', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('GET /sign-in-settings', () => {
|
||||
const signInExperienceQuerySpyOn = jest
|
||||
.spyOn(signInExperienceQueries, 'findDefaultSignInExperience')
|
||||
.mockResolvedValue(mockSignInExperience);
|
||||
|
||||
it('should return github and facebook connector instances', async () => {
|
||||
const response = await sessionRequest.get('/sign-in-settings');
|
||||
expect(signInExperienceQuerySpyOn).toHaveBeenCalledTimes(1);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toMatchObject(
|
||||
expect.objectContaining({
|
||||
...mockSignInExperience,
|
||||
socialConnectors: [
|
||||
{
|
||||
...mockGithubConnectorInstance.metadata,
|
||||
id: mockGithubConnectorInstance.connector.id,
|
||||
},
|
||||
{
|
||||
...mockFacebookConnectorInstance.metadata,
|
||||
id: mockFacebookConnectorInstance.connector.id,
|
||||
},
|
||||
{
|
||||
...mockWechatConnectorInstance.metadata,
|
||||
id: mockWechatConnectorInstance.connector.id,
|
||||
},
|
||||
{
|
||||
...mockWechatNativeConnectorInstance.metadata,
|
||||
id: mockWechatNativeConnectorInstance.connector.id,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('DELETE /session', async () => {
|
||||
const response = await sessionRequest.delete('/session');
|
||||
expect(response.body).toHaveProperty('redirectTo');
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable max-lines */
|
||||
import path from 'path';
|
||||
|
||||
import { ConnectorMetadata } from '@logto/connector-types';
|
||||
import { LogtoErrorCode } from '@logto/phrases';
|
||||
import { PasscodeType, userInfoSelectFields } from '@logto/schemas';
|
||||
import {
|
||||
|
@ -16,7 +15,7 @@ import pick from 'lodash.pick';
|
|||
import { Provider } from 'oidc-provider';
|
||||
import { object, string } from 'zod';
|
||||
|
||||
import { getConnectorInstances, getSocialConnectorInstanceById } from '@/connectors';
|
||||
import { getSocialConnectorInstanceById } from '@/connectors';
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { createPasscode, sendPasscode, verifyPasscode } from '@/lib/passcode';
|
||||
import { assignInteractionResults, saveUserFirstConsentedAppId } from '@/lib/session';
|
||||
|
@ -32,7 +31,6 @@ import {
|
|||
updateLastSignInAt,
|
||||
} from '@/lib/user';
|
||||
import koaGuard from '@/middleware/koa-guard';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
import {
|
||||
hasUserWithEmail,
|
||||
hasUserWithPhone,
|
||||
|
@ -578,25 +576,5 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
|
|||
|
||||
return next();
|
||||
});
|
||||
|
||||
router.get('/sign-in-settings', async (ctx, next) => {
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const connectorInstances = await getConnectorInstances();
|
||||
const socialConnectors = signInExperience.socialSignInConnectorTargets.reduce<
|
||||
Array<ConnectorMetadata & { id: string }>
|
||||
>((previous, connectorTarget) => {
|
||||
const connectors = connectorInstances.filter(
|
||||
({ metadata: { target } }) => target === connectorTarget
|
||||
);
|
||||
|
||||
return [
|
||||
...previous,
|
||||
...connectors.map(({ metadata, connector: { id } }) => ({ ...metadata, id })),
|
||||
];
|
||||
}, []);
|
||||
ctx.body = { ...signInExperience, socialConnectors };
|
||||
|
||||
return next();
|
||||
});
|
||||
}
|
||||
/* eslint-enable max-lines */
|
||||
|
|
89
packages/core/src/routes/sign-in-settings.test.ts
Normal file
89
packages/core/src/routes/sign-in-settings.test.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
import { ConnectorType } from '@logto/schemas';
|
||||
|
||||
import {
|
||||
mockAliyunDmConnectorInstance,
|
||||
mockAliyunSmsConnectorInstance,
|
||||
mockFacebookConnectorInstance,
|
||||
mockGithubConnectorInstance,
|
||||
mockGoogleConnectorInstance,
|
||||
mockSignInExperience,
|
||||
mockWechatConnectorInstance,
|
||||
mockWechatNativeConnectorInstance,
|
||||
} from '@/__mocks__';
|
||||
import { getConnectorInstanceById } from '@/connectors';
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import * as signInExperienceQueries from '@/queries/sign-in-experience';
|
||||
import signInSettingsRoutes from '@/routes/sign-in-settings';
|
||||
import { createRequester } from '@/utils/test-utils';
|
||||
|
||||
const getConnectorInstances = jest.fn(async () => [
|
||||
mockAliyunDmConnectorInstance,
|
||||
mockAliyunSmsConnectorInstance,
|
||||
mockFacebookConnectorInstance,
|
||||
mockGithubConnectorInstance,
|
||||
mockGoogleConnectorInstance,
|
||||
mockWechatConnectorInstance,
|
||||
mockWechatNativeConnectorInstance,
|
||||
]);
|
||||
jest.mock('@/connectors', () => ({
|
||||
getSocialConnectorInstanceById: async (connectorId: string) => {
|
||||
const connectorInstance = await getConnectorInstanceById(connectorId);
|
||||
|
||||
if (connectorInstance.metadata.type !== ConnectorType.Social) {
|
||||
throw new RequestError({
|
||||
code: 'entity.not_found',
|
||||
status: 404,
|
||||
});
|
||||
}
|
||||
|
||||
return connectorInstance;
|
||||
},
|
||||
getConnectorInstances: async () => getConnectorInstances(),
|
||||
}));
|
||||
|
||||
describe('GET /sign-in-settings', () => {
|
||||
const sessionRequest = createRequester({
|
||||
anonymousRoutes: signInSettingsRoutes,
|
||||
middlewares: [
|
||||
async (ctx, next) => {
|
||||
ctx.addLogContext = jest.fn();
|
||||
ctx.log = jest.fn();
|
||||
|
||||
return next();
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const signInExperienceQuerySpyOn = jest
|
||||
.spyOn(signInExperienceQueries, 'findDefaultSignInExperience')
|
||||
.mockResolvedValue(mockSignInExperience);
|
||||
|
||||
it('should return github and facebook connector instances', async () => {
|
||||
const response = await sessionRequest.get('/sign-in-settings');
|
||||
expect(signInExperienceQuerySpyOn).toHaveBeenCalledTimes(1);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toMatchObject(
|
||||
expect.objectContaining({
|
||||
...mockSignInExperience,
|
||||
socialConnectors: [
|
||||
{
|
||||
...mockGithubConnectorInstance.metadata,
|
||||
id: mockGithubConnectorInstance.connector.id,
|
||||
},
|
||||
{
|
||||
...mockFacebookConnectorInstance.metadata,
|
||||
id: mockFacebookConnectorInstance.connector.id,
|
||||
},
|
||||
{
|
||||
...mockWechatConnectorInstance.metadata,
|
||||
id: mockWechatConnectorInstance.connector.id,
|
||||
},
|
||||
{
|
||||
...mockWechatNativeConnectorInstance.metadata,
|
||||
id: mockWechatNativeConnectorInstance.connector.id,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
30
packages/core/src/routes/sign-in-settings.ts
Normal file
30
packages/core/src/routes/sign-in-settings.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { ConnectorMetadata } from '@logto/connector-types';
|
||||
|
||||
import { getConnectorInstances } from '@/connectors';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
|
||||
import { AnonymousRouter } from './types';
|
||||
|
||||
export default function signInSettingsRoutes<T extends AnonymousRouter>(router: T) {
|
||||
router.get('/sign-in-settings', async (ctx, next) => {
|
||||
const [signInExperience, connectorInstances] = await Promise.all([
|
||||
findDefaultSignInExperience(),
|
||||
getConnectorInstances(),
|
||||
]);
|
||||
const socialConnectors = signInExperience.socialSignInConnectorTargets.reduce<
|
||||
Array<ConnectorMetadata & { id: string }>
|
||||
>((previous, connectorTarget) => {
|
||||
const connectors = connectorInstances.filter(
|
||||
({ metadata: { target } }) => target === connectorTarget
|
||||
);
|
||||
|
||||
return [
|
||||
...previous,
|
||||
...connectors.map(({ metadata, connector: { id } }) => ({ ...metadata, id })),
|
||||
];
|
||||
}, []);
|
||||
ctx.body = { ...signInExperience, socialConnectors };
|
||||
|
||||
return next();
|
||||
});
|
||||
}
|
Loading…
Add table
Reference in a new issue