0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-24 22:05:56 -05:00

feat(schemas): add mfa to sign in experience table (#4396)

This commit is contained in:
wangsijie 2023-09-12 10:36:47 +08:00 committed by GitHub
parent b48810146d
commit b91aa8d3d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 204 additions and 127 deletions

View file

@ -6,7 +6,7 @@ import type {
SignUp,
SignIn,
} from '@logto/schemas';
import { SignInMode, SignInIdentifier } from '@logto/schemas';
import { SignInMode, SignInIdentifier, MfaPolicy } from '@logto/schemas';
export const mockColor: Color = {
primaryColor: '#000',
@ -92,4 +92,8 @@ export const mockSignInExperience: SignInExperience = {
customCss: null,
customContent: {},
passwordPolicy: {},
mfa: {
policy: MfaPolicy.UserControlled,
factors: [],
},
};

View file

@ -33,12 +33,13 @@ describe('sign-in-experience query', () => {
socialSignInConnectorTargets: JSON.stringify(mockSignInExperience.socialSignInConnectorTargets),
customContent: JSON.stringify(mockSignInExperience.customContent),
passwordPolicy: JSON.stringify(mockSignInExperience.passwordPolicy),
mfa: JSON.stringify(mockSignInExperience.mfa),
};
it('findDefaultSignInExperience', async () => {
/* eslint-disable sql/no-unsafe-query */
const expectSql = `
select "tenant_id", "id", "color", "branding", "language_info", "terms_of_use_url", "privacy_policy_url", "sign_in", "sign_up", "social_sign_in_connector_targets", "sign_in_mode", "custom_css", "custom_content", "password_policy"
select "tenant_id", "id", "color", "branding", "language_info", "terms_of_use_url", "privacy_policy_url", "sign_in", "sign_up", "social_sign_in_connector_targets", "sign_in_mode", "custom_css", "custom_content", "password_policy", "mfa"
from "sign_in_experiences"
where "id"=$1
`;

View file

@ -0,0 +1,26 @@
import { sql } from 'slonik';
import type { AlterationScript } from '../lib/types/alteration.js';
const alteration: AlterationScript = {
up: async (pool) => {
await pool.query(sql`
alter table sign_in_experiences
add column if not exists mfa jsonb not null default '{}'::jsonb;
`);
await pool.query(sql`
update sign_in_experiences
set mfa = '{"factors":[],"policy":"UserControlled"}'
where id = 'default';
`);
},
down: async (pool) => {
await pool.query(sql`
alter table sign_in_experiences
drop column mfa;
`);
},
};
export default alteration;

View file

@ -164,6 +164,28 @@ export const customContentGuard = z.record(z.string());
export type CustomContent = z.infer<typeof customContentGuard>;
export enum MfaFactor {
TOTP = 'TOTP',
WebAuthn = 'WebAuthn',
BackupCode = 'BackupCode',
}
export const mfaFactorsGuard = z.nativeEnum(MfaFactor).array();
export type MfaFactors = z.infer<typeof mfaFactorsGuard>;
export enum MfaPolicy {
UserControlled = 'UserControlled',
Mandatory = 'Mandatory',
}
export const mfaGuard = z.object({
factors: mfaFactorsGuard,
policy: z.nativeEnum(MfaPolicy),
});
export type Mfa = z.infer<typeof mfaGuard>;
/* === Phrases === */
export type Translation = {

View file

@ -2,7 +2,7 @@ import { generateDarkColor } from '@logto/core-kit';
import type { CreateSignInExperience } from '../db-entries/index.js';
import { SignInMode } from '../db-entries/index.js';
import { SignInIdentifier } from '../foundations/index.js';
import { MfaPolicy, SignInIdentifier } from '../foundations/index.js';
import { adminTenantId, defaultTenantId } from './tenant.js';
@ -50,6 +50,10 @@ export const createDefaultSignInExperience = (
customCss: null,
customContent: {},
passwordPolicy: {},
mfa: {
factors: [],
policy: MfaPolicy.UserControlled,
},
});
/** @deprecated Use `createDefaultSignInExperience()` instead. */

View file

@ -16,5 +16,6 @@ create table sign_in_experiences (
custom_css text,
custom_content jsonb /* @use CustomContent */ not null default '{}'::jsonb,
password_policy jsonb /* @use PartialPasswordPolicy */ not null default '{}'::jsonb,
mfa jsonb /* @use Mfa */ not null default '{}'::jsonb,
primary key (tenant_id, id)
);

View file

@ -1,134 +1,21 @@
import type { SignInExperience, SignIn } from '@logto/schemas';
import { ConnectorPlatform, ConnectorType, SignInIdentifier, SignInMode } from '@logto/schemas';
import {
ConnectorPlatform,
ConnectorType,
MfaPolicy,
SignInIdentifier,
SignInMode,
} from '@logto/schemas';
import type { SignInExperienceResponse } from '@/types';
import { socialConnectors } from './social-connectors';
export * from './social-connectors';
export const appLogo = 'https://avatars.githubusercontent.com/u/88327661?s=200&v=4';
export const appHeadline = 'Build user identity in a modern way';
export const socialConnectors = [
{
id: 'BE8QXN0VsrOH7xdWFDJZ9',
target: 'github',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with GitHub',
'pt-PT': 'Entrar com GitHub',
'zh-CN': '使用 GitHub 登录',
'tr-TR': 'Github ile giriş yap',
ko: 'Github 로그인',
},
description: {
en: 'Sign in with GitHub',
'pt-PT': 'Entrar com GitHub',
'zh-CN': '使用 GitHub 登录',
'tr-TR': 'Github ile giriş yap',
ko: 'Github 로그인',
},
readme: '',
configTemplate: '',
},
{
id: '24yt_xIUl5btN4UwvFokt',
target: 'alipay',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with Alipay',
'pt-PT': 'Entrar com Alipay',
'zh-CN': '使用 Alipay 登录',
'tr-TR': 'Alipay ile giriş yap',
ko: 'Alipay 로그인',
},
description: {
en: 'Sign in with Alipay',
'pt-PT': 'Entrar com Alipay',
'zh-CN': '使用 Alipay 登录',
'tr-TR': 'Alipay ile giriş yap',
ko: 'Alipay 로그인',
},
readme: '',
configTemplate: '',
},
{
id: 'E5kb2gdq769qOEYaLg1V5',
target: 'wechat',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with WeChat',
'pt-PT': 'Entrar com WeChat',
'zh-CN': '使用 WeChat 登录',
'tr-TR': 'WeChat ile giriş yap',
ko: 'WeChat 로그인',
},
description: {
en: 'Sign in with WeChat',
'pt-PT': 'Entrar com WeChat',
'zh-CN': '使用 WeChat 登录',
'tr-TR': 'WeChat ile giriş yap',
ko: 'WeChat 로그인',
},
readme: '',
configTemplate: '',
},
{
id: 'xY2YZEweMFPKxphngGHhy',
target: 'google',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with Google',
'pt-PT': 'Entrar com Google',
'zh-CN': '使用 Google 登录',
'tr-TR': 'Google ile giriş yap',
ko: 'Google 로그인',
},
description: {
en: 'Sign in with Google',
'pt-PT': 'Entrar com Google',
'zh-CN': '使用 Google 登录',
'tr-TR': 'Google ile giriş yap',
ko: 'Google 로그인',
},
readme: '',
configTemplate: '',
},
{
id: 'lcXT4o2GSjbV9kg2shZC7',
target: 'facebook',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with Meta',
'pt-PT': 'Entrar com Facebook',
'zh-CN': '使用 Meta 登录',
'tr-TR': 'Meta ile giriş yap',
ko: 'Meta 로그인',
},
description: {
en: 'Sign in with Meta',
'pt-PT': 'Entrar com Facebook',
'zh-CN': '使用 Meta 登录',
'tr-TR': 'Meta ile giriş yap',
ko: 'Meta 로그인',
},
readme: '',
configTemplate: '',
},
];
export const mockSocialConnectorData = {
id: 'arbitrary-social-connector-data',
target: 'google',
@ -205,6 +92,10 @@ export const mockSignInExperience: SignInExperience = {
customCss: null,
customContent: {},
passwordPolicy: {},
mfa: {
policy: MfaPolicy.UserControlled,
factors: [],
},
};
export const mockSignInExperienceSettings: SignInExperienceResponse = {
@ -230,6 +121,10 @@ export const mockSignInExperienceSettings: SignInExperienceResponse = {
customCss: null,
customContent: {},
passwordPolicy: {},
mfa: {
policy: MfaPolicy.UserControlled,
factors: [],
},
};
const usernameSettings = {

View file

@ -0,0 +1,124 @@
import { ConnectorPlatform, ConnectorType } from '@logto/connector-kit';
export const socialConnectors = [
{
id: 'BE8QXN0VsrOH7xdWFDJZ9',
target: 'github',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with GitHub',
'pt-PT': 'Entrar com GitHub',
'zh-CN': '使用 GitHub 登录',
'tr-TR': 'Github ile giriş yap',
ko: 'Github 로그인',
},
description: {
en: 'Sign in with GitHub',
'pt-PT': 'Entrar com GitHub',
'zh-CN': '使用 GitHub 登录',
'tr-TR': 'Github ile giriş yap',
ko: 'Github 로그인',
},
readme: '',
configTemplate: '',
},
{
id: '24yt_xIUl5btN4UwvFokt',
target: 'alipay',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with Alipay',
'pt-PT': 'Entrar com Alipay',
'zh-CN': '使用 Alipay 登录',
'tr-TR': 'Alipay ile giriş yap',
ko: 'Alipay 로그인',
},
description: {
en: 'Sign in with Alipay',
'pt-PT': 'Entrar com Alipay',
'zh-CN': '使用 Alipay 登录',
'tr-TR': 'Alipay ile giriş yap',
ko: 'Alipay 로그인',
},
readme: '',
configTemplate: '',
},
{
id: 'E5kb2gdq769qOEYaLg1V5',
target: 'wechat',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with WeChat',
'pt-PT': 'Entrar com WeChat',
'zh-CN': '使用 WeChat 登录',
'tr-TR': 'WeChat ile giriş yap',
ko: 'WeChat 로그인',
},
description: {
en: 'Sign in with WeChat',
'pt-PT': 'Entrar com WeChat',
'zh-CN': '使用 WeChat 登录',
'tr-TR': 'WeChat ile giriş yap',
ko: 'WeChat 로그인',
},
readme: '',
configTemplate: '',
},
{
id: 'xY2YZEweMFPKxphngGHhy',
target: 'google',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with Google',
'pt-PT': 'Entrar com Google',
'zh-CN': '使用 Google 登录',
'tr-TR': 'Google ile giriş yap',
ko: 'Google 로그인',
},
description: {
en: 'Sign in with Google',
'pt-PT': 'Entrar com Google',
'zh-CN': '使用 Google 登录',
'tr-TR': 'Google ile giriş yap',
ko: 'Google 로그인',
},
readme: '',
configTemplate: '',
},
{
id: 'lcXT4o2GSjbV9kg2shZC7',
target: 'facebook',
platform: ConnectorPlatform.Web,
type: ConnectorType.Social,
logo: 'https://user-images.githubusercontent.com/5717882/156983224-7ea0296b-38fa-419d-9515-67e8a9612e09.png',
logoDark: null,
name: {
en: 'Sign in with Meta',
'pt-PT': 'Entrar com Facebook',
'zh-CN': '使用 Meta 登录',
'tr-TR': 'Meta ile giriş yap',
ko: 'Meta 로그인',
},
description: {
en: 'Sign in with Meta',
'pt-PT': 'Entrar com Facebook',
'zh-CN': '使用 Meta 登录',
'tr-TR': 'Meta ile giriş yap',
ko: 'Meta 로그인',
},
readme: '',
configTemplate: '',
},
];