From e892dc34c5b7c37aafea6629a2b72116ae41d934 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Wed, 12 Jun 2024 15:49:49 +0800 Subject: [PATCH] feat(schemas): add `agree_to_terms_policy` for sie table --- .../core/src/__mocks__/sign-in-experience.ts | 3 +- .../src/queries/sign-in-experience.test.ts | 2 +- packages/experience/src/__mocks__/logto.tsx | 3 ++ ...xt-1718594164-add-agree-to-terms-policy.ts | 40 +++++++++++++++++++ .../schemas/tables/sign_in_experiences.sql | 8 ++++ 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 packages/schemas/alterations/next-1718594164-add-agree-to-terms-policy.ts diff --git a/packages/core/src/__mocks__/sign-in-experience.ts b/packages/core/src/__mocks__/sign-in-experience.ts index 6e92ec63a651..1c4eb86185e7 100644 --- a/packages/core/src/__mocks__/sign-in-experience.ts +++ b/packages/core/src/__mocks__/sign-in-experience.ts @@ -6,7 +6,7 @@ import type { SignUp, SignIn, } from '@logto/schemas'; -import { SignInMode, SignInIdentifier, MfaPolicy } from '@logto/schemas'; +import { SignInMode, SignInIdentifier, MfaPolicy, AgreeToTermsPolicy } from '@logto/schemas'; export const mockColor: Color = { primaryColor: '#000', @@ -91,6 +91,7 @@ export const mockSignInExperience: SignInExperience = { signInMode: SignInMode.SignInAndRegister, customCss: null, customContent: {}, + agreeToTermsPolicy: AgreeToTermsPolicy.Automatic, passwordPolicy: {}, mfa: { policy: MfaPolicy.UserControlled, diff --git a/packages/core/src/queries/sign-in-experience.test.ts b/packages/core/src/queries/sign-in-experience.test.ts index c18b5a2057a8..4c4de7e04438 100644 --- a/packages/core/src/queries/sign-in-experience.test.ts +++ b/packages/core/src/queries/sign-in-experience.test.ts @@ -40,7 +40,7 @@ describe('sign-in-experience query', () => { 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", "social_sign_in_connector_targets", "sign_in_mode", "custom_css", "custom_content", "password_policy", "mfa", "single_sign_on_enabled" + select "tenant_id", "id", "color", "branding", "language_info", "terms_of_use_url", "privacy_policy_url", "agree_to_terms_policy", "sign_in", "sign_up", "social_sign_in", "social_sign_in_connector_targets", "sign_in_mode", "custom_css", "custom_content", "password_policy", "mfa", "single_sign_on_enabled" from "sign_in_experiences" where "id"=$1 `; diff --git a/packages/experience/src/__mocks__/logto.tsx b/packages/experience/src/__mocks__/logto.tsx index ec3b66d09d85..fff0e1daf0d6 100644 --- a/packages/experience/src/__mocks__/logto.tsx +++ b/packages/experience/src/__mocks__/logto.tsx @@ -1,5 +1,6 @@ import type { SignInExperience, SignIn, SsoConnectorMetadata } from '@logto/schemas'; import { + AgreeToTermsPolicy, ConnectorPlatform, ConnectorType, MfaPolicy, @@ -104,6 +105,7 @@ export const mockSignInExperience: SignInExperience = { signInMode: SignInMode.SignInAndRegister, customCss: null, customContent: {}, + agreeToTermsPolicy: AgreeToTermsPolicy.Automatic, passwordPolicy: {}, mfa: { policy: MfaPolicy.UserControlled, @@ -136,6 +138,7 @@ export const mockSignInExperienceSettings: SignInExperienceResponse = { }, customCss: null, customContent: {}, + agreeToTermsPolicy: AgreeToTermsPolicy.Automatic, passwordPolicy: {}, mfa: { policy: MfaPolicy.UserControlled, diff --git a/packages/schemas/alterations/next-1718594164-add-agree-to-terms-policy.ts b/packages/schemas/alterations/next-1718594164-add-agree-to-terms-policy.ts new file mode 100644 index 000000000000..b8f7b6835920 --- /dev/null +++ b/packages/schemas/alterations/next-1718594164-add-agree-to-terms-policy.ts @@ -0,0 +1,40 @@ +import { yes } from '@silverhand/essentials'; +import { sql } from '@silverhand/slonik'; + +import type { AlterationScript } from '../lib/types/alteration.js'; + +const isCi = yes(process.env.CI); + +const alteration: AlterationScript = { + up: async (pool) => { + // Create type + await pool.query(sql` + create type agree_to_terms_policy as enum ('Automatic', 'ManualRegistrationOnly', 'Manual'); + `); + + if (isCi) { + // Direct set default to 'Automatic' to align with the sql table definition when running CI + await pool.query(sql` + alter table sign_in_experiences add column agree_to_terms_policy agree_to_terms_policy not null default 'Automatic'; + `); + } else { + // For compatibility with existing data, default to 'ManualRegistrationOnly' + await pool.query(sql` + alter table sign_in_experiences add column agree_to_terms_policy agree_to_terms_policy not null default 'ManualRegistrationOnly'; + `); + + // For new data, default to 'Automatic' + await pool.query(sql` + alter table sign_in_experiences alter column agree_to_terms_policy set default 'Automatic'; + `); + } + }, + down: async (pool) => { + await pool.query(sql` + alter table sign_in_experiences drop column agree_to_terms_policy; + drop type agree_to_terms_policy; + `); + }, +}; + +export default alteration; diff --git a/packages/schemas/tables/sign_in_experiences.sql b/packages/schemas/tables/sign_in_experiences.sql index 21594b0c6ebc..7042afcf688f 100644 --- a/packages/schemas/tables/sign_in_experiences.sql +++ b/packages/schemas/tables/sign_in_experiences.sql @@ -1,4 +1,5 @@ create type sign_in_mode as enum ('SignIn', 'Register', 'SignInAndRegister'); +create type agree_to_terms_policy as enum ('Automatic', 'ManualRegistrationOnly', 'Manual'); create table sign_in_experiences ( tenant_id varchar(21) not null @@ -9,6 +10,13 @@ create table sign_in_experiences ( language_info jsonb /* @use LanguageInfo */ not null, terms_of_use_url varchar(2048), privacy_policy_url varchar(2048), + /** + * The policy that determines how users agree to the terms of use and privacy policy. + * - Automatic: users automatically agree to terms by continuing to use the service + * - ManualRegistrationOnly: users must agree to terms by checking a box during registration, and don't need to agree when signing in + * - Manual: users must agree to terms by checking a box during registration or signing in + */ + agree_to_terms_policy agree_to_terms_policy not null default 'Automatic', sign_in jsonb /* @use SignIn */ not null, sign_up jsonb /* @use SignUp */ not null, social_sign_in jsonb /* @use SocialSignIn */ not null default '{}'::jsonb,