@logto/schemas 1.2.3 → 1.3.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 (37) hide show
  1. package/alterations/1.3.0-1683292832-update-hooks.ts +105 -0
  2. package/alterations-js/1.3.0-1683292832-update-hooks.d.ts +3 -0
  3. package/alterations-js/1.3.0-1683292832-update-hooks.js +73 -0
  4. package/lib/db-entries/application.js +3 -3
  5. package/lib/db-entries/applications-role.js +3 -3
  6. package/lib/db-entries/connector.js +2 -2
  7. package/lib/db-entries/custom-phrase.js +2 -2
  8. package/lib/db-entries/hook.d.ts +11 -3
  9. package/lib/db-entries/hook.js +20 -4
  10. package/lib/db-entries/log.js +2 -2
  11. package/lib/db-entries/logto-config.js +1 -1
  12. package/lib/db-entries/oidc-model-instance.js +2 -2
  13. package/lib/db-entries/passcode.js +3 -3
  14. package/lib/db-entries/resource.js +3 -3
  15. package/lib/db-entries/role.js +3 -3
  16. package/lib/db-entries/roles-scope.js +3 -3
  17. package/lib/db-entries/scope.js +4 -4
  18. package/lib/db-entries/service-log.js +2 -2
  19. package/lib/db-entries/sign-in-experience.js +1 -1
  20. package/lib/db-entries/system.js +1 -1
  21. package/lib/db-entries/user.js +1 -1
  22. package/lib/db-entries/users-role.js +3 -3
  23. package/lib/db-entries/verification-status.js +2 -2
  24. package/lib/foundations/jsonb-types.d.ts +19 -8
  25. package/lib/foundations/jsonb-types.js +11 -0
  26. package/lib/types/connector.d.ts +2984 -8
  27. package/lib/types/connector.js +22 -0
  28. package/lib/types/dashboard.d.ts +116 -0
  29. package/lib/types/dashboard.js +18 -0
  30. package/lib/types/index.d.ts +1 -0
  31. package/lib/types/index.js +1 -0
  32. package/lib/types/scope.d.ts +40 -4
  33. package/lib/types/scope.js +4 -1
  34. package/lib/types/user.d.ts +129 -5
  35. package/lib/types/user.js +6 -0
  36. package/package.json +1 -1
  37. package/tables/hooks.sql +13 -11
@@ -0,0 +1,105 @@
1
+ import { generateStandardId } from '@logto/shared';
2
+ import { sql } from 'slonik';
3
+
4
+ import type { AlterationScript } from '../lib/types/alteration.js';
5
+
6
+ enum HookEvent {
7
+ PostRegister = 'PostRegister',
8
+ PostSignIn = 'PostSignIn',
9
+ PostResetPassword = 'PostResetPassword',
10
+ }
11
+
12
+ type HookConfig = {
13
+ url: string;
14
+ headers?: Record<string, string>;
15
+ retries?: number;
16
+ };
17
+
18
+ type Hook = {
19
+ tenantId: string;
20
+ id: string;
21
+ name: string;
22
+ event: HookEvent | null;
23
+ events: HookEvent[];
24
+ config: HookConfig;
25
+ signingKey: string;
26
+ enabled: boolean;
27
+ createdAt: number;
28
+ };
29
+
30
+ const alteration: AlterationScript = {
31
+ up: async (pool) => {
32
+ await pool.query(sql`
33
+ alter table hooks
34
+ add column name varchar(256) not null default '',
35
+ add column events jsonb not null default '[]'::jsonb,
36
+ add column signing_key varchar(64) not null default '',
37
+ add column enabled boolean not null default true,
38
+ alter column event drop not null;
39
+ drop index hooks__event;
40
+ `);
41
+ },
42
+ down: async (pool) => {
43
+ await pool.query(sql`
44
+ delete from hooks where enabled = false;
45
+ `);
46
+
47
+ const { rows: hooks } = await pool.query<Hook>(sql`
48
+ select * from hooks;
49
+ `);
50
+
51
+ /* eslint-disable no-await-in-loop */
52
+ for (const { id, tenantId, events, config } of hooks) {
53
+ const { retries, ...rest } = config;
54
+
55
+ const updatedConfig = {
56
+ ...rest,
57
+ retries: retries ?? 3,
58
+ };
59
+
60
+ if (events.length === 0) {
61
+ await pool.query(sql`
62
+ update hooks
63
+ set config = ${JSON.stringify(updatedConfig)}
64
+ where id = ${id} and tenant_id = ${tenantId};
65
+ `);
66
+
67
+ continue;
68
+ }
69
+
70
+ for (const [index, event] of events.entries()) {
71
+ if (index === 0) {
72
+ await pool.query(sql`
73
+ update hooks
74
+ set event = ${event},
75
+ config = ${JSON.stringify(updatedConfig)}
76
+ where id = ${id} and tenant_id = ${tenantId};
77
+ `);
78
+
79
+ continue;
80
+ }
81
+
82
+ // Create new hook when there are multiple events
83
+ const hookId = generateStandardId();
84
+
85
+ await pool.query(sql`
86
+ insert into hooks (id, tenant_id, event, config)
87
+ values (${hookId}, ${tenantId}, ${event}, ${JSON.stringify(updatedConfig)});
88
+ `);
89
+ }
90
+ }
91
+ /* eslint-enable no-await-in-loop */
92
+
93
+ await pool.query(sql`
94
+ alter table hooks
95
+ alter column event set not null,
96
+ drop column name,
97
+ drop column events,
98
+ drop column signing_key,
99
+ drop column enabled;
100
+ create index hooks__event on hooks (tenant_id, event);
101
+ `);
102
+ },
103
+ };
104
+
105
+ 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,73 @@
1
+ import { generateStandardId } from '@logto/shared';
2
+ import { sql } from 'slonik';
3
+ var HookEvent;
4
+ (function (HookEvent) {
5
+ HookEvent["PostRegister"] = "PostRegister";
6
+ HookEvent["PostSignIn"] = "PostSignIn";
7
+ HookEvent["PostResetPassword"] = "PostResetPassword";
8
+ })(HookEvent || (HookEvent = {}));
9
+ const alteration = {
10
+ up: async (pool) => {
11
+ await pool.query(sql `
12
+ alter table hooks
13
+ add column name varchar(256) not null default '',
14
+ add column events jsonb not null default '[]'::jsonb,
15
+ add column signing_key varchar(64) not null default '',
16
+ add column enabled boolean not null default true,
17
+ alter column event drop not null;
18
+ drop index hooks__event;
19
+ `);
20
+ },
21
+ down: async (pool) => {
22
+ await pool.query(sql `
23
+ delete from hooks where enabled = false;
24
+ `);
25
+ const { rows: hooks } = await pool.query(sql `
26
+ select * from hooks;
27
+ `);
28
+ /* eslint-disable no-await-in-loop */
29
+ for (const { id, tenantId, events, config } of hooks) {
30
+ const { retries, ...rest } = config;
31
+ const updatedConfig = {
32
+ ...rest,
33
+ retries: retries ?? 3,
34
+ };
35
+ if (events.length === 0) {
36
+ await pool.query(sql `
37
+ update hooks
38
+ set config = ${JSON.stringify(updatedConfig)}
39
+ where id = ${id} and tenant_id = ${tenantId};
40
+ `);
41
+ continue;
42
+ }
43
+ for (const [index, event] of events.entries()) {
44
+ if (index === 0) {
45
+ await pool.query(sql `
46
+ update hooks
47
+ set event = ${event},
48
+ config = ${JSON.stringify(updatedConfig)}
49
+ where id = ${id} and tenant_id = ${tenantId};
50
+ `);
51
+ continue;
52
+ }
53
+ // Create new hook when there are multiple events
54
+ const hookId = generateStandardId();
55
+ await pool.query(sql `
56
+ insert into hooks (id, tenant_id, event, config)
57
+ values (${hookId}, ${tenantId}, ${event}, ${JSON.stringify(updatedConfig)});
58
+ `);
59
+ }
60
+ }
61
+ /* eslint-enable no-await-in-loop */
62
+ await pool.query(sql `
63
+ alter table hooks
64
+ alter column event set not null,
65
+ drop column name,
66
+ drop column events,
67
+ drop column signing_key,
68
+ drop column enabled;
69
+ create index hooks__event on hooks (tenant_id, event);
70
+ `);
71
+ },
72
+ };
73
+ export default alteration;
@@ -4,9 +4,9 @@ import { oidcClientMetadataGuard, customClientMetadataGuard } from './../foundat
4
4
  import { ApplicationType } from './custom-types.js';
5
5
  const createGuard = z.object({
6
6
  tenantId: z.string().max(21).optional(),
7
- id: z.string().max(21),
8
- name: z.string().max(256),
9
- secret: z.string().max(64),
7
+ id: z.string().min(1).max(21),
8
+ name: z.string().min(1).max(256),
9
+ secret: z.string().min(1).max(64),
10
10
  description: z.string().nullable().optional(),
11
11
  type: z.nativeEnum(ApplicationType),
12
12
  oidcClientMetadata: oidcClientMetadataGuard,
@@ -2,9 +2,9 @@
2
2
  import { z } from 'zod';
3
3
  const createGuard = z.object({
4
4
  tenantId: z.string().max(21).optional(),
5
- id: z.string().max(21),
6
- applicationId: z.string().max(21),
7
- roleId: z.string().max(21),
5
+ id: z.string().min(1).max(21),
6
+ applicationId: z.string().min(1).max(21),
7
+ roleId: z.string().min(1).max(21),
8
8
  });
9
9
  const guard = z.object({
10
10
  tenantId: z.string().max(21),
@@ -3,9 +3,9 @@ import { z } from 'zod';
3
3
  import { jsonObjectGuard, configurableConnectorMetadataGuard } from './../foundations/index.js';
4
4
  const createGuard = z.object({
5
5
  tenantId: z.string().max(21).optional(),
6
- id: z.string().max(128),
6
+ id: z.string().min(1).max(128),
7
7
  syncProfile: z.boolean().optional(),
8
- connectorId: z.string().max(128),
8
+ connectorId: z.string().min(1).max(128),
9
9
  config: jsonObjectGuard.optional(),
10
10
  metadata: configurableConnectorMetadataGuard.optional(),
11
11
  createdAt: z.number().optional(),
@@ -3,8 +3,8 @@ import { z } from 'zod';
3
3
  import { translationGuard } from './../foundations/index.js';
4
4
  const createGuard = z.object({
5
5
  tenantId: z.string().max(21).optional(),
6
- id: z.string().max(21),
7
- languageTag: z.string().max(16),
6
+ id: z.string().min(1).max(21),
7
+ languageTag: z.string().min(1).max(16),
8
8
  translation: translationGuard,
9
9
  });
10
10
  const guard = z.object({
@@ -1,16 +1,24 @@
1
- import { HookEvent, HookConfig, GeneratedSchema } from './../foundations/index.js';
1
+ import { HookEvent, HookEvents, HookConfig, GeneratedSchema } from './../foundations/index.js';
2
2
  export type CreateHook = {
3
3
  tenantId?: string;
4
4
  id: string;
5
- event: HookEvent;
5
+ name?: string;
6
+ event?: HookEvent | null;
7
+ events?: HookEvents;
6
8
  config: HookConfig;
9
+ signingKey?: string;
10
+ enabled?: boolean;
7
11
  createdAt?: number;
8
12
  };
9
13
  export type Hook = {
10
14
  tenantId: string;
11
15
  id: string;
12
- event: HookEvent;
16
+ name: string;
17
+ event: HookEvent | null;
18
+ events: HookEvents;
13
19
  config: HookConfig;
20
+ signingKey: string;
21
+ enabled: boolean;
14
22
  createdAt: number;
15
23
  };
16
24
  export declare const Hooks: GeneratedSchema<CreateHook, Hook>;
@@ -1,18 +1,26 @@
1
1
  // THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2
2
  import { z } from 'zod';
3
- import { hookEventGuard, hookConfigGuard } from './../foundations/index.js';
3
+ import { hookEventGuard, hookEventsGuard, hookConfigGuard } from './../foundations/index.js';
4
4
  const createGuard = z.object({
5
5
  tenantId: z.string().max(21).optional(),
6
- id: z.string().max(21),
7
- event: hookEventGuard,
6
+ id: z.string().min(1).max(21),
7
+ name: z.string().max(256).optional(),
8
+ event: hookEventGuard.nullable().optional(),
9
+ events: hookEventsGuard.optional(),
8
10
  config: hookConfigGuard,
11
+ signingKey: z.string().max(64).optional(),
12
+ enabled: z.boolean().optional(),
9
13
  createdAt: z.number().optional(),
10
14
  });
11
15
  const guard = z.object({
12
16
  tenantId: z.string().max(21),
13
17
  id: z.string().max(21),
14
- event: hookEventGuard,
18
+ name: z.string().max(256),
19
+ event: hookEventGuard.nullable(),
20
+ events: hookEventsGuard,
15
21
  config: hookConfigGuard,
22
+ signingKey: z.string().max(64),
23
+ enabled: z.boolean(),
16
24
  createdAt: z.number(),
17
25
  });
18
26
  export const Hooks = Object.freeze({
@@ -21,15 +29,23 @@ export const Hooks = Object.freeze({
21
29
  fields: {
22
30
  tenantId: 'tenant_id',
23
31
  id: 'id',
32
+ name: 'name',
24
33
  event: 'event',
34
+ events: 'events',
25
35
  config: 'config',
36
+ signingKey: 'signing_key',
37
+ enabled: 'enabled',
26
38
  createdAt: 'created_at',
27
39
  },
28
40
  fieldKeys: [
29
41
  'tenantId',
30
42
  'id',
43
+ 'name',
31
44
  'event',
45
+ 'events',
32
46
  'config',
47
+ 'signingKey',
48
+ 'enabled',
33
49
  'createdAt',
34
50
  ],
35
51
  createGuard,
@@ -3,8 +3,8 @@ import { z } from 'zod';
3
3
  import { logContextPayloadGuard } from './../foundations/index.js';
4
4
  const createGuard = z.object({
5
5
  tenantId: z.string().max(21).optional(),
6
- id: z.string().max(21),
7
- key: z.string().max(128),
6
+ id: z.string().min(1).max(21),
7
+ key: z.string().min(1).max(128),
8
8
  payload: logContextPayloadGuard.optional(),
9
9
  createdAt: z.number().optional(),
10
10
  });
@@ -3,7 +3,7 @@ import { z } from 'zod';
3
3
  import { jsonObjectGuard } from './../foundations/index.js';
4
4
  const createGuard = z.object({
5
5
  tenantId: z.string().max(21).optional(),
6
- key: z.string().max(256),
6
+ key: z.string().min(1).max(256),
7
7
  value: jsonObjectGuard.optional(),
8
8
  });
9
9
  const guard = z.object({
@@ -3,8 +3,8 @@ import { z } from 'zod';
3
3
  import { oidcModelInstancePayloadGuard } from './../foundations/index.js';
4
4
  const createGuard = z.object({
5
5
  tenantId: z.string().max(21).optional(),
6
- modelName: z.string().max(64),
7
- id: z.string().max(128),
6
+ modelName: z.string().min(1).max(64),
7
+ id: z.string().min(1).max(128),
8
8
  payload: oidcModelInstancePayloadGuard,
9
9
  expiresAt: z.number(),
10
10
  consumedAt: z.number().nullable().optional(),
@@ -2,12 +2,12 @@
2
2
  import { z } from 'zod';
3
3
  const createGuard = z.object({
4
4
  tenantId: z.string().max(21).optional(),
5
- id: z.string().max(21),
5
+ id: z.string().min(1).max(21),
6
6
  interactionJti: z.string().max(128).nullable().optional(),
7
7
  phone: z.string().max(32).nullable().optional(),
8
8
  email: z.string().max(128).nullable().optional(),
9
- type: z.string().max(32),
10
- code: z.string().max(6),
9
+ type: z.string().min(1).max(32),
10
+ code: z.string().min(1).max(6),
11
11
  consumed: z.boolean().optional(),
12
12
  tryCount: z.number().optional(),
13
13
  createdAt: z.number().optional(),
@@ -2,9 +2,9 @@
2
2
  import { z } from 'zod';
3
3
  const createGuard = z.object({
4
4
  tenantId: z.string().max(21).optional(),
5
- id: z.string().max(21),
6
- name: z.string(),
7
- indicator: z.string(),
5
+ id: z.string().min(1).max(21),
6
+ name: z.string().min(1),
7
+ indicator: z.string().min(1),
8
8
  accessTokenTtl: z.number().optional(),
9
9
  });
10
10
  const guard = z.object({
@@ -2,9 +2,9 @@
2
2
  import { z } from 'zod';
3
3
  const createGuard = z.object({
4
4
  tenantId: z.string().max(21).optional(),
5
- id: z.string().max(21),
6
- name: z.string().max(128),
7
- description: z.string().max(128),
5
+ id: z.string().min(1).max(21),
6
+ name: z.string().min(1).max(128),
7
+ description: z.string().min(1).max(128),
8
8
  });
9
9
  const guard = z.object({
10
10
  tenantId: z.string().max(21),
@@ -2,9 +2,9 @@
2
2
  import { z } from 'zod';
3
3
  const createGuard = z.object({
4
4
  tenantId: z.string().max(21).optional(),
5
- id: z.string().max(21),
6
- roleId: z.string().max(21),
7
- scopeId: z.string().max(21),
5
+ id: z.string().min(1).max(21),
6
+ roleId: z.string().min(1).max(21),
7
+ scopeId: z.string().min(1).max(21),
8
8
  });
9
9
  const guard = z.object({
10
10
  tenantId: z.string().max(21),
@@ -2,10 +2,10 @@
2
2
  import { z } from 'zod';
3
3
  const createGuard = z.object({
4
4
  tenantId: z.string().max(21).optional(),
5
- id: z.string().max(21),
6
- resourceId: z.string().max(21),
7
- name: z.string().max(256),
8
- description: z.string(),
5
+ id: z.string().min(1).max(21),
6
+ resourceId: z.string().min(1).max(21),
7
+ name: z.string().min(1).max(256),
8
+ description: z.string().min(1),
9
9
  createdAt: z.number().optional(),
10
10
  });
11
11
  const guard = z.object({
@@ -2,9 +2,9 @@
2
2
  import { z } from 'zod';
3
3
  import { jsonObjectGuard } from './../foundations/index.js';
4
4
  const createGuard = z.object({
5
- id: z.string().max(21),
5
+ id: z.string().min(1).max(21),
6
6
  tenantId: z.string().max(21).optional(),
7
- type: z.string().max(64),
7
+ type: z.string().min(1).max(64),
8
8
  payload: jsonObjectGuard.optional(),
9
9
  createdAt: z.number().optional(),
10
10
  });
@@ -4,7 +4,7 @@ import { colorGuard, brandingGuard, languageInfoGuard, signInGuard, signUpGuard,
4
4
  import { SignInMode } from './custom-types.js';
5
5
  const createGuard = z.object({
6
6
  tenantId: z.string().max(21).optional(),
7
- id: z.string().max(21),
7
+ id: z.string().min(1).max(21),
8
8
  color: colorGuard,
9
9
  branding: brandingGuard,
10
10
  languageInfo: languageInfoGuard,
@@ -2,7 +2,7 @@
2
2
  import { z } from 'zod';
3
3
  import { jsonObjectGuard } from './../foundations/index.js';
4
4
  const createGuard = z.object({
5
- key: z.string().max(256),
5
+ key: z.string().min(1).max(256),
6
6
  value: jsonObjectGuard.optional(),
7
7
  });
8
8
  const guard = z.object({
@@ -4,7 +4,7 @@ import { identitiesGuard, jsonObjectGuard } from './../foundations/index.js';
4
4
  import { UsersPasswordEncryptionMethod } from './custom-types.js';
5
5
  const createGuard = z.object({
6
6
  tenantId: z.string().max(21).optional(),
7
- id: z.string().max(12),
7
+ id: z.string().min(1).max(12),
8
8
  username: z.string().max(128).nullable().optional(),
9
9
  primaryEmail: z.string().max(128).nullable().optional(),
10
10
  primaryPhone: z.string().max(128).nullable().optional(),
@@ -2,9 +2,9 @@
2
2
  import { z } from 'zod';
3
3
  const createGuard = z.object({
4
4
  tenantId: z.string().max(21).optional(),
5
- id: z.string().max(21),
6
- userId: z.string().max(21),
7
- roleId: z.string().max(21),
5
+ id: z.string().min(1).max(21),
6
+ userId: z.string().min(1).max(21),
7
+ roleId: z.string().min(1).max(21),
8
8
  });
9
9
  const guard = z.object({
10
10
  tenantId: z.string().max(21),
@@ -2,8 +2,8 @@
2
2
  import { z } from 'zod';
3
3
  const createGuard = z.object({
4
4
  tenantId: z.string().max(21).optional(),
5
- id: z.string().max(21),
6
- userId: z.string().max(21),
5
+ id: z.string().min(1).max(21),
6
+ userId: z.string().min(1).max(21),
7
7
  createdAt: z.number().optional(),
8
8
  });
9
9
  const guard = z.object({
@@ -228,17 +228,28 @@ export declare enum HookEvent {
228
228
  PostResetPassword = "PostResetPassword"
229
229
  }
230
230
  export declare const hookEventGuard: z.ZodType<HookEvent>;
231
- export type HookConfig = {
231
+ export declare const hookEventsGuard: z.ZodArray<z.ZodType<HookEvent, z.ZodTypeDef, HookEvent>, "many">;
232
+ export type HookEvents = z.infer<typeof hookEventsGuard>;
233
+ export declare const hookConfigGuard: z.ZodObject<{
232
234
  /** We don't need `type` since v1 only has web hook */
233
235
  /** Method fixed to `POST` */
234
- url: string;
236
+ url: z.ZodString;
235
237
  /** Additional headers that attach to the request */
236
- headers?: Record<string, string>;
238
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
237
239
  /**
240
+ * @deprecated
238
241
  * Retry times when hook response status >= 500.
239
- *
240
- * Must be less than or equal to `3`. Use `0` to disable retry.
241
- **/
242
+ * Now the retry times is fixed to 3.
243
+ * Keep for backward compatibility.
244
+ */
245
+ retries: z.ZodNumber;
246
+ }, "strip", z.ZodTypeAny, {
247
+ headers?: Record<string, string> | undefined;
248
+ url: string;
242
249
  retries: number;
243
- };
244
- export declare const hookConfigGuard: z.ZodType<HookConfig>;
250
+ }, {
251
+ headers?: Record<string, string> | undefined;
252
+ url: string;
253
+ retries: number;
254
+ }>;
255
+ export type HookConfig = z.infer<typeof hookConfigGuard>;
@@ -126,8 +126,19 @@ export var HookEvent;
126
126
  HookEvent["PostResetPassword"] = "PostResetPassword";
127
127
  })(HookEvent || (HookEvent = {}));
128
128
  export const hookEventGuard = z.nativeEnum(HookEvent);
129
+ export const hookEventsGuard = hookEventGuard.array();
129
130
  export const hookConfigGuard = z.object({
131
+ /** We don't need `type` since v1 only has web hook */
132
+ // type: 'web';
133
+ /** Method fixed to `POST` */
130
134
  url: z.string(),
135
+ /** Additional headers that attach to the request */
131
136
  headers: z.record(z.string()).optional(),
137
+ /**
138
+ * @deprecated
139
+ * Retry times when hook response status >= 500.
140
+ * Now the retry times is fixed to 3.
141
+ * Keep for backward compatibility.
142
+ */
132
143
  retries: z.number().gte(0).lte(3),
133
144
  });