mirror of
https://github.com/logto-io/logto.git
synced 2025-01-20 21:32:31 -05:00
chore: add tests
This commit is contained in:
parent
942780fcfa
commit
552a3e59db
4 changed files with 96 additions and 17 deletions
|
@ -212,10 +212,18 @@ export const mockGoogleConnector: LogtoConnector = {
|
||||||
dbEntry: {
|
dbEntry: {
|
||||||
...mockConnector,
|
...mockConnector,
|
||||||
id: 'google',
|
id: 'google',
|
||||||
|
config: {
|
||||||
|
clientId: 'fake_client_id',
|
||||||
|
clientSecret: 'fake_client_secret',
|
||||||
|
oneTap: {
|
||||||
|
isEnabled: true,
|
||||||
|
autoSelect: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
metadata: {
|
metadata: {
|
||||||
...mockMetadata,
|
...mockMetadata,
|
||||||
id: 'google',
|
id: 'google-universal',
|
||||||
target: 'google',
|
target: 'google',
|
||||||
platform: ConnectorPlatform.Web,
|
platform: ConnectorPlatform.Web,
|
||||||
},
|
},
|
||||||
|
@ -238,16 +246,6 @@ export const mockDemoSocialConnector: LogtoConnector = {
|
||||||
...mockLogtoConnector,
|
...mockLogtoConnector,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mockLogtoConnectors = [
|
|
||||||
mockAliyunDmConnector,
|
|
||||||
mockAliyunSmsConnector,
|
|
||||||
mockFacebookConnector,
|
|
||||||
mockGithubConnector,
|
|
||||||
mockGoogleConnector,
|
|
||||||
mockWechatConnector,
|
|
||||||
mockWechatNativeConnector,
|
|
||||||
];
|
|
||||||
|
|
||||||
export const socialTarget01 = 'socialTarget-id01';
|
export const socialTarget01 = 'socialTarget-id01';
|
||||||
export const socialTarget02 = 'socialTarget-id02';
|
export const socialTarget02 = 'socialTarget-id02';
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ import { builtInLanguages } from '@logto/phrases-experience';
|
||||||
import type { CreateSignInExperience, SignInExperience } from '@logto/schemas';
|
import type { CreateSignInExperience, SignInExperience } from '@logto/schemas';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
mockGithubConnector,
|
||||||
|
mockGoogleConnector,
|
||||||
mockSignInExperience,
|
mockSignInExperience,
|
||||||
mockSocialConnectors,
|
mockSocialConnectors,
|
||||||
socialTarget01,
|
socialTarget01,
|
||||||
|
@ -170,6 +172,48 @@ describe('getFullSignInExperience()', () => {
|
||||||
googleOneTap: undefined,
|
googleOneTap: undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return full sign-in experience with google one tap', async () => {
|
||||||
|
findDefaultSignInExperience.mockResolvedValueOnce({
|
||||||
|
...mockSignInExperience,
|
||||||
|
socialSignInConnectorTargets: ['github', 'facebook', 'google'],
|
||||||
|
});
|
||||||
|
getLogtoConnectors.mockResolvedValueOnce([mockGoogleConnector, mockGithubConnector]);
|
||||||
|
ssoConnectorLibrary.getAvailableSsoConnectors.mockResolvedValueOnce([
|
||||||
|
wellConfiguredSsoConnector,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const fullSignInExperience = await getFullSignInExperience('en');
|
||||||
|
const connectorFactory = ssoConnectorFactories[wellConfiguredSsoConnector.providerName];
|
||||||
|
|
||||||
|
expect(fullSignInExperience).toStrictEqual({
|
||||||
|
...mockSignInExperience,
|
||||||
|
socialConnectors: [
|
||||||
|
{ ...mockGithubConnector.metadata, id: mockGithubConnector.dbEntry.id },
|
||||||
|
{ ...mockGoogleConnector.metadata, id: mockGoogleConnector.dbEntry.id },
|
||||||
|
],
|
||||||
|
socialSignInConnectorTargets: ['github', 'facebook', 'google'],
|
||||||
|
forgotPassword: {
|
||||||
|
email: false,
|
||||||
|
phone: false,
|
||||||
|
},
|
||||||
|
ssoConnectors: [
|
||||||
|
{
|
||||||
|
id: wellConfiguredSsoConnector.id,
|
||||||
|
connectorName: connectorFactory.name.en,
|
||||||
|
logo: connectorFactory.logo,
|
||||||
|
darkLogo: connectorFactory.logoDark,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isDevelopmentTenant: false,
|
||||||
|
googleOneTap: {
|
||||||
|
isEnabled: true,
|
||||||
|
autoSelect: true,
|
||||||
|
clientId: 'fake_client_id',
|
||||||
|
connectorId: 'google',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('get sso connectors', () => {
|
describe('get sso connectors', () => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ConnectorType } from '@logto/connector-kit';
|
import { ConnectorType, GoogleConnector } from '@logto/connector-kit';
|
||||||
import { createMockUtils } from '@logto/shared/esm';
|
import { createMockUtils } from '@logto/shared/esm';
|
||||||
|
|
||||||
import type { WithLogContext } from '#src/middleware/koa-audit-log.js';
|
import type { WithLogContext } from '#src/middleware/koa-audit-log.js';
|
||||||
|
@ -27,8 +27,8 @@ mockEsm('#src/libraries/connector.js', () => ({
|
||||||
|
|
||||||
const { verifySocialIdentity } = await import('./social-verification.js');
|
const { verifySocialIdentity } = await import('./social-verification.js');
|
||||||
|
|
||||||
describe('social-verification', () => {
|
describe('verifySocialIdentity', () => {
|
||||||
it('verifySocialIdentity', async () => {
|
it('should verify social identity', async () => {
|
||||||
// @ts-expect-error test mock context
|
// @ts-expect-error test mock context
|
||||||
const ctx: WithLogContext = {
|
const ctx: WithLogContext = {
|
||||||
...createMockContext(),
|
...createMockContext(),
|
||||||
|
@ -41,4 +41,37 @@ describe('social-verification', () => {
|
||||||
expect(getUserInfo).toBeCalledWith(connectorId, connectorData, expect.anything());
|
expect(getUserInfo).toBeCalledWith(connectorId, connectorData, expect.anything());
|
||||||
expect(userInfo).toEqual({ id: 'foo' });
|
expect(userInfo).toEqual({ id: 'foo' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw error if csrf token is not matched for Google One Tap verification', async () => {
|
||||||
|
const ctx: WithLogContext = {
|
||||||
|
...createMockContext(),
|
||||||
|
...createMockLogContext(),
|
||||||
|
// @ts-expect-error test mock context
|
||||||
|
cookies: { get: jest.fn().mockReturnValue('token') },
|
||||||
|
};
|
||||||
|
const connectorId = GoogleConnector.factoryId;
|
||||||
|
const connectorData = { credential: 'credential' };
|
||||||
|
|
||||||
|
await expect(verifySocialIdentity({ connectorId, connectorData }, ctx, tenant)).rejects.toThrow(
|
||||||
|
'CSRF token mismatch.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should verify Google One Tap verification', async () => {
|
||||||
|
const ctx: WithLogContext = {
|
||||||
|
...createMockContext(),
|
||||||
|
...createMockLogContext(),
|
||||||
|
// @ts-expect-error test mock context
|
||||||
|
cookies: { get: jest.fn().mockReturnValue('token') },
|
||||||
|
};
|
||||||
|
const connectorId = GoogleConnector.factoryId;
|
||||||
|
const connectorData = {
|
||||||
|
[GoogleConnector.oneTapParams.credential]: 'credential',
|
||||||
|
[GoogleConnector.oneTapParams.csrfToken]: 'token',
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
verifySocialIdentity({ connectorId, connectorData }, ctx, tenant)
|
||||||
|
).resolves.toEqual({ id: 'foo' });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -63,9 +63,13 @@ export const verifySocialIdentity = async (
|
||||||
const log = ctx.createLog('Interaction.SignIn.Identifier.Social.Submit');
|
const log = ctx.createLog('Interaction.SignIn.Identifier.Social.Submit');
|
||||||
log.append({ connectorId, connectorData });
|
log.append({ connectorId, connectorData });
|
||||||
|
|
||||||
// Verify Google One Tap CSRF token, if it exists
|
// Verify the CSRF token if it's a Google connector and has credential (a Google One Tap
|
||||||
const csrfToken = connectorData[GoogleConnector.oneTapParams.csrfToken];
|
// verification)
|
||||||
if (csrfToken) {
|
if (
|
||||||
|
connectorId === GoogleConnector.factoryId &&
|
||||||
|
connectorData[GoogleConnector.oneTapParams.credential]
|
||||||
|
) {
|
||||||
|
const csrfToken = connectorData[GoogleConnector.oneTapParams.csrfToken];
|
||||||
const value = ctx.cookies.get(GoogleConnector.oneTapParams.csrfToken);
|
const value = ctx.cookies.get(GoogleConnector.oneTapParams.csrfToken);
|
||||||
assertThat(value === csrfToken, 'session.csrf_token_mismatch');
|
assertThat(value === csrfToken, 'session.csrf_token_mismatch');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue