@logto/schemas 1.7.0 → 1.8.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.
- package/alterations/1.8.0-1692088012-add-is-suspend-column-to-tenants-table.ts +18 -0
- package/alterations/1.8.0-1692194751-add-affiliate-scopes.ts +57 -0
- package/alterations-js/1.8.0-1692088012-add-is-suspend-column-to-tenants-table.d.ts +3 -0
- package/alterations-js/1.8.0-1692088012-add-is-suspend-column-to-tenants-table.js +14 -0
- package/alterations-js/1.8.0-1692194751-add-affiliate-scopes.d.ts +3 -0
- package/alterations-js/1.8.0-1692194751-add-affiliate-scopes.js +48 -0
- package/lib/foundations/jsonb-types.js +1 -1
- package/lib/models/tenants.d.ts +7 -5
- package/lib/models/tenants.js +2 -1
- package/lib/seeds/cloud-api.js +2 -0
- package/lib/types/log/index.d.ts +3 -1
- package/package.json +4 -4
|
@@ -0,0 +1,18 @@
|
|
|
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 tenants add column is_suspended boolean not null default false;
|
|
9
|
+
`);
|
|
10
|
+
},
|
|
11
|
+
down: async (pool) => {
|
|
12
|
+
await pool.query(sql`
|
|
13
|
+
alter table tenants drop column is_suspended;
|
|
14
|
+
`);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default alteration;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { generateStandardId } from '@logto/shared/universal';
|
|
2
|
+
import { sql } from 'slonik';
|
|
3
|
+
|
|
4
|
+
import type { AlterationScript } from '../lib/types/alteration.js';
|
|
5
|
+
|
|
6
|
+
const adminTenantId = 'admin';
|
|
7
|
+
|
|
8
|
+
const alteration: AlterationScript = {
|
|
9
|
+
up: async (pool) => {
|
|
10
|
+
// Get `resourceId` of the admin tenant's resource whose indicator is `https://cloud.logto.io/api`.
|
|
11
|
+
const { id: resourceId } = await pool.one<{ id: string }>(sql`
|
|
12
|
+
select id from resources
|
|
13
|
+
where tenant_id = ${adminTenantId}
|
|
14
|
+
and indicator = 'https://cloud.logto.io/api'
|
|
15
|
+
`);
|
|
16
|
+
|
|
17
|
+
const { id: roleId } = await pool.one<{ id: string }>(sql`
|
|
18
|
+
select id from roles
|
|
19
|
+
where tenant_id = ${adminTenantId}
|
|
20
|
+
and name = 'admin:admin'
|
|
21
|
+
`);
|
|
22
|
+
|
|
23
|
+
const createAffiliateId = generateStandardId();
|
|
24
|
+
const manageAffiliateId = generateStandardId();
|
|
25
|
+
|
|
26
|
+
await pool.query(sql`
|
|
27
|
+
insert into scopes (tenant_id, id, name, description, resource_id)
|
|
28
|
+
values (
|
|
29
|
+
${adminTenantId},
|
|
30
|
+
${createAffiliateId},
|
|
31
|
+
'create:affiliate',
|
|
32
|
+
'Allow creating new affiliates and logs.',
|
|
33
|
+
${resourceId}
|
|
34
|
+
), (
|
|
35
|
+
${adminTenantId},
|
|
36
|
+
${manageAffiliateId},
|
|
37
|
+
'manage:affiliate',
|
|
38
|
+
'Allow managing affiliates, including create, update, and delete.',
|
|
39
|
+
${resourceId}
|
|
40
|
+
);
|
|
41
|
+
`);
|
|
42
|
+
|
|
43
|
+
await pool.query(sql`
|
|
44
|
+
insert into roles_scopes (tenant_id, id, role_id, scope_id) values
|
|
45
|
+
(${adminTenantId}, ${generateStandardId()}, ${roleId}, ${createAffiliateId}),
|
|
46
|
+
(${adminTenantId}, ${generateStandardId()}, ${roleId}, ${manageAffiliateId});
|
|
47
|
+
`);
|
|
48
|
+
},
|
|
49
|
+
down: async (pool) => {
|
|
50
|
+
await pool.query(sql`
|
|
51
|
+
delete from scopes
|
|
52
|
+
where tenant_id = ${adminTenantId} and name = any(array['create:affiliate', 'manage:affiliate']);
|
|
53
|
+
`);
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default alteration;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { sql } from 'slonik';
|
|
2
|
+
const alteration = {
|
|
3
|
+
up: async (pool) => {
|
|
4
|
+
await pool.query(sql `
|
|
5
|
+
alter table tenants add column is_suspended boolean not null default false;
|
|
6
|
+
`);
|
|
7
|
+
},
|
|
8
|
+
down: async (pool) => {
|
|
9
|
+
await pool.query(sql `
|
|
10
|
+
alter table tenants drop column is_suspended;
|
|
11
|
+
`);
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export default alteration;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { generateStandardId } from '@logto/shared/universal';
|
|
2
|
+
import { sql } from 'slonik';
|
|
3
|
+
const adminTenantId = 'admin';
|
|
4
|
+
const alteration = {
|
|
5
|
+
up: async (pool) => {
|
|
6
|
+
// Get `resourceId` of the admin tenant's resource whose indicator is `https://cloud.logto.io/api`.
|
|
7
|
+
const { id: resourceId } = await pool.one(sql `
|
|
8
|
+
select id from resources
|
|
9
|
+
where tenant_id = ${adminTenantId}
|
|
10
|
+
and indicator = 'https://cloud.logto.io/api'
|
|
11
|
+
`);
|
|
12
|
+
const { id: roleId } = await pool.one(sql `
|
|
13
|
+
select id from roles
|
|
14
|
+
where tenant_id = ${adminTenantId}
|
|
15
|
+
and name = 'admin:admin'
|
|
16
|
+
`);
|
|
17
|
+
const createAffiliateId = generateStandardId();
|
|
18
|
+
const manageAffiliateId = generateStandardId();
|
|
19
|
+
await pool.query(sql `
|
|
20
|
+
insert into scopes (tenant_id, id, name, description, resource_id)
|
|
21
|
+
values (
|
|
22
|
+
${adminTenantId},
|
|
23
|
+
${createAffiliateId},
|
|
24
|
+
'create:affiliate',
|
|
25
|
+
'Allow creating new affiliates and logs.',
|
|
26
|
+
${resourceId}
|
|
27
|
+
), (
|
|
28
|
+
${adminTenantId},
|
|
29
|
+
${manageAffiliateId},
|
|
30
|
+
'manage:affiliate',
|
|
31
|
+
'Allow managing affiliates, including create, update, and delete.',
|
|
32
|
+
${resourceId}
|
|
33
|
+
);
|
|
34
|
+
`);
|
|
35
|
+
await pool.query(sql `
|
|
36
|
+
insert into roles_scopes (tenant_id, id, role_id, scope_id) values
|
|
37
|
+
(${adminTenantId}, ${generateStandardId()}, ${roleId}, ${createAffiliateId}),
|
|
38
|
+
(${adminTenantId}, ${generateStandardId()}, ${roleId}, ${manageAffiliateId});
|
|
39
|
+
`);
|
|
40
|
+
},
|
|
41
|
+
down: async (pool) => {
|
|
42
|
+
await pool.query(sql `
|
|
43
|
+
delete from scopes
|
|
44
|
+
where tenant_id = ${adminTenantId} and name = any(array['create:affiliate', 'manage:affiliate']);
|
|
45
|
+
`);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export default alteration;
|
|
@@ -65,7 +65,7 @@ export var CustomClientMetadataKey;
|
|
|
65
65
|
CustomClientMetadataKey["RotateRefreshToken"] = "rotateRefreshToken";
|
|
66
66
|
})(CustomClientMetadataKey || (CustomClientMetadataKey = {}));
|
|
67
67
|
export const customClientMetadataGuard = z.object({
|
|
68
|
-
[CustomClientMetadataKey.CorsAllowedOrigins]: z.string().
|
|
68
|
+
[CustomClientMetadataKey.CorsAllowedOrigins]: z.string().min(1).array().optional(),
|
|
69
69
|
[CustomClientMetadataKey.IdTokenTtl]: z.number().optional(),
|
|
70
70
|
[CustomClientMetadataKey.RefreshTokenTtl]: z.number().optional(),
|
|
71
71
|
[CustomClientMetadataKey.RefreshTokenTtlInDays]: z.number().int().min(1).max(90).optional(),
|
package/lib/models/tenants.d.ts
CHANGED
|
@@ -12,11 +12,9 @@ export declare const Tenants: import("@withtyped/server/model").default<"tenants
|
|
|
12
12
|
name: string;
|
|
13
13
|
tag: TenantTag;
|
|
14
14
|
createdAt: Date;
|
|
15
|
-
|
|
15
|
+
isSuspended: boolean;
|
|
16
|
+
}, "name" | "createdAt" | "isSuspended" | "tag", "createdAt">;
|
|
16
17
|
export type TenantModel = InferModelType<typeof Tenants>;
|
|
17
|
-
export type TenantInfo = Pick<TenantModel, 'id' | 'name' | 'tag'> & {
|
|
18
|
-
indicator: string;
|
|
19
|
-
};
|
|
20
18
|
export declare const tenantInfoGuard: z.ZodObject<z.extendShape<Pick<{
|
|
21
19
|
id: z.ZodType<string, z.ZodTypeDef, string>;
|
|
22
20
|
dbUser: z.ZodType<string | null, z.ZodTypeDef, string | null>;
|
|
@@ -24,16 +22,20 @@ export declare const tenantInfoGuard: z.ZodObject<z.extendShape<Pick<{
|
|
|
24
22
|
name: z.ZodType<string, z.ZodTypeDef, string>;
|
|
25
23
|
tag: z.ZodType<TenantTag, z.ZodTypeDef, TenantTag>;
|
|
26
24
|
createdAt: z.ZodType<Date, z.ZodTypeDef, Date>;
|
|
27
|
-
|
|
25
|
+
isSuspended: z.ZodType<boolean, z.ZodTypeDef, boolean>;
|
|
26
|
+
}, "name" | "id" | "isSuspended" | "tag">, {
|
|
28
27
|
indicator: z.ZodString;
|
|
29
28
|
}>, "strip", z.ZodTypeAny, {
|
|
30
29
|
name: string;
|
|
31
30
|
id: string;
|
|
32
31
|
indicator: string;
|
|
32
|
+
isSuspended: boolean;
|
|
33
33
|
tag: TenantTag;
|
|
34
34
|
}, {
|
|
35
35
|
name: string;
|
|
36
36
|
id: string;
|
|
37
37
|
indicator: string;
|
|
38
|
+
isSuspended: boolean;
|
|
38
39
|
tag: TenantTag;
|
|
39
40
|
}>;
|
|
41
|
+
export type TenantInfo = z.infer<typeof tenantInfoGuard>;
|
package/lib/models/tenants.js
CHANGED
|
@@ -16,6 +16,7 @@ export const Tenants = createModel(
|
|
|
16
16
|
name varchar(128) not null default 'My Project',
|
|
17
17
|
tag varchar(64) not null default '${TenantTag.Development}',
|
|
18
18
|
created_at timestamptz not null default(now()),
|
|
19
|
+
is_suspended boolean not null default false,
|
|
19
20
|
primary key (id),
|
|
20
21
|
constraint tenants__db_user
|
|
21
22
|
unique (db_user)
|
|
@@ -25,5 +26,5 @@ export const Tenants = createModel(
|
|
|
25
26
|
.extend('tag', z.nativeEnum(TenantTag))
|
|
26
27
|
.extend('createdAt', { readonly: true });
|
|
27
28
|
export const tenantInfoGuard = Tenants.guard('model')
|
|
28
|
-
.pick({ id: true, name: true, tag: true })
|
|
29
|
+
.pick({ id: true, name: true, tag: true, isSuspended: true })
|
|
29
30
|
.extend({ indicator: z.string() });
|
package/lib/seeds/cloud-api.js
CHANGED
|
@@ -47,6 +47,8 @@ export const createCloudApi = () => {
|
|
|
47
47
|
buildScope(CloudScope.ManageTenant, 'Allow managing existing tenants, including create without limitation, update, and delete.'),
|
|
48
48
|
buildScope(CloudScope.SendEmail, 'Allow sending emails. This scope is only available to M2M application.'),
|
|
49
49
|
buildScope(CloudScope.SendSms, 'Allow sending SMS. This scope is only available to M2M application.'),
|
|
50
|
+
buildScope(CloudScope.CreateAffiliate, 'Allow creating new affiliates and logs.'),
|
|
51
|
+
buildScope(CloudScope.ManageAffiliate, 'Allow managing affiliates, including create, update, and delete.'),
|
|
50
52
|
]);
|
|
51
53
|
};
|
|
52
54
|
export const createTenantApplicationRole = () => ({
|
package/lib/types/log/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * as token from './token.js';
|
|
|
6
6
|
export * as hook from './hook.js';
|
|
7
7
|
/** Fallback for empty or unrecognized log keys. */
|
|
8
8
|
export declare const LogKeyUnknown = "Unknown";
|
|
9
|
+
export type AuditLogKey = typeof LogKeyUnknown | interaction.LogKey | token.LogKey;
|
|
10
|
+
export type WebhookLogKey = hook.LogKey;
|
|
9
11
|
/**
|
|
10
12
|
* The union type of all available log keys.
|
|
11
13
|
* Note duplicate keys are allowed but should be avoided.
|
|
@@ -13,4 +15,4 @@ export declare const LogKeyUnknown = "Unknown";
|
|
|
13
15
|
* @see {@link interaction.LogKey} for interaction log keys.
|
|
14
16
|
* @see {@link token.LogKey} for token log keys.
|
|
15
17
|
**/
|
|
16
|
-
export type LogKey =
|
|
18
|
+
export type LogKey = AuditLogKey | WebhookLogKey;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logto/schemas",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"author": "Silverhand Inc. <contact@silverhand.io>",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
"@types/jest": "^29.4.0",
|
|
32
32
|
"@types/node": "^18.11.18",
|
|
33
33
|
"@types/pluralize": "^0.0.29",
|
|
34
|
-
"camelcase": "^
|
|
34
|
+
"camelcase": "^8.0.0",
|
|
35
35
|
"chalk": "^5.0.0",
|
|
36
36
|
"eslint": "^8.44.0",
|
|
37
37
|
"jest": "^29.5.0",
|
|
38
|
-
"lint-staged": "^
|
|
38
|
+
"lint-staged": "^14.0.0",
|
|
39
39
|
"pluralize": "^8.0.0",
|
|
40
40
|
"prettier": "^3.0.0",
|
|
41
41
|
"roarr": "^7.11.0",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@logto/phrases": "^1.4.1",
|
|
71
71
|
"@logto/phrases-ui": "^1.2.0",
|
|
72
72
|
"@logto/shared": "^2.0.0",
|
|
73
|
-
"@withtyped/server": "^0.12.
|
|
73
|
+
"@withtyped/server": "^0.12.9"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"zod": "^3.20.2"
|