@logto/schemas 1.8.0 → 1.9.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 (57) hide show
  1. package/alterations/1.9.0-1693554904-add-possword-policy.ts +21 -0
  2. package/alterations/1.9.0-1694399696-add-type-col-to-roles-table.ts +55 -0
  3. package/alterations/1.9.0-1694418765-specify-check-role-type-function-to-be-public-schema.ts +54 -0
  4. package/alterations/1.9.0-1694484927-remove-deprecated-challenge-flag.ts +100 -0
  5. package/alterations/1.9.0-1694487524-sie-mfa.ts +26 -0
  6. package/alterations/1.9.0-1694509714-keep-existing-password-policy.ts +54 -0
  7. package/alterations/1.9.0-1694746763-user-verifications.ts +20 -0
  8. package/alterations-js/1.9.0-1693554904-add-possword-policy.d.ts +4 -0
  9. package/alterations-js/1.9.0-1693554904-add-possword-policy.js +17 -0
  10. package/alterations-js/1.9.0-1694399696-add-type-col-to-roles-table.d.ts +3 -0
  11. package/alterations-js/1.9.0-1694399696-add-type-col-to-roles-table.js +44 -0
  12. package/alterations-js/1.9.0-1694418765-specify-check-role-type-function-to-be-public-schema.d.ts +9 -0
  13. package/alterations-js/1.9.0-1694418765-specify-check-role-type-function-to-be-public-schema.js +42 -0
  14. package/alterations-js/1.9.0-1694484927-remove-deprecated-challenge-flag.d.ts +3 -0
  15. package/alterations-js/1.9.0-1694484927-remove-deprecated-challenge-flag.js +35 -0
  16. package/alterations-js/1.9.0-1694487524-sie-mfa.d.ts +3 -0
  17. package/alterations-js/1.9.0-1694487524-sie-mfa.js +21 -0
  18. package/alterations-js/1.9.0-1694509714-keep-existing-password-policy.d.ts +3 -0
  19. package/alterations-js/1.9.0-1694509714-keep-existing-password-policy.js +42 -0
  20. package/alterations-js/1.9.0-1694746763-user-verifications.d.ts +3 -0
  21. package/alterations-js/1.9.0-1694746763-user-verifications.js +16 -0
  22. package/lib/db-entries/custom-types.d.ts +4 -0
  23. package/lib/db-entries/custom-types.js +5 -0
  24. package/lib/db-entries/role.d.ts +3 -0
  25. package/lib/db-entries/role.js +5 -0
  26. package/lib/db-entries/sign-in-experience.d.ts +5 -1
  27. package/lib/db-entries/sign-in-experience.js +9 -1
  28. package/lib/db-entries/user.d.ts +3 -1
  29. package/lib/db-entries/user.js +5 -1
  30. package/lib/foundations/jsonb-types.d.ts +233 -26
  31. package/lib/foundations/jsonb-types.js +51 -21
  32. package/lib/models/tenants.d.ts +4 -4
  33. package/lib/seeds/cloud-api.d.ts +1 -1
  34. package/lib/seeds/cloud-api.js +2 -0
  35. package/lib/seeds/logto-config.js +0 -7
  36. package/lib/seeds/management-api.d.ts +2 -1
  37. package/lib/seeds/management-api.js +5 -0
  38. package/lib/seeds/sign-in-experience.js +6 -1
  39. package/lib/types/connector.d.ts +4 -4
  40. package/lib/types/hook.d.ts +13 -2
  41. package/lib/types/hook.js +4 -0
  42. package/lib/types/interactions.d.ts +1 -2
  43. package/lib/types/interactions.js +4 -5
  44. package/lib/types/logto-config.d.ts +0 -21
  45. package/lib/types/logto-config.js +0 -8
  46. package/lib/types/role.d.ts +4 -2
  47. package/lib/types/scope.d.ts +6 -6
  48. package/lib/types/system.d.ts +11 -8
  49. package/lib/types/system.js +6 -5
  50. package/lib/types/user.d.ts +195 -16
  51. package/lib/types/user.js +10 -0
  52. package/package.json +6 -6
  53. package/tables/applications_roles.sql +5 -1
  54. package/tables/roles.sql +8 -0
  55. package/tables/sign_in_experiences.sql +2 -0
  56. package/tables/users.sql +1 -0
  57. package/tables/users_roles.sql +5 -1
@@ -0,0 +1,21 @@
1
+ import { sql } from 'slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ /** The alteration script for adding `password_policy` column to the sign-in experience table. */
6
+ const alteration: AlterationScript = {
7
+ up: async (pool) => {
8
+ await pool.query(sql`
9
+ alter table sign_in_experiences
10
+ add column password_policy jsonb not null default '{}';
11
+ `);
12
+ },
13
+ down: async (pool) => {
14
+ await pool.query(sql`
15
+ alter table sign_in_experiences
16
+ drop column password_policy;
17
+ `);
18
+ },
19
+ };
20
+
21
+ export default alteration;
@@ -0,0 +1,55 @@
1
+ import { sql } from 'slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ enum InternalRole {
6
+ Admin = '#internal:admin',
7
+ }
8
+
9
+ const alteration: AlterationScript = {
10
+ up: async (pool) => {
11
+ // Get all m2m role ids.
12
+ const { rows: m2mRoleIds } = await pool.query<{ id: string }>(sql`
13
+ select roles.id as "id" from roles
14
+ left join applications_roles on applications_roles.role_id = roles.id and applications_roles.tenant_id = roles.tenant_id
15
+ left join applications on applications.id = applications_roles.application_id and applications.tenant_id = applications_roles.tenant_id
16
+ where applications.type = 'MachineToMachine' or roles.name = ${InternalRole.Admin} group by roles.id;
17
+ `);
18
+ // Add `type` column to `roles` table, and set `type` to 'MachineToMachine' for all m2m roles.
19
+ await pool.query(sql`
20
+ create type role_type as enum ('User', 'MachineToMachine');
21
+ `);
22
+ await pool.query(sql`alter table roles add column type role_type not null default 'User';`);
23
+ await pool.query(sql`
24
+ update roles set type = 'MachineToMachine' where id in (${sql.join(
25
+ m2mRoleIds.map(({ id }) => id),
26
+ sql`, `
27
+ )});
28
+ `);
29
+ // Add role type check function and constraints for recording user/application-role relations.
30
+ await pool.query(sql`
31
+ create function check_role_type(role_id varchar(21), target_type role_type) returns boolean as
32
+ $$ begin
33
+ return (select type from roles where id = role_id) = target_type;
34
+ end; $$ language plpgsql;
35
+ `);
36
+ await pool.query(sql`
37
+ alter table users_roles add constraint users_roles__role_type
38
+ check (check_role_type(role_id, 'User'));
39
+ `);
40
+ await pool.query(
41
+ sql`alter table applications_roles add constraint applications_roles__role_type check (check_role_type(role_id, 'MachineToMachine'));`
42
+ );
43
+ },
44
+ down: async (pool) => {
45
+ await pool.query(
46
+ sql`alter table applications_roles drop constraint applications_roles__role_type;`
47
+ );
48
+ await pool.query(sql`alter table users_roles drop constraint users_roles__role_type;`);
49
+ await pool.query(sql`drop function check_role_type;`);
50
+ await pool.query(sql`alter table roles drop column type;`);
51
+ await pool.query(sql`drop type role_type;`);
52
+ },
53
+ };
54
+
55
+ export default alteration;
@@ -0,0 +1,54 @@
1
+ import { sql } from 'slonik';
2
+
3
+ import type { AlterationScript } from '../lib/types/alteration.js';
4
+
5
+ /**
6
+ * This alteration is a fix on `check_role_type` function, since this function could be called by
7
+ * cloud (at the time the DB schema is `cloud` and can not find `public` functions/tables).
8
+ *
9
+ * As a result, we need to specify the function to be with `public` schema.
10
+ */
11
+ const alteration: AlterationScript = {
12
+ up: async (pool) => {
13
+ await pool.query(
14
+ sql`alter table applications_roles drop constraint applications_roles__role_type;`
15
+ );
16
+ await pool.query(sql`alter table users_roles drop constraint users_roles__role_type;`);
17
+ await pool.query(sql`drop function check_role_type;`);
18
+ await pool.query(sql`
19
+ create function public.check_role_type(role_id varchar(21), target_type role_type) returns boolean as
20
+ $$ begin
21
+ return (select type from public.roles where id = role_id) = target_type;
22
+ end; $$ language plpgsql;
23
+ `);
24
+ await pool.query(sql`
25
+ alter table users_roles add constraint users_roles__role_type
26
+ check (public.check_role_type(role_id, 'User'));
27
+ `);
28
+ await pool.query(
29
+ sql`alter table applications_roles add constraint applications_roles__role_type check (public.check_role_type(role_id, 'MachineToMachine'));`
30
+ );
31
+ },
32
+ down: async (pool) => {
33
+ await pool.query(
34
+ sql`alter table applications_roles drop constraint applications_roles__role_type;`
35
+ );
36
+ await pool.query(sql`alter table users_roles drop constraint users_roles__role_type;`);
37
+ await pool.query(sql`drop function public.check_role_type;`);
38
+ await pool.query(sql`
39
+ create function check_role_type(role_id varchar(21), target_type role_type) returns boolean as
40
+ $$ begin
41
+ return (select type from roles where id = role_id) = target_type;
42
+ end; $$ language plpgsql;
43
+ `);
44
+ await pool.query(sql`
45
+ alter table users_roles add constraint users_roles__role_type
46
+ check (check_role_type(role_id, 'User'));
47
+ `);
48
+ await pool.query(
49
+ sql`alter table applications_roles add constraint applications_roles__role_type check (check_role_type(role_id, 'MachineToMachine'));`
50
+ );
51
+ },
52
+ };
53
+
54
+ export default alteration;
@@ -0,0 +1,100 @@
1
+ import type { DatabaseTransactionConnection } from 'slonik';
2
+ import { sql } from 'slonik';
3
+
4
+ import type { AlterationScript } from '../lib/types/alteration.js';
5
+
6
+ const adminConsoleConfigKey = 'adminConsole';
7
+
8
+ type OldAdminConsoleData = {
9
+ livePreviewChecked: boolean;
10
+ applicationCreated: boolean;
11
+ signInExperienceCustomized: boolean;
12
+ passwordlessConfigured: boolean;
13
+ furtherReadingsChecked: boolean;
14
+ roleCreated: boolean;
15
+ communityChecked: boolean;
16
+ m2mApplicationCreated: boolean;
17
+ } & Record<string, unknown>;
18
+
19
+ type OldLogtoAdminConsoleConfig = {
20
+ tenantId: string;
21
+ value: OldAdminConsoleData;
22
+ };
23
+
24
+ type NewAdminConsoleData = {
25
+ signInExperienceCustomized: boolean;
26
+ } & Record<string, unknown>;
27
+
28
+ type NewLogtoAdminConsoleConfig = {
29
+ tenantId: string;
30
+ value: NewAdminConsoleData;
31
+ };
32
+
33
+ const alterAdminConsoleData = async (
34
+ logtoConfig: OldLogtoAdminConsoleConfig,
35
+ pool: DatabaseTransactionConnection
36
+ ) => {
37
+ const { tenantId, value: oldAdminConsoleConfig } = logtoConfig;
38
+
39
+ const {
40
+ livePreviewChecked,
41
+ applicationCreated,
42
+ passwordlessConfigured,
43
+ communityChecked,
44
+ furtherReadingsChecked,
45
+ roleCreated,
46
+ m2mApplicationCreated,
47
+ ...others
48
+ } = oldAdminConsoleConfig;
49
+
50
+ const newAdminConsoleData: NewAdminConsoleData = {
51
+ ...others,
52
+ };
53
+
54
+ await pool.query(
55
+ sql`update logto_configs set value = ${JSON.stringify(
56
+ newAdminConsoleData
57
+ )} where tenant_id = ${tenantId} and key = ${adminConsoleConfigKey}`
58
+ );
59
+ };
60
+
61
+ const rollbackAdminConsoleData = async (
62
+ logtoConfig: NewLogtoAdminConsoleConfig,
63
+ pool: DatabaseTransactionConnection
64
+ ) => {
65
+ const { tenantId, value: newAdminConsoleConfig } = logtoConfig;
66
+
67
+ const oldAdminConsoleData: OldAdminConsoleData = {
68
+ ...newAdminConsoleConfig,
69
+ livePreviewChecked: false,
70
+ applicationCreated: false,
71
+ passwordlessConfigured: false,
72
+ communityChecked: false,
73
+ furtherReadingsChecked: false,
74
+ roleCreated: false,
75
+ m2mApplicationCreated: false,
76
+ };
77
+
78
+ await pool.query(
79
+ sql`update logto_configs set value = ${JSON.stringify(
80
+ oldAdminConsoleData
81
+ )} where tenant_id = ${tenantId} and key = ${adminConsoleConfigKey}`
82
+ );
83
+ };
84
+
85
+ const alteration: AlterationScript = {
86
+ up: async (pool) => {
87
+ const rows = await pool.many<OldLogtoAdminConsoleConfig>(
88
+ sql`select * from logto_configs where key = ${adminConsoleConfigKey}`
89
+ );
90
+ await Promise.all(rows.map(async (row) => alterAdminConsoleData(row, pool)));
91
+ },
92
+ down: async (pool) => {
93
+ const rows = await pool.many<NewLogtoAdminConsoleConfig>(
94
+ sql`select * from logto_configs where key = ${adminConsoleConfigKey}`
95
+ );
96
+ await Promise.all(rows.map(async (row) => rollbackAdminConsoleData(row, pool)));
97
+ },
98
+ };
99
+
100
+ export default alteration;
@@ -0,0 +1,26 @@
1
+ import { sql } from '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 if not exists mfa jsonb not null default '{}'::jsonb;
10
+ `);
11
+
12
+ await pool.query(sql`
13
+ update sign_in_experiences
14
+ set mfa = '{"factors":[],"policy":"UserControlled"}'
15
+ where id = 'default';
16
+ `);
17
+ },
18
+ down: async (pool) => {
19
+ await pool.query(sql`
20
+ alter table sign_in_experiences
21
+ drop column mfa;
22
+ `);
23
+ },
24
+ };
25
+
26
+ export default alteration;
@@ -0,0 +1,54 @@
1
+ import { yes } from '@silverhand/essentials';
2
+ import { sql } from 'slonik';
3
+
4
+ import type { AlterationScript } from '../lib/types/alteration.js';
5
+
6
+ // In the alteration testing environment, we do not want to run this alteration
7
+ // script since it alters the existing data which does not match the new policy.
8
+ const isAlterationTesting = yes(process.env.ALTERATION_TEST);
9
+
10
+ /**
11
+ * Note: The legacy password policy does not separate upper and lower cases into
12
+ * different character types. It is not possible to migrate this behavior.
13
+ */
14
+ const legacyPasswordPolicy = {
15
+ length: { min: 8 },
16
+ characterTypes: { min: 2 },
17
+ rejects: {
18
+ pwned: false,
19
+ repetitionAndSequence: false,
20
+ userInfo: false,
21
+ words: [],
22
+ },
23
+ };
24
+
25
+ const alteration: AlterationScript = {
26
+ up: async (pool) => {
27
+ if (isAlterationTesting) {
28
+ console.warn(
29
+ 'Skipping alteration script next-1694509714-keep-existing-password-policy in alteration testing environment.'
30
+ );
31
+ return;
32
+ }
33
+
34
+ await pool.query(sql`
35
+ update sign_in_experiences
36
+ set password_policy = ${sql.jsonb(legacyPasswordPolicy)};
37
+ `);
38
+ },
39
+ down: async (pool) => {
40
+ if (isAlterationTesting) {
41
+ console.warn(
42
+ 'Skipping alteration script next-1694509714-keep-existing-password-policy in alteration testing environment.'
43
+ );
44
+ return;
45
+ }
46
+
47
+ await pool.query(sql`
48
+ update sign_in_experiences
49
+ set password_policy = '{}'::jsonb;
50
+ `);
51
+ },
52
+ };
53
+
54
+ export default alteration;
@@ -0,0 +1,20 @@
1
+ import { sql } from '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 users
9
+ add column if not exists mfa_verifications jsonb not null default '[]'::jsonb;
10
+ `);
11
+ },
12
+ down: async (pool) => {
13
+ await pool.query(sql`
14
+ alter table users
15
+ drop column mfa_verifications;
16
+ `);
17
+ },
18
+ };
19
+
20
+ export default alteration;
@@ -0,0 +1,4 @@
1
+ import type { AlterationScript } from '../lib/types/alteration.js';
2
+ /** The alteration script for adding `password_policy` column to the sign-in experience table. */
3
+ declare const alteration: AlterationScript;
4
+ export default alteration;
@@ -0,0 +1,17 @@
1
+ import { sql } from 'slonik';
2
+ /** The alteration script for adding `password_policy` column to the sign-in experience table. */
3
+ const alteration = {
4
+ up: async (pool) => {
5
+ await pool.query(sql `
6
+ alter table sign_in_experiences
7
+ add column password_policy jsonb not null default '{}';
8
+ `);
9
+ },
10
+ down: async (pool) => {
11
+ await pool.query(sql `
12
+ alter table sign_in_experiences
13
+ drop column password_policy;
14
+ `);
15
+ },
16
+ };
17
+ export default alteration;
@@ -0,0 +1,3 @@
1
+ import type { AlterationScript } from '../lib/types/alteration.js';
2
+ declare const alteration: AlterationScript;
3
+ export default alteration;
@@ -0,0 +1,44 @@
1
+ import { sql } from 'slonik';
2
+ var InternalRole;
3
+ (function (InternalRole) {
4
+ InternalRole["Admin"] = "#internal:admin";
5
+ })(InternalRole || (InternalRole = {}));
6
+ const alteration = {
7
+ up: async (pool) => {
8
+ // Get all m2m role ids.
9
+ const { rows: m2mRoleIds } = await pool.query(sql `
10
+ select roles.id as "id" from roles
11
+ left join applications_roles on applications_roles.role_id = roles.id and applications_roles.tenant_id = roles.tenant_id
12
+ left join applications on applications.id = applications_roles.application_id and applications.tenant_id = applications_roles.tenant_id
13
+ where applications.type = 'MachineToMachine' or roles.name = ${InternalRole.Admin} group by roles.id;
14
+ `);
15
+ // Add `type` column to `roles` table, and set `type` to 'MachineToMachine' for all m2m roles.
16
+ await pool.query(sql `
17
+ create type role_type as enum ('User', 'MachineToMachine');
18
+ `);
19
+ await pool.query(sql `alter table roles add column type role_type not null default 'User';`);
20
+ await pool.query(sql `
21
+ update roles set type = 'MachineToMachine' where id in (${sql.join(m2mRoleIds.map(({ id }) => id), sql `, `)});
22
+ `);
23
+ // Add role type check function and constraints for recording user/application-role relations.
24
+ await pool.query(sql `
25
+ create function check_role_type(role_id varchar(21), target_type role_type) returns boolean as
26
+ $$ begin
27
+ return (select type from roles where id = role_id) = target_type;
28
+ end; $$ language plpgsql;
29
+ `);
30
+ await pool.query(sql `
31
+ alter table users_roles add constraint users_roles__role_type
32
+ check (check_role_type(role_id, 'User'));
33
+ `);
34
+ await pool.query(sql `alter table applications_roles add constraint applications_roles__role_type check (check_role_type(role_id, 'MachineToMachine'));`);
35
+ },
36
+ down: async (pool) => {
37
+ await pool.query(sql `alter table applications_roles drop constraint applications_roles__role_type;`);
38
+ await pool.query(sql `alter table users_roles drop constraint users_roles__role_type;`);
39
+ await pool.query(sql `drop function check_role_type;`);
40
+ await pool.query(sql `alter table roles drop column type;`);
41
+ await pool.query(sql `drop type role_type;`);
42
+ },
43
+ };
44
+ export default alteration;
@@ -0,0 +1,9 @@
1
+ import type { AlterationScript } from '../lib/types/alteration.js';
2
+ /**
3
+ * This alteration is a fix on `check_role_type` function, since this function could be called by
4
+ * cloud (at the time the DB schema is `cloud` and can not find `public` functions/tables).
5
+ *
6
+ * As a result, we need to specify the function to be with `public` schema.
7
+ */
8
+ declare const alteration: AlterationScript;
9
+ export default alteration;
@@ -0,0 +1,42 @@
1
+ import { sql } from 'slonik';
2
+ /**
3
+ * This alteration is a fix on `check_role_type` function, since this function could be called by
4
+ * cloud (at the time the DB schema is `cloud` and can not find `public` functions/tables).
5
+ *
6
+ * As a result, we need to specify the function to be with `public` schema.
7
+ */
8
+ const alteration = {
9
+ up: async (pool) => {
10
+ await pool.query(sql `alter table applications_roles drop constraint applications_roles__role_type;`);
11
+ await pool.query(sql `alter table users_roles drop constraint users_roles__role_type;`);
12
+ await pool.query(sql `drop function check_role_type;`);
13
+ await pool.query(sql `
14
+ create function public.check_role_type(role_id varchar(21), target_type role_type) returns boolean as
15
+ $$ begin
16
+ return (select type from public.roles where id = role_id) = target_type;
17
+ end; $$ language plpgsql;
18
+ `);
19
+ await pool.query(sql `
20
+ alter table users_roles add constraint users_roles__role_type
21
+ check (public.check_role_type(role_id, 'User'));
22
+ `);
23
+ await pool.query(sql `alter table applications_roles add constraint applications_roles__role_type check (public.check_role_type(role_id, 'MachineToMachine'));`);
24
+ },
25
+ down: async (pool) => {
26
+ await pool.query(sql `alter table applications_roles drop constraint applications_roles__role_type;`);
27
+ await pool.query(sql `alter table users_roles drop constraint users_roles__role_type;`);
28
+ await pool.query(sql `drop function public.check_role_type;`);
29
+ await pool.query(sql `
30
+ create function check_role_type(role_id varchar(21), target_type role_type) returns boolean as
31
+ $$ begin
32
+ return (select type from roles where id = role_id) = target_type;
33
+ end; $$ language plpgsql;
34
+ `);
35
+ await pool.query(sql `
36
+ alter table users_roles add constraint users_roles__role_type
37
+ check (check_role_type(role_id, 'User'));
38
+ `);
39
+ await pool.query(sql `alter table applications_roles add constraint applications_roles__role_type check (check_role_type(role_id, 'MachineToMachine'));`);
40
+ },
41
+ };
42
+ export default alteration;
@@ -0,0 +1,3 @@
1
+ import type { AlterationScript } from '../lib/types/alteration.js';
2
+ declare const alteration: AlterationScript;
3
+ export default alteration;
@@ -0,0 +1,35 @@
1
+ import { sql } from 'slonik';
2
+ const adminConsoleConfigKey = 'adminConsole';
3
+ const alterAdminConsoleData = async (logtoConfig, pool) => {
4
+ const { tenantId, value: oldAdminConsoleConfig } = logtoConfig;
5
+ const { livePreviewChecked, applicationCreated, passwordlessConfigured, communityChecked, furtherReadingsChecked, roleCreated, m2mApplicationCreated, ...others } = oldAdminConsoleConfig;
6
+ const newAdminConsoleData = {
7
+ ...others,
8
+ };
9
+ await pool.query(sql `update logto_configs set value = ${JSON.stringify(newAdminConsoleData)} where tenant_id = ${tenantId} and key = ${adminConsoleConfigKey}`);
10
+ };
11
+ const rollbackAdminConsoleData = async (logtoConfig, pool) => {
12
+ const { tenantId, value: newAdminConsoleConfig } = logtoConfig;
13
+ const oldAdminConsoleData = {
14
+ ...newAdminConsoleConfig,
15
+ livePreviewChecked: false,
16
+ applicationCreated: false,
17
+ passwordlessConfigured: false,
18
+ communityChecked: false,
19
+ furtherReadingsChecked: false,
20
+ roleCreated: false,
21
+ m2mApplicationCreated: false,
22
+ };
23
+ await pool.query(sql `update logto_configs set value = ${JSON.stringify(oldAdminConsoleData)} where tenant_id = ${tenantId} and key = ${adminConsoleConfigKey}`);
24
+ };
25
+ const alteration = {
26
+ up: async (pool) => {
27
+ const rows = await pool.many(sql `select * from logto_configs where key = ${adminConsoleConfigKey}`);
28
+ await Promise.all(rows.map(async (row) => alterAdminConsoleData(row, pool)));
29
+ },
30
+ down: async (pool) => {
31
+ const rows = await pool.many(sql `select * from logto_configs where key = ${adminConsoleConfigKey}`);
32
+ await Promise.all(rows.map(async (row) => rollbackAdminConsoleData(row, pool)));
33
+ },
34
+ };
35
+ export default alteration;
@@ -0,0 +1,3 @@
1
+ import type { AlterationScript } from '../lib/types/alteration.js';
2
+ declare const alteration: AlterationScript;
3
+ export default alteration;
@@ -0,0 +1,21 @@
1
+ import { sql } from 'slonik';
2
+ const alteration = {
3
+ up: async (pool) => {
4
+ await pool.query(sql `
5
+ alter table sign_in_experiences
6
+ add column if not exists mfa jsonb not null default '{}'::jsonb;
7
+ `);
8
+ await pool.query(sql `
9
+ update sign_in_experiences
10
+ set mfa = '{"factors":[],"policy":"UserControlled"}'
11
+ where id = 'default';
12
+ `);
13
+ },
14
+ down: async (pool) => {
15
+ await pool.query(sql `
16
+ alter table sign_in_experiences
17
+ drop column mfa;
18
+ `);
19
+ },
20
+ };
21
+ export default alteration;
@@ -0,0 +1,3 @@
1
+ import type { AlterationScript } from '../lib/types/alteration.js';
2
+ declare const alteration: AlterationScript;
3
+ export default alteration;
@@ -0,0 +1,42 @@
1
+ import { yes } from '@silverhand/essentials';
2
+ import { sql } from 'slonik';
3
+ // In the alteration testing environment, we do not want to run this alteration
4
+ // script since it alters the existing data which does not match the new policy.
5
+ const isAlterationTesting = yes(process.env.ALTERATION_TEST);
6
+ /**
7
+ * Note: The legacy password policy does not separate upper and lower cases into
8
+ * different character types. It is not possible to migrate this behavior.
9
+ */
10
+ const legacyPasswordPolicy = {
11
+ length: { min: 8 },
12
+ characterTypes: { min: 2 },
13
+ rejects: {
14
+ pwned: false,
15
+ repetitionAndSequence: false,
16
+ userInfo: false,
17
+ words: [],
18
+ },
19
+ };
20
+ const alteration = {
21
+ up: async (pool) => {
22
+ if (isAlterationTesting) {
23
+ console.warn('Skipping alteration script next-1694509714-keep-existing-password-policy in alteration testing environment.');
24
+ return;
25
+ }
26
+ await pool.query(sql `
27
+ update sign_in_experiences
28
+ set password_policy = ${sql.jsonb(legacyPasswordPolicy)};
29
+ `);
30
+ },
31
+ down: async (pool) => {
32
+ if (isAlterationTesting) {
33
+ console.warn('Skipping alteration script next-1694509714-keep-existing-password-policy in alteration testing environment.');
34
+ return;
35
+ }
36
+ await pool.query(sql `
37
+ update sign_in_experiences
38
+ set password_policy = '{}'::jsonb;
39
+ `);
40
+ },
41
+ };
42
+ export default alteration;
@@ -0,0 +1,3 @@
1
+ import type { AlterationScript } from '../lib/types/alteration.js';
2
+ declare const alteration: AlterationScript;
3
+ export default alteration;
@@ -0,0 +1,16 @@
1
+ import { sql } from 'slonik';
2
+ const alteration = {
3
+ up: async (pool) => {
4
+ await pool.query(sql `
5
+ alter table users
6
+ add column if not exists mfa_verifications jsonb not null default '[]'::jsonb;
7
+ `);
8
+ },
9
+ down: async (pool) => {
10
+ await pool.query(sql `
11
+ alter table users
12
+ drop column mfa_verifications;
13
+ `);
14
+ },
15
+ };
16
+ export default alteration;
@@ -4,6 +4,10 @@ export declare enum ApplicationType {
4
4
  Traditional = "Traditional",
5
5
  MachineToMachine = "MachineToMachine"
6
6
  }
7
+ export declare enum RoleType {
8
+ User = "User",
9
+ MachineToMachine = "MachineToMachine"
10
+ }
7
11
  export declare enum SignInMode {
8
12
  SignIn = "SignIn",
9
13
  Register = "Register",
@@ -6,6 +6,11 @@ export var ApplicationType;
6
6
  ApplicationType["Traditional"] = "Traditional";
7
7
  ApplicationType["MachineToMachine"] = "MachineToMachine";
8
8
  })(ApplicationType || (ApplicationType = {}));
9
+ export var RoleType;
10
+ (function (RoleType) {
11
+ RoleType["User"] = "User";
12
+ RoleType["MachineToMachine"] = "MachineToMachine";
13
+ })(RoleType || (RoleType = {}));
9
14
  export var SignInMode;
10
15
  (function (SignInMode) {
11
16
  SignInMode["SignIn"] = "SignIn";
@@ -1,14 +1,17 @@
1
1
  import { GeneratedSchema } from './../foundations/index.js';
2
+ import { RoleType } from './custom-types.js';
2
3
  export type CreateRole = {
3
4
  tenantId?: string;
4
5
  id: string;
5
6
  name: string;
6
7
  description: string;
8
+ type?: RoleType;
7
9
  };
8
10
  export type Role = {
9
11
  tenantId: string;
10
12
  id: string;
11
13
  name: string;
12
14
  description: string;
15
+ type: RoleType;
13
16
  };
14
17
  export declare const Roles: GeneratedSchema<CreateRole, Role>;