@logto/schemas 1.35.0 → 1.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/alterations/1.36.0-1767193412-allow-token-exchange.ts +34 -0
  2. package/alterations/1.36.0-1767859553-passkey-sign-in.ts +21 -0
  3. package/alterations/1.36.0-1768192304-enable-account-center-for-admin-tenant.ts +32 -0
  4. package/alterations/1.36.0-1768464306-enable-mfa-for-admin-tenant.ts +30 -0
  5. package/alterations/1.36.0-1768758295-add-user-geo-location.ts +32 -0
  6. package/alterations/1.36.0-1768891516-add-user-sign-in-countries-table.ts +33 -0
  7. package/alterations/1.36.0-1769067642-add-adaptive-mfa-configuration.ts +19 -0
  8. package/alterations/1.36.0-1769172677-enable-organization-mfa-policy-for-admin-tenant.ts +31 -0
  9. package/alterations-js/1.36.0-1767193412-allow-token-exchange.js +30 -0
  10. package/alterations-js/1.36.0-1767859553-passkey-sign-in.js +17 -0
  11. package/alterations-js/1.36.0-1768192304-enable-account-center-for-admin-tenant.js +27 -0
  12. package/alterations-js/1.36.0-1768464306-enable-mfa-for-admin-tenant.js +25 -0
  13. package/alterations-js/1.36.0-1768758295-add-user-geo-location.js +27 -0
  14. package/alterations-js/1.36.0-1768891516-add-user-sign-in-countries-table.js +28 -0
  15. package/alterations-js/1.36.0-1769067642-add-adaptive-mfa-configuration.js +15 -0
  16. package/alterations-js/1.36.0-1769172677-enable-organization-mfa-policy-for-admin-tenant.js +26 -0
  17. package/lib/db-entries/index.d.ts +2 -0
  18. package/lib/db-entries/index.js +2 -0
  19. package/lib/db-entries/sign-in-experience.d.ts +6 -2
  20. package/lib/db-entries/sign-in-experience.js +9 -1
  21. package/lib/db-entries/user-geo-location.d.ts +24 -0
  22. package/lib/db-entries/user-geo-location.js +37 -0
  23. package/lib/db-entries/user-sign-in-country.d.ts +24 -0
  24. package/lib/db-entries/user-sign-in-country.js +33 -0
  25. package/lib/foundations/jsonb-types/account-centers.d.ts +2 -2
  26. package/lib/foundations/jsonb-types/logs.d.ts +703 -0
  27. package/lib/foundations/jsonb-types/logs.js +52 -0
  28. package/lib/foundations/jsonb-types/oidc-module.d.ts +15 -3
  29. package/lib/foundations/jsonb-types/oidc-module.js +15 -3
  30. package/lib/foundations/jsonb-types/saml-application-configs.d.ts +1 -1
  31. package/lib/foundations/jsonb-types/sentinel.d.ts +13 -1
  32. package/lib/foundations/jsonb-types/sentinel.js +12 -0
  33. package/lib/foundations/jsonb-types/sign-in-experience.d.ts +59 -0
  34. package/lib/foundations/jsonb-types/sign-in-experience.js +11 -0
  35. package/lib/seeds/account-center.d.ts +6 -0
  36. package/lib/seeds/account-center.js +24 -0
  37. package/lib/seeds/cloud-api.d.ts +3 -1
  38. package/lib/seeds/cloud-api.js +2 -0
  39. package/lib/seeds/sign-in-experience.js +6 -1
  40. package/lib/types/application.d.ts +6 -0
  41. package/lib/types/consent.d.ts +4 -0
  42. package/lib/types/custom-profile-fields.d.ts +3 -3
  43. package/lib/types/hook.d.ts +2 -2
  44. package/lib/types/interactions.d.ts +2 -2
  45. package/lib/types/log/index.d.ts +12 -6
  46. package/lib/types/log/interaction.d.ts +5 -1
  47. package/lib/types/logto-config/index.d.ts +9 -9
  48. package/lib/types/logto-config/jwt-customizer.d.ts +17 -17
  49. package/lib/types/saml-application.d.ts +7 -7
  50. package/lib/types/sign-in-experience.d.ts +6 -0
  51. package/lib/types/user.d.ts +7 -7
  52. package/package.json +5 -5
  53. package/tables/sign_in_experiences.sql +2 -0
  54. package/tables/user_geo_locations.sql +14 -0
  55. package/tables/user_sign_in_countries.sql +16 -0
  56. package/tables/users.sql +3 -0
@@ -0,0 +1,34 @@
1
+ import { sql } from '@silverhand/slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ const alteration: AlterationScript = {
6
+ up: async (pool) => {
7
+ /**
8
+ * For backward compatibility, set allowTokenExchange = true for existing first-party
9
+ * Traditional, Native, and SPA applications.
10
+ * M2M applications were never allowed to use token exchange before this feature.
11
+ *
12
+ * The admin-console should keep token exchange disabled, so we skip it here.
13
+ */
14
+ await pool.query(sql`
15
+ update applications
16
+ set custom_client_metadata = custom_client_metadata || '{"allowTokenExchange": true}'::jsonb
17
+ where is_third_party = false
18
+ and type in ('Traditional', 'Native', 'SPA')
19
+ and id != 'admin-console';
20
+ `);
21
+ },
22
+ down: async (pool) => {
23
+ // Remove allowTokenExchange only from applications that were updated in the `up` migration
24
+ await pool.query(sql`
25
+ update applications
26
+ set custom_client_metadata = custom_client_metadata - 'allowTokenExchange'
27
+ where is_third_party = false
28
+ and type in ('Traditional', 'Native', 'SPA')
29
+ and id != 'admin-console';
30
+ `);
31
+ },
32
+ };
33
+
34
+ export default alteration;
@@ -0,0 +1,21 @@
1
+ import { sql } from '@silverhand/slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ const alteration: AlterationScript = {
6
+ up: async (pool) => {
7
+ await pool.query(sql`
8
+ alter table sign_in_experiences
9
+ add column passkey_sign_in jsonb /* @use PasskeySignIn */ not null default '{}'::jsonb;
10
+ create index users_mfa_verifications_gin on users using gin (mfa_verifications jsonb_path_ops);
11
+ `);
12
+ },
13
+ down: async (pool) => {
14
+ await pool.query(sql`
15
+ alter table sign_in_experiences drop column passkey_sign_in;
16
+ drop index users_mfa_verifications_gin;
17
+ `);
18
+ },
19
+ };
20
+
21
+ export default alteration;
@@ -0,0 +1,32 @@
1
+ import { sql } from '@silverhand/slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ const adminTenantId = 'admin';
6
+
7
+ /**
8
+ * Enable the account center for the admin tenant and set all fields to Edit.
9
+ * This allows the console profile page to use the Account API.
10
+ */
11
+ const alteration: AlterationScript = {
12
+ up: async (pool) => {
13
+ await pool.query(sql`
14
+ update account_centers
15
+ set enabled = true,
16
+ fields = '{"name": "Edit", "avatar": "Edit", "profile": "Edit", "email": "Edit", "phone": "Edit", "password": "Edit", "username": "Edit", "social": "Edit", "customData": "Edit", "mfa": "Edit"}'::jsonb
17
+ where tenant_id = ${adminTenantId}
18
+ and id = 'default'
19
+ `);
20
+ },
21
+ down: async (pool) => {
22
+ await pool.query(sql`
23
+ update account_centers
24
+ set enabled = false,
25
+ fields = '{}'::jsonb
26
+ where tenant_id = ${adminTenantId}
27
+ and id = 'default'
28
+ `);
29
+ },
30
+ };
31
+
32
+ export default alteration;
@@ -0,0 +1,30 @@
1
+ import { sql } from '@silverhand/slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ const adminTenantId = 'admin';
6
+
7
+ /**
8
+ * Enable MFA (TOTP and WebAuthn) for the admin tenant with NoPrompt policy.
9
+ * This allows users to optionally set up MFA via the account center.
10
+ */
11
+ const alteration: AlterationScript = {
12
+ up: async (pool) => {
13
+ await pool.query(sql`
14
+ update sign_in_experiences
15
+ set mfa = '{"factors":["Totp","WebAuthn","BackupCode"],"policy":"NoPrompt"}'::jsonb
16
+ where tenant_id = ${adminTenantId}
17
+ and id = 'default'
18
+ `);
19
+ },
20
+ down: async (pool) => {
21
+ await pool.query(sql`
22
+ update sign_in_experiences
23
+ set mfa = '{"factors":[],"policy":"UserControlled"}'::jsonb
24
+ where tenant_id = ${adminTenantId}
25
+ and id = 'default'
26
+ `);
27
+ },
28
+ };
29
+
30
+ export default alteration;
@@ -0,0 +1,32 @@
1
+ import { sql } from '@silverhand/slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ import { applyTableRls, dropTableRls } from './utils/1704934999-tables.js';
6
+
7
+ const alteration: AlterationScript = {
8
+ up: async (pool) => {
9
+ await pool.query(sql`
10
+ create table user_geo_locations (
11
+ tenant_id varchar(21) not null
12
+ references tenants (id) on update cascade on delete cascade,
13
+ user_id varchar(12) not null
14
+ references users (id) on update cascade on delete cascade,
15
+ latitude numeric(9,6),
16
+ longitude numeric(9,6),
17
+ updated_at timestamptz not null default now(),
18
+ primary key (tenant_id, user_id),
19
+ check ((latitude is null) = (longitude is null))
20
+ );
21
+ `);
22
+ await applyTableRls(pool, 'user_geo_locations');
23
+ },
24
+ down: async (pool) => {
25
+ await dropTableRls(pool, 'user_geo_locations');
26
+ await pool.query(sql`
27
+ drop table user_geo_locations;
28
+ `);
29
+ },
30
+ };
31
+
32
+ export default alteration;
@@ -0,0 +1,33 @@
1
+ import { sql } from '@silverhand/slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ import { applyTableRls, dropTableRls } from './utils/1704934999-tables.js';
6
+
7
+ const alteration: AlterationScript = {
8
+ up: async (pool) => {
9
+ await pool.query(sql`
10
+ create table user_sign_in_countries (
11
+ tenant_id varchar(21) not null
12
+ references tenants (id) on update cascade on delete cascade,
13
+ user_id varchar(12) not null
14
+ references users (id) on update cascade on delete cascade,
15
+ country varchar(16) not null,
16
+ last_sign_in_at timestamptz not null default(now()),
17
+ primary key (tenant_id, user_id, country)
18
+ );
19
+
20
+ create index user_sign_in_countries__tenant_user_last_sign_in_at
21
+ on user_sign_in_countries (tenant_id, user_id, last_sign_in_at desc);
22
+ `);
23
+ await applyTableRls(pool, 'user_sign_in_countries');
24
+ },
25
+ down: async (pool) => {
26
+ await dropTableRls(pool, 'user_sign_in_countries');
27
+ await pool.query(sql`
28
+ drop table user_sign_in_countries;
29
+ `);
30
+ },
31
+ };
32
+
33
+ export default alteration;
@@ -0,0 +1,19 @@
1
+ import { sql } from '@silverhand/slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ const alteration: AlterationScript = {
6
+ up: async (pool) => {
7
+ await pool.query(sql`
8
+ alter table sign_in_experiences
9
+ add column adaptive_mfa jsonb not null default '{}'::jsonb;
10
+ `);
11
+ },
12
+ down: async (pool) => {
13
+ await pool.query(sql`
14
+ alter table sign_in_experiences drop column adaptive_mfa;
15
+ `);
16
+ },
17
+ };
18
+
19
+ export default alteration;
@@ -0,0 +1,31 @@
1
+ import { sql } from '@silverhand/slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ const adminTenantId = 'admin';
6
+
7
+ /**
8
+ * Enable organization required MFA policy for the admin tenant.
9
+ * This allows tenant admins to require MFA for all tenant members
10
+ * by setting `isMfaRequired: true` on the organization.
11
+ */
12
+ const alteration: AlterationScript = {
13
+ up: async (pool) => {
14
+ await pool.query(sql`
15
+ update sign_in_experiences
16
+ set mfa = jsonb_set(mfa, '{organizationRequiredMfaPolicy}', '"Mandatory"')
17
+ where tenant_id = ${adminTenantId}
18
+ and id = 'default'
19
+ `);
20
+ },
21
+ down: async (pool) => {
22
+ await pool.query(sql`
23
+ update sign_in_experiences
24
+ set mfa = mfa - 'organizationRequiredMfaPolicy'
25
+ where tenant_id = ${adminTenantId}
26
+ and id = 'default'
27
+ `);
28
+ },
29
+ };
30
+
31
+ export default alteration;
@@ -0,0 +1,30 @@
1
+ import { sql } from '@silverhand/slonik';
2
+ const alteration = {
3
+ up: async (pool) => {
4
+ /**
5
+ * For backward compatibility, set allowTokenExchange = true for existing first-party
6
+ * Traditional, Native, and SPA applications.
7
+ * M2M applications were never allowed to use token exchange before this feature.
8
+ *
9
+ * The admin-console should keep token exchange disabled, so we skip it here.
10
+ */
11
+ await pool.query(sql `
12
+ update applications
13
+ set custom_client_metadata = custom_client_metadata || '{"allowTokenExchange": true}'::jsonb
14
+ where is_third_party = false
15
+ and type in ('Traditional', 'Native', 'SPA')
16
+ and id != 'admin-console';
17
+ `);
18
+ },
19
+ down: async (pool) => {
20
+ // Remove allowTokenExchange only from applications that were updated in the `up` migration
21
+ await pool.query(sql `
22
+ update applications
23
+ set custom_client_metadata = custom_client_metadata - 'allowTokenExchange'
24
+ where is_third_party = false
25
+ and type in ('Traditional', 'Native', 'SPA')
26
+ and id != 'admin-console';
27
+ `);
28
+ },
29
+ };
30
+ export default alteration;
@@ -0,0 +1,17 @@
1
+ import { sql } from '@silverhand/slonik';
2
+ const alteration = {
3
+ up: async (pool) => {
4
+ await pool.query(sql `
5
+ alter table sign_in_experiences
6
+ add column passkey_sign_in jsonb /* @use PasskeySignIn */ not null default '{}'::jsonb;
7
+ create index users_mfa_verifications_gin on users using gin (mfa_verifications jsonb_path_ops);
8
+ `);
9
+ },
10
+ down: async (pool) => {
11
+ await pool.query(sql `
12
+ alter table sign_in_experiences drop column passkey_sign_in;
13
+ drop index users_mfa_verifications_gin;
14
+ `);
15
+ },
16
+ };
17
+ export default alteration;
@@ -0,0 +1,27 @@
1
+ import { sql } from '@silverhand/slonik';
2
+ const adminTenantId = 'admin';
3
+ /**
4
+ * Enable the account center for the admin tenant and set all fields to Edit.
5
+ * This allows the console profile page to use the Account API.
6
+ */
7
+ const alteration = {
8
+ up: async (pool) => {
9
+ await pool.query(sql `
10
+ update account_centers
11
+ set enabled = true,
12
+ fields = '{"name": "Edit", "avatar": "Edit", "profile": "Edit", "email": "Edit", "phone": "Edit", "password": "Edit", "username": "Edit", "social": "Edit", "customData": "Edit", "mfa": "Edit"}'::jsonb
13
+ where tenant_id = ${adminTenantId}
14
+ and id = 'default'
15
+ `);
16
+ },
17
+ down: async (pool) => {
18
+ await pool.query(sql `
19
+ update account_centers
20
+ set enabled = false,
21
+ fields = '{}'::jsonb
22
+ where tenant_id = ${adminTenantId}
23
+ and id = 'default'
24
+ `);
25
+ },
26
+ };
27
+ export default alteration;
@@ -0,0 +1,25 @@
1
+ import { sql } from '@silverhand/slonik';
2
+ const adminTenantId = 'admin';
3
+ /**
4
+ * Enable MFA (TOTP and WebAuthn) for the admin tenant with NoPrompt policy.
5
+ * This allows users to optionally set up MFA via the account center.
6
+ */
7
+ const alteration = {
8
+ up: async (pool) => {
9
+ await pool.query(sql `
10
+ update sign_in_experiences
11
+ set mfa = '{"factors":["Totp","WebAuthn","BackupCode"],"policy":"NoPrompt"}'::jsonb
12
+ where tenant_id = ${adminTenantId}
13
+ and id = 'default'
14
+ `);
15
+ },
16
+ down: async (pool) => {
17
+ await pool.query(sql `
18
+ update sign_in_experiences
19
+ set mfa = '{"factors":[],"policy":"UserControlled"}'::jsonb
20
+ where tenant_id = ${adminTenantId}
21
+ and id = 'default'
22
+ `);
23
+ },
24
+ };
25
+ export default alteration;
@@ -0,0 +1,27 @@
1
+ import { sql } from '@silverhand/slonik';
2
+ import { applyTableRls, dropTableRls } from './utils/1704934999-tables.js';
3
+ const alteration = {
4
+ up: async (pool) => {
5
+ await pool.query(sql `
6
+ create table user_geo_locations (
7
+ tenant_id varchar(21) not null
8
+ references tenants (id) on update cascade on delete cascade,
9
+ user_id varchar(12) not null
10
+ references users (id) on update cascade on delete cascade,
11
+ latitude numeric(9,6),
12
+ longitude numeric(9,6),
13
+ updated_at timestamptz not null default now(),
14
+ primary key (tenant_id, user_id),
15
+ check ((latitude is null) = (longitude is null))
16
+ );
17
+ `);
18
+ await applyTableRls(pool, 'user_geo_locations');
19
+ },
20
+ down: async (pool) => {
21
+ await dropTableRls(pool, 'user_geo_locations');
22
+ await pool.query(sql `
23
+ drop table user_geo_locations;
24
+ `);
25
+ },
26
+ };
27
+ export default alteration;
@@ -0,0 +1,28 @@
1
+ import { sql } from '@silverhand/slonik';
2
+ import { applyTableRls, dropTableRls } from './utils/1704934999-tables.js';
3
+ const alteration = {
4
+ up: async (pool) => {
5
+ await pool.query(sql `
6
+ create table user_sign_in_countries (
7
+ tenant_id varchar(21) not null
8
+ references tenants (id) on update cascade on delete cascade,
9
+ user_id varchar(12) not null
10
+ references users (id) on update cascade on delete cascade,
11
+ country varchar(16) not null,
12
+ last_sign_in_at timestamptz not null default(now()),
13
+ primary key (tenant_id, user_id, country)
14
+ );
15
+
16
+ create index user_sign_in_countries__tenant_user_last_sign_in_at
17
+ on user_sign_in_countries (tenant_id, user_id, last_sign_in_at desc);
18
+ `);
19
+ await applyTableRls(pool, 'user_sign_in_countries');
20
+ },
21
+ down: async (pool) => {
22
+ await dropTableRls(pool, 'user_sign_in_countries');
23
+ await pool.query(sql `
24
+ drop table user_sign_in_countries;
25
+ `);
26
+ },
27
+ };
28
+ export default alteration;
@@ -0,0 +1,15 @@
1
+ import { sql } from '@silverhand/slonik';
2
+ const alteration = {
3
+ up: async (pool) => {
4
+ await pool.query(sql `
5
+ alter table sign_in_experiences
6
+ add column adaptive_mfa jsonb not null default '{}'::jsonb;
7
+ `);
8
+ },
9
+ down: async (pool) => {
10
+ await pool.query(sql `
11
+ alter table sign_in_experiences drop column adaptive_mfa;
12
+ `);
13
+ },
14
+ };
15
+ export default alteration;
@@ -0,0 +1,26 @@
1
+ import { sql } from '@silverhand/slonik';
2
+ const adminTenantId = 'admin';
3
+ /**
4
+ * Enable organization required MFA policy for the admin tenant.
5
+ * This allows tenant admins to require MFA for all tenant members
6
+ * by setting `isMfaRequired: true` on the organization.
7
+ */
8
+ const alteration = {
9
+ up: async (pool) => {
10
+ await pool.query(sql `
11
+ update sign_in_experiences
12
+ set mfa = jsonb_set(mfa, '{organizationRequiredMfaPolicy}', '"Mandatory"')
13
+ where tenant_id = ${adminTenantId}
14
+ and id = 'default'
15
+ `);
16
+ },
17
+ down: async (pool) => {
18
+ await pool.query(sql `
19
+ update sign_in_experiences
20
+ set mfa = mfa - 'organizationRequiredMfaPolicy'
21
+ where tenant_id = ${adminTenantId}
22
+ and id = 'default'
23
+ `);
24
+ },
25
+ };
26
+ export default alteration;
@@ -62,6 +62,8 @@ export * from './sso-connector-idp-initiated-auth-config.js';
62
62
  export * from './sso-connector.js';
63
63
  export * from './subject-token.js';
64
64
  export * from './system.js';
65
+ export * from './user-geo-location.js';
66
+ export * from './user-sign-in-country.js';
65
67
  export * from './user-sso-identity.js';
66
68
  export * from './user.js';
67
69
  export * from './users-role.js';
@@ -63,6 +63,8 @@ export * from './sso-connector-idp-initiated-auth-config.js';
63
63
  export * from './sso-connector.js';
64
64
  export * from './subject-token.js';
65
65
  export * from './system.js';
66
+ export * from './user-geo-location.js';
67
+ export * from './user-sign-in-country.js';
66
68
  export * from './user-sso-identity.js';
67
69
  export * from './user.js';
68
70
  export * from './users-role.js';
@@ -1,4 +1,4 @@
1
- import { Color, Branding, LanguageInfo, SignIn, SignUp, SocialSignIn, ConnectorTargets, CustomContent, CustomUiAssets, PartialPasswordPolicy, Mfa, CaptchaPolicy, SentinelPolicy, EmailBlocklistPolicy, ForgotPasswordMethods, GeneratedSchema } from './../foundations/index.js';
1
+ import { Color, Branding, LanguageInfo, SignIn, SignUp, SocialSignIn, ConnectorTargets, CustomContent, CustomUiAssets, PartialPasswordPolicy, Mfa, AdaptiveMfa, CaptchaPolicy, SentinelPolicy, EmailBlocklistPolicy, ForgotPasswordMethods, PasskeySignIn, GeneratedSchema } from './../foundations/index.js';
2
2
  import { AgreeToTermsPolicy, SignInMode } from './custom-types.js';
3
3
  /**
4
4
  *
@@ -26,6 +26,7 @@ export type CreateSignInExperience = {
26
26
  customUiAssets?: CustomUiAssets | null;
27
27
  passwordPolicy?: PartialPasswordPolicy;
28
28
  mfa?: Mfa;
29
+ adaptiveMfa?: AdaptiveMfa;
29
30
  singleSignOnEnabled?: boolean;
30
31
  supportEmail?: string | null;
31
32
  supportWebsiteUrl?: string | null;
@@ -34,6 +35,7 @@ export type CreateSignInExperience = {
34
35
  sentinelPolicy?: SentinelPolicy;
35
36
  emailBlocklistPolicy?: EmailBlocklistPolicy;
36
37
  forgotPasswordMethods?: ForgotPasswordMethods | null;
38
+ passkeySignIn?: PasskeySignIn;
37
39
  };
38
40
  export type SignInExperience = {
39
41
  tenantId: string;
@@ -56,6 +58,7 @@ export type SignInExperience = {
56
58
  customUiAssets: CustomUiAssets | null;
57
59
  passwordPolicy: PartialPasswordPolicy;
58
60
  mfa: Mfa;
61
+ adaptiveMfa: AdaptiveMfa;
59
62
  singleSignOnEnabled: boolean;
60
63
  supportEmail: string | null;
61
64
  supportWebsiteUrl: string | null;
@@ -64,6 +67,7 @@ export type SignInExperience = {
64
67
  sentinelPolicy: SentinelPolicy;
65
68
  emailBlocklistPolicy: EmailBlocklistPolicy;
66
69
  forgotPasswordMethods: ForgotPasswordMethods | null;
70
+ passkeySignIn: PasskeySignIn;
67
71
  };
68
- export type SignInExperienceKeys = 'tenantId' | 'id' | 'color' | 'branding' | 'hideLogtoBranding' | 'languageInfo' | 'termsOfUseUrl' | 'privacyPolicyUrl' | 'agreeToTermsPolicy' | 'signIn' | 'signUp' | 'socialSignIn' | 'socialSignInConnectorTargets' | 'signInMode' | 'customCss' | 'customContent' | 'customUiAssets' | 'passwordPolicy' | 'mfa' | 'singleSignOnEnabled' | 'supportEmail' | 'supportWebsiteUrl' | 'unknownSessionRedirectUrl' | 'captchaPolicy' | 'sentinelPolicy' | 'emailBlocklistPolicy' | 'forgotPasswordMethods';
72
+ export type SignInExperienceKeys = 'tenantId' | 'id' | 'color' | 'branding' | 'hideLogtoBranding' | 'languageInfo' | 'termsOfUseUrl' | 'privacyPolicyUrl' | 'agreeToTermsPolicy' | 'signIn' | 'signUp' | 'socialSignIn' | 'socialSignInConnectorTargets' | 'signInMode' | 'customCss' | 'customContent' | 'customUiAssets' | 'passwordPolicy' | 'mfa' | 'adaptiveMfa' | 'singleSignOnEnabled' | 'supportEmail' | 'supportWebsiteUrl' | 'unknownSessionRedirectUrl' | 'captchaPolicy' | 'sentinelPolicy' | 'emailBlocklistPolicy' | 'forgotPasswordMethods' | 'passkeySignIn';
69
73
  export declare const SignInExperiences: GeneratedSchema<SignInExperienceKeys, CreateSignInExperience, SignInExperience, 'sign_in_experiences', 'sign_in_experience'>;
@@ -1,6 +1,6 @@
1
1
  // THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2
2
  import { z } from 'zod';
3
- import { colorGuard, brandingGuard, languageInfoGuard, signInGuard, signUpGuard, socialSignInGuard, connectorTargetsGuard, customContentGuard, customUiAssetsGuard, partialPasswordPolicyGuard, mfaGuard, captchaPolicyGuard, sentinelPolicyGuard, emailBlocklistPolicyGuard, forgotPasswordMethodsGuard } from './../foundations/index.js';
3
+ import { colorGuard, brandingGuard, languageInfoGuard, signInGuard, signUpGuard, socialSignInGuard, connectorTargetsGuard, customContentGuard, customUiAssetsGuard, partialPasswordPolicyGuard, mfaGuard, adaptiveMfaGuard, captchaPolicyGuard, sentinelPolicyGuard, emailBlocklistPolicyGuard, forgotPasswordMethodsGuard, passkeySignInGuard } from './../foundations/index.js';
4
4
  import { AgreeToTermsPolicy, SignInMode } from './custom-types.js';
5
5
  const createGuard = z.object({
6
6
  tenantId: z.string().max(21).optional(),
@@ -22,6 +22,7 @@ const createGuard = z.object({
22
22
  customUiAssets: customUiAssetsGuard.nullable().optional(),
23
23
  passwordPolicy: partialPasswordPolicyGuard.optional(),
24
24
  mfa: mfaGuard.optional(),
25
+ adaptiveMfa: adaptiveMfaGuard.optional(),
25
26
  singleSignOnEnabled: z.boolean().optional(),
26
27
  supportEmail: z.string().nullable().optional(),
27
28
  supportWebsiteUrl: z.string().nullable().optional(),
@@ -30,6 +31,7 @@ const createGuard = z.object({
30
31
  sentinelPolicy: sentinelPolicyGuard.optional(),
31
32
  emailBlocklistPolicy: emailBlocklistPolicyGuard.optional(),
32
33
  forgotPasswordMethods: forgotPasswordMethodsGuard.nullable().optional(),
34
+ passkeySignIn: passkeySignInGuard.optional(),
33
35
  });
34
36
  const guard = z.object({
35
37
  tenantId: z.string().max(21),
@@ -51,6 +53,7 @@ const guard = z.object({
51
53
  customUiAssets: customUiAssetsGuard.nullable(),
52
54
  passwordPolicy: partialPasswordPolicyGuard,
53
55
  mfa: mfaGuard,
56
+ adaptiveMfa: adaptiveMfaGuard,
54
57
  singleSignOnEnabled: z.boolean(),
55
58
  supportEmail: z.string().nullable(),
56
59
  supportWebsiteUrl: z.string().nullable(),
@@ -59,6 +62,7 @@ const guard = z.object({
59
62
  sentinelPolicy: sentinelPolicyGuard,
60
63
  emailBlocklistPolicy: emailBlocklistPolicyGuard,
61
64
  forgotPasswordMethods: forgotPasswordMethodsGuard.nullable(),
65
+ passkeySignIn: passkeySignInGuard,
62
66
  });
63
67
  export const SignInExperiences = Object.freeze({
64
68
  table: 'sign_in_experiences',
@@ -83,6 +87,7 @@ export const SignInExperiences = Object.freeze({
83
87
  customUiAssets: 'custom_ui_assets',
84
88
  passwordPolicy: 'password_policy',
85
89
  mfa: 'mfa',
90
+ adaptiveMfa: 'adaptive_mfa',
86
91
  singleSignOnEnabled: 'single_sign_on_enabled',
87
92
  supportEmail: 'support_email',
88
93
  supportWebsiteUrl: 'support_website_url',
@@ -91,6 +96,7 @@ export const SignInExperiences = Object.freeze({
91
96
  sentinelPolicy: 'sentinel_policy',
92
97
  emailBlocklistPolicy: 'email_blocklist_policy',
93
98
  forgotPasswordMethods: 'forgot_password_methods',
99
+ passkeySignIn: 'passkey_sign_in',
94
100
  },
95
101
  fieldKeys: [
96
102
  'tenantId',
@@ -112,6 +118,7 @@ export const SignInExperiences = Object.freeze({
112
118
  'customUiAssets',
113
119
  'passwordPolicy',
114
120
  'mfa',
121
+ 'adaptiveMfa',
115
122
  'singleSignOnEnabled',
116
123
  'supportEmail',
117
124
  'supportWebsiteUrl',
@@ -120,6 +127,7 @@ export const SignInExperiences = Object.freeze({
120
127
  'sentinelPolicy',
121
128
  'emailBlocklistPolicy',
122
129
  'forgotPasswordMethods',
130
+ 'passkeySignIn',
123
131
  ],
124
132
  createGuard,
125
133
  guard,
@@ -0,0 +1,24 @@
1
+ import { GeneratedSchema } from './../foundations/index.js';
2
+ /**
3
+ * The last known geo coordinates per user for geo-velocity checks.
4
+ *
5
+ * @remarks This is a type for database creation.
6
+ * @see {@link UserGeoLocation} for the original type.
7
+ */
8
+ export type CreateUserGeoLocation = {
9
+ tenantId?: string;
10
+ userId: string;
11
+ latitude?: number | null;
12
+ longitude?: number | null;
13
+ updatedAt?: number;
14
+ };
15
+ /** The last known geo coordinates per user for geo-velocity checks. */
16
+ export type UserGeoLocation = {
17
+ tenantId: string;
18
+ userId: string;
19
+ latitude: number | null;
20
+ longitude: number | null;
21
+ updatedAt: number;
22
+ };
23
+ export type UserGeoLocationKeys = 'tenantId' | 'userId' | 'latitude' | 'longitude' | 'updatedAt';
24
+ export declare const UserGeoLocations: GeneratedSchema<UserGeoLocationKeys, CreateUserGeoLocation, UserGeoLocation, 'user_geo_locations', 'user_geo_location'>;
@@ -0,0 +1,37 @@
1
+ // THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2
+ import { z } from 'zod';
3
+ const createGuard = z.object({
4
+ tenantId: z.string().max(21).optional(),
5
+ userId: z.string().min(1).max(12),
6
+ latitude: z.number().nullable().optional(),
7
+ longitude: z.number().nullable().optional(),
8
+ updatedAt: z.number().optional(),
9
+ });
10
+ const guard = z.object({
11
+ tenantId: z.string().max(21),
12
+ userId: z.string().min(1).max(12),
13
+ latitude: z.number().nullable(),
14
+ longitude: z.number().nullable(),
15
+ updatedAt: z.number(),
16
+ });
17
+ export const UserGeoLocations = Object.freeze({
18
+ table: 'user_geo_locations',
19
+ tableSingular: 'user_geo_location',
20
+ fields: {
21
+ tenantId: 'tenant_id',
22
+ userId: 'user_id',
23
+ latitude: 'latitude',
24
+ longitude: 'longitude',
25
+ updatedAt: 'updated_at',
26
+ },
27
+ fieldKeys: [
28
+ 'tenantId',
29
+ 'userId',
30
+ 'latitude',
31
+ 'longitude',
32
+ 'updatedAt',
33
+ ],
34
+ createGuard,
35
+ guard,
36
+ updateGuard: guard.partial(),
37
+ });
@@ -0,0 +1,24 @@
1
+ import { GeneratedSchema } from './../foundations/index.js';
2
+ /**
3
+ * Tracks per-user sign-in countries for adaptive MFA rules.
4
+ *
5
+ * @remarks This is a type for database creation.
6
+ * @see {@link UserSignInCountry} for the original type.
7
+ */
8
+ export type CreateUserSignInCountry = {
9
+ tenantId?: string;
10
+ userId: string;
11
+ /** ISO 3166-1 alpha-2 country code (2 chars), stored up to 16 chars for robustness. */
12
+ country: string;
13
+ lastSignInAt?: number;
14
+ };
15
+ /** Tracks per-user sign-in countries for adaptive MFA rules. */
16
+ export type UserSignInCountry = {
17
+ tenantId: string;
18
+ userId: string;
19
+ /** ISO 3166-1 alpha-2 country code (2 chars), stored up to 16 chars for robustness. */
20
+ country: string;
21
+ lastSignInAt: number;
22
+ };
23
+ export type UserSignInCountryKeys = 'tenantId' | 'userId' | 'country' | 'lastSignInAt';
24
+ export declare const UserSignInCountries: GeneratedSchema<UserSignInCountryKeys, CreateUserSignInCountry, UserSignInCountry, 'user_sign_in_countries', 'user_sign_in_country'>;