From 8c5ccac59f6e2a4945f86d6207e7396278d575b4 Mon Sep 17 00:00:00 2001 From: Darcy Ye Date: Mon, 26 Dec 2022 10:23:40 +0800 Subject: [PATCH] refactor(core): refactor createSocialAuthorizationUrl and verifySocialIdentity (#2707) Co-authored-by: simeng-li --- packages/core/src/routes/interaction/index.ts | 10 ++----- .../utils/social-verification.test.ts | 13 ++++----- .../interaction/utils/social-verification.ts | 29 ++++++++++++++----- .../identifier-payload-verification.test.ts | 9 ++---- .../identifier-payload-verification.ts | 10 ++----- 5 files changed, 37 insertions(+), 34 deletions(-) diff --git a/packages/core/src/routes/interaction/index.ts b/packages/core/src/routes/interaction/index.ts index f10bef77e..decb86f58 100644 --- a/packages/core/src/routes/interaction/index.ts +++ b/packages/core/src/routes/interaction/index.ts @@ -1,4 +1,3 @@ -import type { ConnectorSession } from '@logto/connector-kit'; import type { LogtoErrorCode } from '@logto/phrases'; import { Event, eventGuard, identifierPayloadGuard, profileGuard } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; @@ -15,7 +14,6 @@ import type { AnonymousRouter } from '../types.js'; import submitInteraction from './actions/submit-interaction.js'; import { sendPasscodePayloadGuard, socialAuthorizationUrlPayloadGuard } from './types/guard.js'; import { - assignConnectorSessionResult, getInteractionStorage, storeInteractionResult, mergeIdentifiers, @@ -236,11 +234,9 @@ export default function interactionRoutes( // Check interaction exists await getInteractionStorage(ctx, provider); - const redirectTo = await createSocialAuthorizationUrl( - ctx.guard.body, - async (connectorStorage: ConnectorSession) => - assignConnectorSessionResult(ctx, provider, connectorStorage) - ); + const { body: payload } = ctx.guard; + + const redirectTo = await createSocialAuthorizationUrl(ctx, provider, payload); ctx.body = { redirectTo }; diff --git a/packages/core/src/routes/interaction/utils/social-verification.test.ts b/packages/core/src/routes/interaction/utils/social-verification.test.ts index ad4b56011..5d3825098 100644 --- a/packages/core/src/routes/interaction/utils/social-verification.test.ts +++ b/packages/core/src/routes/interaction/utils/social-verification.test.ts @@ -1,7 +1,9 @@ import { ConnectorType } from '@logto/connector-kit'; import { mockEsm } from '@logto/shared/esm'; +import createMockContext from '#src/test-utils/jest-koa-mocks/create-mock-context.js'; import { createMockLogContext } from '#src/test-utils/koa-audit-log.js'; +import { createMockProvider } from '#src/test-utils/oidc-provider.js'; const { jest } = import.meta; @@ -24,16 +26,13 @@ const log = createMockLogContext(); describe('social-verification', () => { it('verifySocialIdentity', async () => { - const getSession = jest.fn(); + const provider = createMockProvider(); + const ctx = { ...createMockContext(), ...log }; const connectorId = 'connector'; const connectorData = { authCode: 'code' }; - const userInfo = await verifySocialIdentity( - { connectorId, connectorData }, - log.createLog, - getSession - ); + const userInfo = await verifySocialIdentity({ connectorId, connectorData }, ctx, provider); - expect(getUserInfoByAuthCode).toBeCalledWith(connectorId, connectorData, getSession); + expect(getUserInfoByAuthCode).toBeCalledWith(connectorId, connectorData, expect.anything()); expect(userInfo).toEqual({ id: 'foo' }); }); }); diff --git a/packages/core/src/routes/interaction/utils/social-verification.ts b/packages/core/src/routes/interaction/utils/social-verification.ts index f4c2c40fb..6963031f2 100644 --- a/packages/core/src/routes/interaction/utils/social-verification.ts +++ b/packages/core/src/routes/interaction/utils/social-verification.ts @@ -1,18 +1,25 @@ -import type { GetSession, SetSession } from '@logto/connector-kit'; +import type { ConnectorSession } from '@logto/connector-kit'; import type { SocialConnectorPayload } from '@logto/schemas'; import { ConnectorType } from '@logto/schemas'; +import type { Context } from 'koa'; +import type { Provider } from 'oidc-provider'; import { getLogtoConnectorById } from '#src/connectors/index.js'; import type { SocialUserInfo } from '#src/connectors/types.js'; import { getUserInfoByAuthCode } from '#src/libraries/social.js'; import type { LogContext } from '#src/middleware/koa-audit-log.js'; +import { + getConnectorSessionResult, + assignConnectorSessionResult, +} from '#src/routes/interaction/utils/interaction.js'; import assertThat from '#src/utils/assert-that.js'; import type { SocialAuthorizationUrlPayload } from '../types/index.js'; export const createSocialAuthorizationUrl = async ( - payload: SocialAuthorizationUrlPayload, - setConnectorSession?: SetSession + ctx: Context, + provider: Provider, + payload: SocialAuthorizationUrlPayload ) => { const { connectorId, state, redirectUri } = payload; assertThat(state && redirectUri, 'session.insufficient_info'); @@ -21,18 +28,26 @@ export const createSocialAuthorizationUrl = async ( assertThat(connector.type === ConnectorType.Social, 'connector.unexpected_type'); - return connector.getAuthorizationUri({ state, redirectUri }, setConnectorSession); + return connector.getAuthorizationUri( + { state, redirectUri }, + async (connectorStorage: ConnectorSession) => + assignConnectorSessionResult(ctx, provider, connectorStorage) + ); }; export const verifySocialIdentity = async ( { connectorId, connectorData }: SocialConnectorPayload, - createLog: LogContext['createLog'], - getSession?: GetSession + ctx: Context, + provider: Provider ): Promise => { + // eslint-disable-next-line prefer-destructuring, @typescript-eslint/no-unsafe-assignment + const createLog: LogContext['createLog'] = ctx.createLog; const log = createLog('Interaction.SignIn.Identifier.Social.Submit'); log.append({ connectorId, connectorData }); - const userInfo = await getUserInfoByAuthCode(connectorId, connectorData, getSession); + const userInfo = await getUserInfoByAuthCode(connectorId, connectorData, async () => + getConnectorSessionResult(ctx, provider) + ); log.append(userInfo); diff --git a/packages/core/src/routes/interaction/verifications/identifier-payload-verification.test.ts b/packages/core/src/routes/interaction/verifications/identifier-payload-verification.test.ts index 3fabc539f..18980e150 100644 --- a/packages/core/src/routes/interaction/verifications/identifier-payload-verification.test.ts +++ b/packages/core/src/routes/interaction/verifications/identifier-payload-verification.test.ts @@ -154,18 +154,15 @@ describe('identifier verification', () => { it('social', async () => { const identifier = { connectorId: 'logto', connectorData: {} }; + const provider = createMockProvider(); const result = await identifierPayloadVerification( baseCtx, - createMockProvider(), + provider, identifier, interactionStorage ); - expect(verifySocialIdentity).toBeCalledWith( - identifier, - logContext.createLog, - expect.anything() - ); + expect(verifySocialIdentity).toBeCalledWith(identifier, baseCtx, provider); expect(findUserByIdentifier).not.toBeCalled(); expect(result).toEqual({ diff --git a/packages/core/src/routes/interaction/verifications/identifier-payload-verification.ts b/packages/core/src/routes/interaction/verifications/identifier-payload-verification.ts index 1a4eac36f..76108edc6 100644 --- a/packages/core/src/routes/interaction/verifications/identifier-payload-verification.ts +++ b/packages/core/src/routes/interaction/verifications/identifier-payload-verification.ts @@ -1,4 +1,3 @@ -import type { GetSession } from '@logto/connector-kit'; import type { Event, IdentifierPayload, @@ -10,7 +9,6 @@ import type { Provider } from 'oidc-provider'; import RequestError from '#src/errors/RequestError/index.js'; import { verifyUserPassword } from '#src/libraries/user.js'; -import { getConnectorSessionResult } from '#src/routes/interaction/utils/interaction.js'; import assertThat from '#src/utils/assert-that.js'; import type { @@ -60,9 +58,9 @@ const verifyPasscodeIdentifier = async ( const verifySocialIdentifier = async ( identifier: SocialConnectorPayload, ctx: Context, - getSession?: GetSession + provider: Provider ): Promise => { - const userInfo = await verifySocialIdentity(identifier, ctx.createLog, getSession); + const userInfo = await verifySocialIdentity(identifier, ctx, provider); return { key: 'social', connectorId: identifier.connectorId, userInfo }; }; @@ -104,9 +102,7 @@ export default async function identifierPayloadVerification( } if (isSocialIdentifier(identifierPayload)) { - return verifySocialIdentifier(identifierPayload, ctx, async () => - getConnectorSessionResult(ctx, provider) - ); + return verifySocialIdentifier(identifierPayload, ctx, provider); } // Sign-In with social verified email or phone