@devxcrew/platform 0.1.2 → 0.1.6
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/README.md +7 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -2
- package/dist/modules/identity/audit/audit.controller.d.ts +17 -0
- package/dist/modules/identity/audit/audit.controller.js +12 -0
- package/dist/modules/identity/audit/audit.migration.d.ts +1 -0
- package/dist/modules/identity/audit/audit.migration.js +1 -0
- package/dist/modules/identity/audit/audit.provider.d.ts +24 -0
- package/dist/modules/identity/audit/audit.provider.js +14 -0
- package/dist/modules/identity/audit/audit.repository.d.ts +26 -0
- package/dist/modules/identity/audit/audit.repository.js +46 -0
- package/dist/modules/identity/audit/audit.routes.d.ts +5 -0
- package/dist/modules/identity/audit/audit.routes.js +2 -0
- package/dist/modules/identity/audit/audit.schema.d.ts +1 -0
- package/dist/modules/identity/audit/audit.schema.js +1 -0
- package/dist/modules/identity/audit/audit.seed.d.ts +1 -0
- package/dist/modules/identity/audit/audit.seed.js +1 -0
- package/dist/modules/identity/audit/audit.service.d.ts +23 -0
- package/dist/modules/identity/audit/audit.service.js +46 -0
- package/dist/modules/identity/audit/audit.types.d.ts +12 -0
- package/dist/modules/identity/audit/audit.types.js +1 -0
- package/dist/modules/identity/audit/index.d.ts +4 -0
- package/dist/modules/identity/audit/index.js +3 -0
- package/dist/modules/identity/{identity.administration-service.d.ts → composition/identity.composition.d.ts} +59 -27
- package/dist/modules/identity/composition/identity.composition.js +171 -0
- package/dist/modules/identity/composition/identity.seed.d.ts +3 -0
- package/dist/modules/identity/composition/identity.seed.js +16 -0
- package/dist/modules/identity/identity.controller.d.ts +8 -6
- package/dist/modules/identity/identity.controller.js +90 -70
- package/dist/modules/identity/identity.migration.d.ts +1 -2
- package/dist/modules/identity/identity.migration.js +1 -79
- package/dist/modules/identity/identity.provider.d.ts +39 -13
- package/dist/modules/identity/identity.provider.js +19 -73
- package/dist/modules/identity/identity.public-schemas.d.ts +9 -3
- package/dist/modules/identity/identity.public-schemas.js +9 -3
- package/dist/modules/identity/identity.repository.d.ts +1 -40
- package/dist/modules/identity/identity.repository.js +1 -196
- package/dist/modules/identity/identity.routes.d.ts +2 -5
- package/dist/modules/identity/identity.routes.js +3 -11
- package/dist/modules/identity/identity.schema.d.ts +1 -27
- package/dist/modules/identity/identity.schema.js +1 -34
- package/dist/modules/identity/identity.seed.d.ts +1 -3
- package/dist/modules/identity/identity.seed.js +1 -81
- package/dist/modules/identity/identity.service.d.ts +1 -32
- package/dist/modules/identity/identity.service.js +1 -83
- package/dist/modules/identity/identity.types.d.ts +13 -106
- package/dist/modules/identity/index.d.ts +18 -11
- package/dist/modules/identity/index.js +14 -8
- package/dist/modules/identity/{identity.administration-migration.js → legacy/identity.administration-migration.js} +3 -11
- package/dist/modules/identity/legacy/identity.migration.d.ts +2 -0
- package/dist/modules/identity/legacy/identity.migration.js +72 -0
- package/dist/modules/identity/organization/index.d.ts +6 -0
- package/dist/modules/identity/organization/index.js +5 -0
- package/dist/modules/identity/organization/organization.controller.d.ts +35 -0
- package/dist/modules/identity/organization/organization.controller.js +18 -0
- package/dist/modules/identity/organization/organization.migration.d.ts +1 -0
- package/dist/modules/identity/organization/organization.migration.js +1 -0
- package/dist/modules/identity/organization/organization.provider.d.ts +46 -0
- package/dist/modules/identity/organization/organization.provider.js +33 -0
- package/dist/modules/identity/organization/organization.repository.d.ts +58 -0
- package/dist/modules/identity/organization/organization.repository.js +101 -0
- package/dist/modules/identity/organization/organization.routes.d.ts +5 -0
- package/dist/modules/identity/organization/organization.routes.js +2 -0
- package/dist/modules/identity/organization/organization.schema.d.ts +11 -0
- package/dist/modules/identity/organization/organization.schema.js +18 -0
- package/dist/modules/identity/organization/organization.seed.d.ts +3 -0
- package/dist/modules/identity/organization/organization.seed.js +11 -0
- package/dist/modules/identity/organization/organization.service.d.ts +39 -0
- package/dist/modules/identity/organization/organization.service.js +55 -0
- package/dist/modules/identity/organization/organization.types.d.ts +19 -0
- package/dist/modules/identity/organization/organization.types.js +1 -0
- package/dist/modules/identity/permission/index.d.ts +9 -0
- package/dist/modules/identity/permission/index.js +6 -0
- package/dist/modules/identity/permission/permission.controller.d.ts +21 -0
- package/dist/modules/identity/permission/permission.controller.js +12 -0
- package/dist/modules/identity/{identity.permission-declarations-migration.js → permission/permission.declarations.migration.js} +9 -4
- package/dist/modules/identity/{identity.permission-labels-migration.js → permission/permission.labels.migration.js} +5 -2
- package/dist/modules/identity/permission/permission.migration.d.ts +2 -0
- package/dist/modules/identity/permission/permission.migration.js +2 -0
- package/dist/modules/identity/permission/permission.provider.d.ts +19 -0
- package/dist/modules/identity/permission/permission.provider.js +14 -0
- package/dist/modules/identity/permission/permission.repository.d.ts +51 -0
- package/dist/modules/identity/permission/permission.repository.js +84 -0
- package/dist/modules/identity/permission/permission.routes.d.ts +5 -0
- package/dist/modules/identity/permission/permission.routes.js +2 -0
- package/dist/modules/identity/permission/permission.schema.d.ts +14 -0
- package/dist/modules/identity/permission/permission.schema.js +29 -0
- package/dist/modules/identity/permission/permission.seed.d.ts +4 -0
- package/dist/modules/identity/permission/permission.seed.js +17 -0
- package/dist/modules/identity/permission/permission.service.d.ts +31 -0
- package/dist/modules/identity/permission/permission.service.js +77 -0
- package/dist/modules/identity/permission/permission.types.d.ts +15 -0
- package/dist/modules/identity/permission/permission.types.js +1 -0
- package/dist/modules/identity/role/index.d.ts +10 -0
- package/dist/modules/identity/role/index.js +6 -0
- package/dist/modules/identity/role/role.controller.d.ts +42 -0
- package/dist/modules/identity/role/role.controller.js +25 -0
- package/dist/modules/identity/{identity.roles-migration.js → role/role.migration.js} +5 -18
- package/dist/modules/identity/role/role.provider.d.ts +14 -0
- package/dist/modules/identity/role/role.provider.js +30 -0
- package/dist/modules/identity/role/role.repository.d.ts +38 -0
- package/dist/modules/identity/role/role.repository.js +46 -0
- package/dist/modules/identity/role/role.routes.d.ts +5 -0
- package/dist/modules/identity/role/role.routes.js +2 -0
- package/dist/modules/identity/role/role.schema.d.ts +16 -0
- package/dist/modules/identity/role/role.schema.js +27 -0
- package/dist/modules/identity/role/role.seed.d.ts +3 -0
- package/dist/modules/identity/role/role.seed.js +8 -0
- package/dist/modules/identity/role/role.service.d.ts +69 -0
- package/dist/modules/identity/role/role.service.js +192 -0
- package/dist/modules/identity/role/role.types.d.ts +17 -0
- package/dist/modules/identity/role/role.types.js +1 -0
- package/dist/modules/identity/role-permission/index.d.ts +6 -0
- package/dist/modules/identity/role-permission/index.js +4 -0
- package/dist/modules/identity/role-permission/role-permission.controller.d.ts +1 -0
- package/dist/modules/identity/role-permission/role-permission.controller.js +1 -0
- package/dist/modules/identity/role-permission/role-permission.migration.d.ts +1 -0
- package/dist/modules/identity/role-permission/role-permission.migration.js +1 -0
- package/dist/modules/identity/role-permission/role-permission.provider.d.ts +14 -0
- package/dist/modules/identity/role-permission/role-permission.provider.js +15 -0
- package/dist/modules/identity/role-permission/role-permission.repository.d.ts +12 -0
- package/dist/modules/identity/role-permission/role-permission.repository.js +51 -0
- package/dist/modules/identity/role-permission/role-permission.routes.d.ts +1 -0
- package/dist/modules/identity/role-permission/role-permission.routes.js +2 -0
- package/dist/modules/identity/role-permission/role-permission.schema.d.ts +2 -0
- package/dist/modules/identity/role-permission/role-permission.schema.js +3 -0
- package/dist/modules/identity/role-permission/role-permission.seed.d.ts +3 -0
- package/dist/modules/identity/role-permission/role-permission.seed.js +10 -0
- package/dist/modules/identity/role-permission/role-permission.service.d.ts +13 -0
- package/dist/modules/identity/role-permission/role-permission.service.js +35 -0
- package/dist/modules/identity/role-permission/role-permission.types.d.ts +12 -0
- package/dist/modules/identity/role-permission/role-permission.types.js +1 -0
- package/dist/modules/identity/session/index.d.ts +6 -0
- package/dist/modules/identity/session/index.js +5 -0
- package/dist/modules/identity/session/session.authentication.controller.d.ts +30 -0
- package/dist/modules/identity/session/session.authentication.controller.js +37 -0
- package/dist/modules/identity/session/session.controller.d.ts +18 -0
- package/dist/modules/identity/session/session.controller.js +15 -0
- package/dist/modules/identity/session/session.migration.d.ts +1 -0
- package/dist/modules/identity/session/session.migration.js +1 -0
- package/dist/modules/identity/session/session.provider.d.ts +34 -0
- package/dist/modules/identity/session/session.provider.js +23 -0
- package/dist/modules/identity/session/session.repository.d.ts +36 -0
- package/dist/modules/identity/session/session.repository.js +128 -0
- package/dist/modules/identity/session/session.routes.d.ts +27 -0
- package/dist/modules/identity/session/session.routes.js +13 -0
- package/dist/modules/identity/session/session.schema.d.ts +6 -0
- package/dist/modules/identity/session/session.schema.js +12 -0
- package/dist/modules/identity/session/session.seed.d.ts +1 -0
- package/dist/modules/identity/session/session.seed.js +1 -0
- package/dist/modules/identity/session/session.service.d.ts +20 -0
- package/dist/modules/identity/session/session.service.js +27 -0
- package/dist/modules/identity/session/session.types.d.ts +17 -0
- package/dist/modules/identity/session/session.types.js +1 -0
- package/dist/modules/identity/settings/index.d.ts +5 -0
- package/dist/modules/identity/settings/index.js +4 -0
- package/dist/modules/identity/settings/settings.controller.d.ts +35 -0
- package/dist/modules/identity/settings/settings.controller.js +18 -0
- package/dist/modules/identity/settings/settings.migration.d.ts +1 -0
- package/dist/modules/identity/settings/settings.migration.js +1 -0
- package/dist/modules/identity/settings/settings.provider.d.ts +35 -0
- package/dist/modules/identity/settings/settings.provider.js +14 -0
- package/dist/modules/identity/settings/settings.repository.d.ts +49 -0
- package/dist/modules/identity/settings/settings.repository.js +75 -0
- package/dist/modules/identity/settings/settings.routes.d.ts +1 -0
- package/dist/modules/identity/settings/settings.routes.js +7 -0
- package/dist/modules/identity/settings/settings.schema.d.ts +15 -0
- package/dist/modules/identity/settings/settings.schema.js +27 -0
- package/dist/modules/identity/settings/settings.seed.d.ts +1 -0
- package/dist/modules/identity/settings/settings.seed.js +1 -0
- package/dist/modules/identity/settings/settings.service.d.ts +40 -0
- package/dist/modules/identity/settings/settings.service.js +101 -0
- package/dist/modules/identity/settings/settings.types.d.ts +20 -0
- package/dist/modules/identity/settings/settings.types.js +1 -0
- package/dist/modules/identity/support/identity.schema.d.ts +8 -0
- package/dist/modules/identity/support/identity.schema.js +10 -0
- package/dist/modules/identity/support/pagination.d.ts +13 -0
- package/dist/modules/identity/support/pagination.js +27 -0
- package/dist/modules/identity/support/pagination.schema.d.ts +43 -0
- package/dist/modules/identity/support/pagination.schema.js +15 -0
- package/dist/modules/identity/support/resource-controller.d.ts +14 -0
- package/dist/modules/identity/support/resource-controller.js +1 -0
- package/dist/modules/identity/user/index.d.ts +13 -0
- package/dist/modules/identity/user/index.js +11 -0
- package/dist/modules/identity/user/user.administration.service.d.ts +59 -0
- package/dist/modules/identity/user/user.administration.service.js +159 -0
- package/dist/modules/identity/user/user.controller.d.ts +44 -0
- package/dist/modules/identity/user/user.controller.js +21 -0
- package/dist/modules/identity/user/user.lifecycle.controller.d.ts +58 -0
- package/dist/modules/identity/user/user.lifecycle.controller.js +27 -0
- package/dist/modules/identity/{identity.lifecycle-schema.js → user/user.lifecycle.schema.js} +5 -5
- package/dist/modules/identity/{identity.lifecycle-service.d.ts → user/user.lifecycle.service.d.ts} +8 -4
- package/dist/modules/identity/{identity.lifecycle-service.js → user/user.lifecycle.service.js} +66 -118
- package/dist/modules/identity/user/user.migration.d.ts +1 -0
- package/dist/modules/identity/user/user.migration.js +1 -0
- package/dist/modules/identity/{identity.password.js → user/user.password.js} +1 -1
- package/dist/modules/identity/user/user.provider.d.ts +80 -0
- package/dist/modules/identity/user/user.provider.js +22 -0
- package/dist/modules/identity/user/user.repository.d.ts +64 -0
- package/dist/modules/identity/user/user.repository.js +129 -0
- package/dist/modules/identity/user/user.routes.d.ts +12 -0
- package/dist/modules/identity/user/user.routes.js +9 -0
- package/dist/modules/identity/user/user.schema.d.ts +34 -0
- package/dist/modules/identity/user/user.schema.js +46 -0
- package/dist/modules/identity/user/user.seed.d.ts +14 -0
- package/dist/modules/identity/user/user.seed.js +47 -0
- package/dist/modules/identity/user/user.service.d.ts +33 -0
- package/dist/modules/identity/user/user.service.js +76 -0
- package/dist/modules/identity/user/user.types.d.ts +27 -0
- package/dist/modules/identity/user/user.types.js +1 -0
- package/dist/modules/identity/user-role/index.d.ts +8 -0
- package/dist/modules/identity/user-role/index.js +6 -0
- package/dist/modules/identity/user-role/user-role.controller.d.ts +42 -0
- package/dist/modules/identity/user-role/user-role.controller.js +21 -0
- package/dist/modules/identity/user-role/user-role.migration.d.ts +1 -0
- package/dist/modules/identity/user-role/user-role.migration.js +1 -0
- package/dist/modules/identity/user-role/user-role.policy.d.ts +3 -0
- package/dist/modules/identity/user-role/user-role.policy.js +25 -0
- package/dist/modules/identity/user-role/user-role.provider.d.ts +18 -0
- package/dist/modules/identity/user-role/user-role.provider.js +23 -0
- package/dist/modules/identity/user-role/user-role.repository.d.ts +34 -0
- package/dist/modules/identity/user-role/user-role.repository.js +87 -0
- package/dist/modules/identity/user-role/user-role.routes.d.ts +5 -0
- package/dist/modules/identity/user-role/user-role.routes.js +2 -0
- package/dist/modules/identity/user-role/user-role.schema.d.ts +14 -0
- package/dist/modules/identity/user-role/user-role.schema.js +25 -0
- package/dist/modules/identity/user-role/user-role.seed.d.ts +7 -0
- package/dist/modules/identity/user-role/user-role.seed.js +11 -0
- package/dist/modules/identity/user-role/user-role.service.d.ts +60 -0
- package/dist/modules/identity/user-role/user-role.service.js +216 -0
- package/dist/modules/identity/user-role/user-role.types.d.ts +12 -0
- package/dist/modules/identity/user-role/user-role.types.js +1 -0
- package/dist/modules/tenant/index.d.ts +6 -0
- package/dist/modules/tenant/index.js +5 -0
- package/dist/modules/tenant/tenant.command.d.ts +3 -0
- package/dist/modules/tenant/tenant.command.js +43 -0
- package/dist/modules/tenant/tenant.controller.d.ts +4 -0
- package/dist/modules/tenant/tenant.controller.js +12 -0
- package/dist/modules/tenant/tenant.migration.d.ts +5 -0
- package/dist/modules/tenant/tenant.migration.js +46 -0
- package/dist/modules/tenant/tenant.provider.d.ts +3 -0
- package/dist/modules/tenant/tenant.provider.js +44 -0
- package/dist/modules/tenant/tenant.readiness.d.ts +6 -0
- package/dist/modules/tenant/tenant.readiness.js +45 -0
- package/dist/modules/tenant/tenant.repository.d.ts +15 -0
- package/dist/modules/tenant/tenant.repository.js +23 -0
- package/dist/modules/tenant/tenant.routes.d.ts +4 -0
- package/dist/modules/tenant/tenant.routes.js +7 -0
- package/dist/modules/tenant/tenant.schema.d.ts +20 -0
- package/dist/modules/tenant/tenant.schema.js +31 -0
- package/dist/modules/tenant/tenant.seed.d.ts +8 -0
- package/dist/modules/tenant/tenant.seed.js +40 -0
- package/dist/modules/tenant/tenant.service.d.ts +16 -0
- package/dist/modules/tenant/tenant.service.js +72 -0
- package/dist/modules/tenant/tenant.types.d.ts +39 -0
- package/dist/modules/tenant/tenant.types.js +1 -0
- package/package.json +9 -5
- package/dist/modules/identity/identity.administration-repository.d.ts +0 -19
- package/dist/modules/identity/identity.administration-repository.js +0 -102
- package/dist/modules/identity/identity.administration-schema.d.ts +0 -113
- package/dist/modules/identity/identity.administration-schema.js +0 -121
- package/dist/modules/identity/identity.administration-service.js +0 -517
- package/dist/modules/identity/identity.membership-policy.d.ts +0 -3
- package/dist/modules/identity/identity.membership-policy.js +0 -27
- package/dist/modules/identity/identity.permission-declarations.d.ts +0 -23
- package/dist/modules/identity/identity.permission-declarations.js +0 -57
- package/dist/modules/identity/identity.presentation-service.d.ts +0 -23
- package/dist/modules/identity/identity.presentation-service.js +0 -51
- package/dist/modules/identity/identity.roles-service.d.ts +0 -49
- package/dist/modules/identity/identity.roles-service.js +0 -327
- /package/dist/modules/identity/{identity.administration-migration.d.ts → legacy/identity.administration-migration.d.ts} +0 -0
- /package/dist/modules/identity/{identity.permission-declarations-migration.d.ts → permission/permission.declarations.migration.d.ts} +0 -0
- /package/dist/modules/identity/{identity.permission-labels-migration.d.ts → permission/permission.labels.migration.d.ts} +0 -0
- /package/dist/modules/identity/{identity.roles-migration.d.ts → role/role.migration.d.ts} +0 -0
- /package/dist/modules/identity/{identity.error.d.ts → support/identity.error.d.ts} +0 -0
- /package/dist/modules/identity/{identity.error.js → support/identity.error.js} +0 -0
- /package/dist/modules/identity/{identity.request-context.d.ts → support/identity.request-context.d.ts} +0 -0
- /package/dist/modules/identity/{identity.request-context.js → support/identity.request-context.js} +0 -0
- /package/dist/modules/identity/{identity.lifecycle-schema.d.ts → user/user.lifecycle.schema.d.ts} +0 -0
- /package/dist/modules/identity/{identity.password.d.ts → user/user.password.d.ts} +0 -0
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
-
import type {
|
|
2
|
+
import type { IdentityUserProvider } from "./user/index.js";
|
|
3
3
|
import type { IdentityConfig, Portal } from "./identity.types.js";
|
|
4
|
-
import {
|
|
5
|
-
import { IdentityLifecycleService } from "./identity.lifecycle-service.js";
|
|
4
|
+
import { IdentityAdministrationComposition } from "./composition/identity.composition.js";
|
|
6
5
|
export declare class IdentityController {
|
|
7
|
-
private readonly service;
|
|
8
6
|
private readonly config;
|
|
9
7
|
private readonly administration;
|
|
10
|
-
private readonly
|
|
11
|
-
|
|
8
|
+
private readonly authentication;
|
|
9
|
+
private readonly accounts;
|
|
10
|
+
constructor(service: IdentityUserProvider["identity"], config: IdentityConfig, administration: IdentityAdministrationComposition, lifecycle: IdentityUserProvider["lifecycle"]);
|
|
12
11
|
handle(request: IncomingMessage, response: ServerResponse, signal?: AbortSignal): Promise<boolean>;
|
|
13
12
|
authenticateRequest(request: IncomingMessage, requestedPortal: Portal, signal?: AbortSignal): Promise<import("./identity.types.js").Principal>;
|
|
14
13
|
private handleRequest;
|
|
15
14
|
private adminRequest;
|
|
16
15
|
private wireList;
|
|
16
|
+
private requireResult;
|
|
17
|
+
private requireAction;
|
|
18
|
+
private requireUpdate;
|
|
17
19
|
private cookie;
|
|
18
20
|
private cookieName;
|
|
19
21
|
private token;
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { ZodError } from "zod";
|
|
2
|
-
import { portalSchema,
|
|
3
|
-
import {
|
|
2
|
+
import { portalSchema, IdentityUserLifecycleController, userLifecyclePaths } from "./user/index.js";
|
|
3
|
+
import { settingsPaths } from "./settings/index.js";
|
|
4
|
+
import { IdentitySessionAuthenticationController } from "./session/index.js";
|
|
5
|
+
import { IdentityError } from "./support/identity.error.js";
|
|
4
6
|
import { identityRoutes, portalRoutes } from "./identity.routes.js";
|
|
5
|
-
import { resourceListQuerySchema
|
|
6
|
-
import {
|
|
7
|
+
import { resourceListQuerySchema } from "./support/pagination.schema.js";
|
|
8
|
+
import { membershipDeleteQuerySchema } from "./user-role/index.js";
|
|
9
|
+
import { resourceIdSchema } from "./support/identity.schema.js";
|
|
10
|
+
import { checkIdentityRequest, runIdentityRequest } from "./support/identity.request-context.js";
|
|
7
11
|
export class IdentityController {
|
|
8
|
-
service;
|
|
9
12
|
config;
|
|
10
13
|
administration;
|
|
11
|
-
|
|
14
|
+
authentication;
|
|
15
|
+
accounts;
|
|
12
16
|
constructor(service, config, administration, lifecycle) {
|
|
13
|
-
this.service = service;
|
|
14
17
|
this.config = config;
|
|
15
18
|
this.administration = administration;
|
|
16
|
-
this.
|
|
19
|
+
this.authentication = new IdentitySessionAuthenticationController(service, config);
|
|
20
|
+
this.accounts = new IdentityUserLifecycleController(lifecycle);
|
|
17
21
|
}
|
|
18
22
|
async handle(request, response, signal) {
|
|
19
23
|
return runIdentityRequest(signal, () => this.handleRequest(request, response));
|
|
@@ -23,11 +27,14 @@ export class IdentityController {
|
|
|
23
27
|
checkIdentityRequest();
|
|
24
28
|
const parsedPortal = portalSchema.safeParse(requestedPortal);
|
|
25
29
|
if (!parsedPortal.success)
|
|
26
|
-
throw new IdentityError(422, "Validation failed", {
|
|
30
|
+
throw new IdentityError(422, "Validation failed", {
|
|
31
|
+
portal: ["Select a supported portal."]
|
|
32
|
+
});
|
|
27
33
|
const portal = parsedPortal.data;
|
|
28
|
-
if (!["GET", "HEAD", "OPTIONS"].includes(request.method ?? "") &&
|
|
34
|
+
if (!["GET", "HEAD", "OPTIONS"].includes(request.method ?? "") &&
|
|
35
|
+
request.headers.origin !== this.config.origin)
|
|
29
36
|
throw new IdentityError(403, "Untrusted request origin.");
|
|
30
|
-
const principal = await this.
|
|
37
|
+
const principal = await this.authentication.authenticate(portal, this.token(request, portal));
|
|
31
38
|
checkIdentityRequest();
|
|
32
39
|
return principal;
|
|
33
40
|
});
|
|
@@ -46,8 +53,8 @@ export class IdentityController {
|
|
|
46
53
|
const token = this.token(request, portal);
|
|
47
54
|
if (desk) {
|
|
48
55
|
try {
|
|
49
|
-
const principal = await this.
|
|
50
|
-
this.
|
|
56
|
+
const principal = await this.authentication.authenticate(portal, token);
|
|
57
|
+
this.authentication.requireDesk(principal, portal);
|
|
51
58
|
return false;
|
|
52
59
|
}
|
|
53
60
|
catch (error) {
|
|
@@ -59,37 +66,33 @@ export class IdentityController {
|
|
|
59
66
|
}
|
|
60
67
|
}
|
|
61
68
|
const route = identityRoutes.find((r) => r.method === request.method && r.path === api?.[2]);
|
|
62
|
-
if (request.method !== "GET" &&
|
|
63
|
-
request.headers.origin !== this.config.origin)
|
|
69
|
+
if (request.method !== "GET" && request.headers.origin !== this.config.origin)
|
|
64
70
|
throw new IdentityError(403, "Untrusted request origin.");
|
|
65
71
|
if (!route) {
|
|
66
72
|
await this.adminRequest(request, response, portal, token, api[2]);
|
|
67
73
|
return true;
|
|
68
74
|
}
|
|
69
75
|
if (route.action === "login") {
|
|
70
|
-
const result = await this.
|
|
71
|
-
.refine((input) => this.config.mode !== "multi-tenant" || Boolean(input.tenantId), { path: ["tenantId"], message: "Enter an organization ID." })
|
|
72
|
-
.parse(await this.body(request)), request.socket.remoteAddress ?? "unknown", token);
|
|
76
|
+
const result = await this.authentication.login(portal, await this.body(request), request.socket.remoteAddress ?? "unknown", token);
|
|
73
77
|
response.setHeader("Set-Cookie", this.cookie(portal, result.token, result.sessionSeconds));
|
|
74
78
|
this.json(response, 201, { data: result.principal });
|
|
75
79
|
}
|
|
76
80
|
else if (route.action === "logout") {
|
|
77
|
-
await this.
|
|
81
|
+
await this.authentication.logout(portal, token);
|
|
78
82
|
response.setHeader("Set-Cookie", this.cookie(portal, "", 0));
|
|
79
83
|
response.writeHead(204);
|
|
80
84
|
response.end();
|
|
81
85
|
}
|
|
82
86
|
else {
|
|
83
|
-
const principal = await this.
|
|
87
|
+
const principal = await this.authentication.authenticate(portal, token);
|
|
84
88
|
if (route.action === "password") {
|
|
85
|
-
await this.
|
|
89
|
+
await this.authentication.changePassword(principal, await this.body(request));
|
|
86
90
|
response.setHeader("Set-Cookie", this.cookie(portal, "", 0));
|
|
87
91
|
response.writeHead(204);
|
|
88
92
|
response.end();
|
|
89
93
|
}
|
|
90
94
|
else {
|
|
91
|
-
this.
|
|
92
|
-
this.json(response, 200, { data: principal });
|
|
95
|
+
this.json(response, 200, { data: this.authentication.current(principal, portal) });
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
}
|
|
@@ -105,62 +108,67 @@ export class IdentityController {
|
|
|
105
108
|
else {
|
|
106
109
|
console.error("Identity request failed.");
|
|
107
110
|
this.json(response, 500, {
|
|
108
|
-
message: "Unable to complete the request."
|
|
111
|
+
message: "Unable to complete the request."
|
|
109
112
|
});
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
return true;
|
|
113
116
|
}
|
|
114
117
|
async adminRequest(request, response, portal, token, path) {
|
|
115
|
-
if (path ===
|
|
118
|
+
if (path === settingsPaths[0]) {
|
|
116
119
|
if (request.method !== "GET")
|
|
117
120
|
throw new IdentityError(405, "Method not allowed.");
|
|
118
121
|
this.json(response, 200, {
|
|
119
|
-
data: await this.administration.configuration(this.config.appId, this.config.mode === "multi-tenant")
|
|
122
|
+
data: await this.administration.settingsController.configuration(this.config.appId, this.config.mode === "multi-tenant")
|
|
120
123
|
});
|
|
121
124
|
return;
|
|
122
125
|
}
|
|
123
|
-
if ([
|
|
126
|
+
if ([
|
|
127
|
+
userLifecyclePaths.recovery,
|
|
128
|
+
userLifecyclePaths.recoveryComplete,
|
|
129
|
+
userLifecyclePaths.invitationAccept
|
|
130
|
+
].some((route) => route === path)) {
|
|
124
131
|
if (request.method !== "POST")
|
|
125
132
|
throw new IdentityError(405, "Method not allowed.");
|
|
126
133
|
const raw = await this.body(request);
|
|
127
|
-
const data = path ===
|
|
128
|
-
? await this.
|
|
129
|
-
: await this.
|
|
130
|
-
this.json(response, path ===
|
|
134
|
+
const data = path === userLifecyclePaths.recovery
|
|
135
|
+
? await this.accounts.requestRecovery(portal, raw, request.socket.remoteAddress ?? "unknown")
|
|
136
|
+
: await this.accounts.complete(portal, path === userLifecyclePaths.recoveryComplete ? "recovery" : "invitation", raw, request.socket.remoteAddress ?? "unknown");
|
|
137
|
+
this.json(response, path === userLifecyclePaths.recovery ? 202 : 200, { data });
|
|
131
138
|
return;
|
|
132
139
|
}
|
|
133
|
-
const principal = await this.
|
|
134
|
-
if (path ===
|
|
140
|
+
const principal = await this.authentication.authenticate(portal, token);
|
|
141
|
+
if (path === settingsPaths[1]) {
|
|
135
142
|
if (request.method !== "GET")
|
|
136
143
|
throw new IdentityError(405, "Method not allowed.");
|
|
137
144
|
this.json(response, 200, {
|
|
138
|
-
data: await this.administration.presentation(principal)
|
|
145
|
+
data: await this.administration.settingsController.presentation(principal)
|
|
139
146
|
});
|
|
140
147
|
return;
|
|
141
148
|
}
|
|
142
|
-
if (path ===
|
|
143
|
-
|
|
149
|
+
if (path === userLifecyclePaths.invitations ||
|
|
150
|
+
path.startsWith(`${userLifecyclePaths.invitations}/`)) {
|
|
151
|
+
if (path === userLifecyclePaths.invitations && request.method === "GET") {
|
|
144
152
|
const query = resourceListQuerySchema.parse(Object.fromEntries(new URL(request.url, this.config.origin).searchParams));
|
|
145
|
-
this.json(response, 200, this.wireList(await this.
|
|
153
|
+
this.json(response, 200, this.wireList(await this.accounts.index(principal, query)));
|
|
146
154
|
}
|
|
147
|
-
else if (path ===
|
|
155
|
+
else if (path === userLifecyclePaths.invitations && request.method === "POST") {
|
|
148
156
|
this.json(response, 201, {
|
|
149
|
-
data: await this.
|
|
157
|
+
data: await this.accounts.store(principal, await this.body(request))
|
|
150
158
|
});
|
|
151
159
|
}
|
|
152
160
|
else if (request.method === "GET") {
|
|
153
161
|
this.json(response, 200, {
|
|
154
|
-
data: await this.
|
|
162
|
+
data: await this.accounts.show(principal, resourceIdSchema.parse(path.slice(`${userLifecyclePaths.invitations}/`.length)))
|
|
155
163
|
});
|
|
156
164
|
}
|
|
157
165
|
else if (request.method === "POST" && path.endsWith("/resend")) {
|
|
158
166
|
this.json(response, 201, {
|
|
159
|
-
data: await this.
|
|
167
|
+
data: await this.accounts.resend(principal, resourceIdSchema.parse(path.slice(`${userLifecyclePaths.invitations}/`.length, -"/resend".length)))
|
|
160
168
|
});
|
|
161
169
|
}
|
|
162
170
|
else if (request.method === "DELETE") {
|
|
163
|
-
await this.
|
|
171
|
+
await this.accounts.destroy(principal, resourceIdSchema.parse(path.slice(`${userLifecyclePaths.invitations}/`.length)));
|
|
164
172
|
response.writeHead(204);
|
|
165
173
|
response.end();
|
|
166
174
|
}
|
|
@@ -168,53 +176,50 @@ export class IdentityController {
|
|
|
168
176
|
throw new IdentityError(405, "Method not allowed.");
|
|
169
177
|
return;
|
|
170
178
|
}
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
"settings",
|
|
174
|
-
"application-settings",
|
|
175
|
-
"security-settings",
|
|
176
|
-
].includes(path)) {
|
|
179
|
+
if (path === userLifecyclePaths.profile ||
|
|
180
|
+
settingsPaths.includes(path)) {
|
|
177
181
|
if (!["GET", "PATCH"].includes(request.method ?? ""))
|
|
178
182
|
throw new IdentityError(405, "Method not allowed.");
|
|
179
183
|
const input = request.method === "PATCH" ? await this.body(request) : undefined;
|
|
180
|
-
const data = path ===
|
|
181
|
-
? await this.administration.profile(principal, input)
|
|
182
|
-
: path ===
|
|
183
|
-
? await this.administration.
|
|
184
|
-
: await this.administration.
|
|
184
|
+
const data = path === userLifecyclePaths.profile
|
|
185
|
+
? await this.administration.userController.profile(principal, input)
|
|
186
|
+
: path === settingsPaths[2]
|
|
187
|
+
? await this.administration.settingsController.organization(principal, input)
|
|
188
|
+
: await this.administration.settingsController.application(principal, path === settingsPaths[4], input, this.config.sessionSeconds);
|
|
185
189
|
this.json(response, 200, { data });
|
|
186
190
|
return;
|
|
187
191
|
}
|
|
188
|
-
const
|
|
189
|
-
|
|
192
|
+
const [segment, encodedId, extra] = path.split("/");
|
|
193
|
+
const route = this.administration.routes.find(({ resource }) => resource === segment);
|
|
194
|
+
if (!route || extra)
|
|
190
195
|
throw new IdentityError(404, "Not found.");
|
|
191
|
-
const resource =
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
: undefined;
|
|
196
|
+
const resource = route.resource;
|
|
197
|
+
const controller = route.controller;
|
|
198
|
+
const id = encodedId ? resourceIdSchema.parse(decodeURIComponent(encodedId)) : undefined;
|
|
195
199
|
if (request.method === "GET") {
|
|
196
200
|
const query = resourceListQuerySchema.parse(Object.fromEntries(new URL(request.url, this.config.origin).searchParams));
|
|
197
201
|
this.json(response, 200, id
|
|
198
|
-
? { data: await this.
|
|
199
|
-
: this.wireList(await
|
|
202
|
+
? { data: await this.requireResult(controller.show(principal, id)) }
|
|
203
|
+
: this.wireList((await controller.index(principal, query))));
|
|
200
204
|
}
|
|
201
205
|
else if (request.method === "POST" && !id) {
|
|
202
206
|
this.json(response, 201, {
|
|
203
|
-
data: await this.
|
|
207
|
+
data: await this.requireAction(controller.store?.bind(controller), principal, await this.body(request))
|
|
204
208
|
});
|
|
205
209
|
}
|
|
206
210
|
else if (request.method === "PATCH" && id) {
|
|
207
211
|
this.json(response, 200, {
|
|
208
|
-
data: await this.
|
|
212
|
+
data: await this.requireUpdate(controller.update?.bind(controller), principal, id, await this.body(request))
|
|
209
213
|
});
|
|
210
214
|
}
|
|
211
215
|
else if (request.method === "DELETE" && id) {
|
|
212
216
|
const query = new URL(request.url, this.config.origin).searchParams;
|
|
213
217
|
const expectedVersion = resource === "memberships"
|
|
214
|
-
? membershipDeleteQuerySchema.parse(Object.fromEntries(query))
|
|
215
|
-
.expectedVersion
|
|
218
|
+
? membershipDeleteQuerySchema.parse(Object.fromEntries(query)).expectedVersion
|
|
216
219
|
: undefined;
|
|
217
|
-
|
|
220
|
+
if (!controller.destroy)
|
|
221
|
+
throw new IdentityError(405, "Deletion is not supported for this resource.");
|
|
222
|
+
await controller.destroy(principal, id, expectedVersion);
|
|
218
223
|
response.writeHead(204);
|
|
219
224
|
response.end();
|
|
220
225
|
}
|
|
@@ -228,10 +233,26 @@ export class IdentityController {
|
|
|
228
233
|
current_page: page.meta.page,
|
|
229
234
|
per_page: page.meta.perPage,
|
|
230
235
|
total: page.meta.total,
|
|
231
|
-
last_page: page.meta.lastPage
|
|
232
|
-
}
|
|
236
|
+
last_page: page.meta.lastPage
|
|
237
|
+
}
|
|
233
238
|
};
|
|
234
239
|
}
|
|
240
|
+
async requireResult(result) {
|
|
241
|
+
const value = await result;
|
|
242
|
+
if (!value)
|
|
243
|
+
throw new IdentityError(404, "Resource not found.");
|
|
244
|
+
return value;
|
|
245
|
+
}
|
|
246
|
+
requireAction(action, actor, raw) {
|
|
247
|
+
if (!action)
|
|
248
|
+
throw new IdentityError(405, "Creation is not supported for this resource.");
|
|
249
|
+
return action(actor, raw);
|
|
250
|
+
}
|
|
251
|
+
requireUpdate(action, actor, id, raw) {
|
|
252
|
+
if (!action)
|
|
253
|
+
throw new IdentityError(405, "Update is not supported for this resource.");
|
|
254
|
+
return action(actor, id, raw);
|
|
255
|
+
}
|
|
235
256
|
cookie(portal, token, age) {
|
|
236
257
|
return `${this.cookieName(portal)}=${token}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${age}${this.config.origin.startsWith("https:") ? "; Secure" : ""}`;
|
|
237
258
|
}
|
|
@@ -250,8 +271,7 @@ export class IdentityController {
|
|
|
250
271
|
response.end(JSON.stringify(body));
|
|
251
272
|
}
|
|
252
273
|
async body(request) {
|
|
253
|
-
if (request.headers["content-type"]?.split(";")[0].trim() !==
|
|
254
|
-
"application/json")
|
|
274
|
+
if (request.headers["content-type"]?.split(";")[0].trim() !== "application/json")
|
|
255
275
|
throw new IdentityError(415, "Use JSON request bodies.");
|
|
256
276
|
const chunks = [];
|
|
257
277
|
let size = 0;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const identityMigration: Migration;
|
|
1
|
+
export {};
|
|
@@ -1,79 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
async up(db) {
|
|
3
|
-
await db.schema
|
|
4
|
-
.createTable("identity_users")
|
|
5
|
-
.addColumn("id", "text", (c) => c.primaryKey())
|
|
6
|
-
.addColumn("email", "text", (c) => c.notNull().unique())
|
|
7
|
-
.addColumn("name", "text", (c) => c.notNull())
|
|
8
|
-
.addColumn("password_hash", "text", (c) => c.notNull())
|
|
9
|
-
.addColumn("active", "integer", (c) => c.notNull().defaultTo(1))
|
|
10
|
-
.execute();
|
|
11
|
-
await db.schema
|
|
12
|
-
.createTable("identity_tenants")
|
|
13
|
-
.addColumn("id", "text", (c) => c.primaryKey())
|
|
14
|
-
.addColumn("name", "text", (c) => c.notNull())
|
|
15
|
-
.addColumn("active", "integer", (c) => c.notNull().defaultTo(1))
|
|
16
|
-
.execute();
|
|
17
|
-
await db.schema
|
|
18
|
-
.createTable("identity_roles")
|
|
19
|
-
.addColumn("id", "text", (c) => c.primaryKey())
|
|
20
|
-
.execute();
|
|
21
|
-
await db.schema
|
|
22
|
-
.createTable("identity_permissions")
|
|
23
|
-
.addColumn("id", "text", (c) => c.primaryKey())
|
|
24
|
-
.execute();
|
|
25
|
-
await db.schema
|
|
26
|
-
.createTable("identity_role_permissions")
|
|
27
|
-
.addColumn("role_id", "text", (c) => c.notNull().references("identity_roles.id"))
|
|
28
|
-
.addColumn("permission_id", "text", (c) => c.notNull().references("identity_permissions.id"))
|
|
29
|
-
.addPrimaryKeyConstraint("identity_role_permission_pk", [
|
|
30
|
-
"role_id",
|
|
31
|
-
"permission_id",
|
|
32
|
-
])
|
|
33
|
-
.execute();
|
|
34
|
-
await db.schema
|
|
35
|
-
.createTable("identity_memberships")
|
|
36
|
-
.addColumn("user_id", "text", (c) => c.notNull().references("identity_users.id").onDelete("cascade"))
|
|
37
|
-
.addColumn("tenant_id", "text", (c) => c.notNull().references("identity_tenants.id").onDelete("cascade"))
|
|
38
|
-
.addColumn("role_id", "text", (c) => c.notNull().references("identity_roles.id"))
|
|
39
|
-
.addPrimaryKeyConstraint("identity_membership_pk", [
|
|
40
|
-
"user_id",
|
|
41
|
-
"tenant_id",
|
|
42
|
-
"role_id",
|
|
43
|
-
])
|
|
44
|
-
.execute();
|
|
45
|
-
await db.schema
|
|
46
|
-
.createTable("identity_sessions")
|
|
47
|
-
.addColumn("token_hash", "text", (c) => c.primaryKey())
|
|
48
|
-
.addColumn("user_id", "text", (c) => c.notNull().references("identity_users.id").onDelete("cascade"))
|
|
49
|
-
.addColumn("tenant_id", "text", (c) => c.notNull().references("identity_tenants.id").onDelete("cascade"))
|
|
50
|
-
.addColumn("app_id", "text", (c) => c.notNull())
|
|
51
|
-
.addColumn("portal", "text", (c) => c.notNull())
|
|
52
|
-
.addColumn("expires_at", "text", (c) => c.notNull())
|
|
53
|
-
.execute();
|
|
54
|
-
await db.schema
|
|
55
|
-
.createIndex("identity_sessions_expiry")
|
|
56
|
-
.on("identity_sessions")
|
|
57
|
-
.column("expires_at")
|
|
58
|
-
.execute();
|
|
59
|
-
await db.schema
|
|
60
|
-
.createTable("identity_throttles")
|
|
61
|
-
.addColumn("key", "text", (c) => c.primaryKey())
|
|
62
|
-
.addColumn("attempts", "integer", (c) => c.notNull())
|
|
63
|
-
.addColumn("expires_at", "text", (c) => c.notNull())
|
|
64
|
-
.execute();
|
|
65
|
-
},
|
|
66
|
-
async down(db) {
|
|
67
|
-
for (const table of [
|
|
68
|
-
"identity_throttles",
|
|
69
|
-
"identity_sessions",
|
|
70
|
-
"identity_memberships",
|
|
71
|
-
"identity_role_permissions",
|
|
72
|
-
"identity_permissions",
|
|
73
|
-
"identity_roles",
|
|
74
|
-
"identity_tenants",
|
|
75
|
-
"identity_users",
|
|
76
|
-
])
|
|
77
|
-
await db.schema.dropTable(table).execute();
|
|
78
|
-
},
|
|
79
|
-
};
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Kysely } from "kysely";
|
|
2
2
|
import type { IdentitySchema, IdentityProviderOptions } from "./identity.types.js";
|
|
3
|
-
import { type IdentityPermissionDeclaration } from "./
|
|
3
|
+
import { type IdentityPermissionDeclaration } from "./permission/index.js";
|
|
4
4
|
export declare function createIdentityProvider(database: Kysely<IdentitySchema>, environment: NodeJS.ProcessEnv, options?: IdentityProviderOptions): {
|
|
5
5
|
registerPermissions: (declaration: IdentityPermissionDeclaration) => Promise<{
|
|
6
6
|
owner: string;
|
|
@@ -11,7 +11,7 @@ export declare function createIdentityProvider(database: Kysely<IdentitySchema>,
|
|
|
11
11
|
authenticateRequest: (request: import("node:http").IncomingMessage, requestedPortal: import("./identity.types.js").Portal, signal?: AbortSignal) => Promise<import("./identity.types.js").Principal>;
|
|
12
12
|
requirePermission: (principal: import("./identity.types.js").Principal, permission: string) => void;
|
|
13
13
|
administration: {
|
|
14
|
-
list: (actor: import("./identity.types.js").Principal, resource: import("./
|
|
14
|
+
list: (actor: import("./identity.types.js").Principal, resource: import("./index.js").IdentityResource, query: import("./index.js").IdentityListQuery) => Promise<{
|
|
15
15
|
data: Record<string, unknown>[];
|
|
16
16
|
meta: {
|
|
17
17
|
page: number;
|
|
@@ -19,14 +19,35 @@ export declare function createIdentityProvider(database: Kysely<IdentitySchema>,
|
|
|
19
19
|
total: number;
|
|
20
20
|
lastPage: number;
|
|
21
21
|
};
|
|
22
|
+
} | {
|
|
23
|
+
data: {
|
|
24
|
+
portals: string[];
|
|
25
|
+
}[];
|
|
26
|
+
meta: {
|
|
27
|
+
page: number;
|
|
28
|
+
perPage: number;
|
|
29
|
+
total: number;
|
|
30
|
+
lastPage: number;
|
|
31
|
+
};
|
|
32
|
+
} | {
|
|
33
|
+
data: {
|
|
34
|
+
active: boolean;
|
|
35
|
+
version: number;
|
|
36
|
+
}[];
|
|
37
|
+
meta: {
|
|
38
|
+
page: number;
|
|
39
|
+
perPage: number;
|
|
40
|
+
total: number;
|
|
41
|
+
lastPage: number;
|
|
42
|
+
};
|
|
22
43
|
}>;
|
|
23
|
-
show: (actor: import("./identity.types.js").Principal, resource: import("./
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
name: string;
|
|
44
|
+
show: (actor: import("./identity.types.js").Principal, resource: import("./index.js").IdentityResource, id: string) => Promise<Record<string, unknown> | {
|
|
45
|
+
portals: string[];
|
|
46
|
+
} | {
|
|
27
47
|
active: boolean;
|
|
28
48
|
version: number;
|
|
29
|
-
}
|
|
49
|
+
}>;
|
|
50
|
+
create: (actor: import("./identity.types.js").Principal, resource: import("./index.js").IdentityResource, raw: unknown) => Promise<{
|
|
30
51
|
id: string;
|
|
31
52
|
userId: string;
|
|
32
53
|
tenantId: string;
|
|
@@ -34,8 +55,17 @@ export declare function createIdentityProvider(database: Kysely<IdentitySchema>,
|
|
|
34
55
|
portal: import("./identity.types.js").Portal;
|
|
35
56
|
active: boolean;
|
|
36
57
|
version: number;
|
|
58
|
+
} | {
|
|
59
|
+
id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
active: boolean;
|
|
62
|
+
version: number;
|
|
37
63
|
}>;
|
|
38
|
-
update: (actor: import("./identity.types.js").Principal, resource: import("./
|
|
64
|
+
update: (actor: import("./identity.types.js").Principal, resource: import("./index.js").IdentityResource, id: string, raw: unknown) => Promise<{
|
|
65
|
+
id: string;
|
|
66
|
+
permissionIds: string[];
|
|
67
|
+
version: number;
|
|
68
|
+
} | {
|
|
39
69
|
id: string;
|
|
40
70
|
userId: string;
|
|
41
71
|
tenantId: string;
|
|
@@ -48,12 +78,8 @@ export declare function createIdentityProvider(database: Kysely<IdentitySchema>,
|
|
|
48
78
|
version: number;
|
|
49
79
|
id: string;
|
|
50
80
|
name: string;
|
|
51
|
-
} | {
|
|
52
|
-
id: string;
|
|
53
|
-
permissionIds: string[];
|
|
54
|
-
version: number;
|
|
55
81
|
}>;
|
|
56
|
-
remove: (actor: import("./identity.types.js").Principal, resource: import("./
|
|
82
|
+
remove: (actor: import("./identity.types.js").Principal, resource: import("./index.js").IdentityResource, id: string, expectedVersion?: number) => Promise<void>;
|
|
57
83
|
profile: (actor: import("./identity.types.js").Principal, raw?: unknown) => Promise<{
|
|
58
84
|
active: boolean;
|
|
59
85
|
version: number;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
import { IdentityService } from "./identity.service.js";
|
|
2
|
+
import { createIdentityUserProvider } from "./user/index.js";
|
|
4
3
|
import { IdentityController } from "./identity.controller.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { registerIdentityPermissions } from "./identity.permission-declarations.js";
|
|
4
|
+
import { IdentityAdministrationComposition } from "./composition/identity.composition.js";
|
|
5
|
+
import { identityKeySchema } from "./user/index.js";
|
|
6
|
+
import { createIdentityPermissionProvider } from "./permission/index.js";
|
|
9
7
|
export function createIdentityProvider(database, environment, options = {}) {
|
|
10
8
|
const config = z
|
|
11
9
|
.object({
|
|
@@ -13,34 +11,35 @@ export function createIdentityProvider(database, environment, options = {}) {
|
|
|
13
11
|
origin: z.url(),
|
|
14
12
|
mode: z.enum(["single-client", "multi-tenant"]),
|
|
15
13
|
tenantId: identityKeySchema,
|
|
16
|
-
sessionSeconds: z.coerce.number().int().min(300).max(86400)
|
|
14
|
+
sessionSeconds: z.coerce.number().int().min(300).max(86400)
|
|
17
15
|
})
|
|
18
16
|
.parse({
|
|
19
17
|
appId: environment.APP_ID,
|
|
20
18
|
origin: environment.APP_URL,
|
|
21
19
|
mode: environment.IDENTITY_MODE ?? "single-client",
|
|
22
20
|
tenantId: environment.IDENTITY_TENANT_ID ?? "default",
|
|
23
|
-
sessionSeconds: environment.IDENTITY_SESSION_SECONDS ?? 28800
|
|
21
|
+
sessionSeconds: environment.IDENTITY_SESSION_SECONDS ?? 28800
|
|
24
22
|
});
|
|
25
23
|
const origin = new URL(config.origin);
|
|
26
|
-
if (origin.origin !== config.origin ||
|
|
27
|
-
!["http:", "https:"].includes(origin.protocol))
|
|
24
|
+
if (origin.origin !== config.origin || !["http:", "https:"].includes(origin.protocol))
|
|
28
25
|
throw new Error("Identity requires a valid application origin.");
|
|
29
26
|
if (origin.protocol !== "https:" &&
|
|
30
27
|
!["127.0.0.1", "localhost", "[::1]"].includes(origin.hostname))
|
|
31
28
|
throw new Error("Identity requires HTTPS outside loopback development.");
|
|
32
|
-
const
|
|
29
|
+
const permissions = createIdentityPermissionProvider(database);
|
|
33
30
|
const appName = z
|
|
34
31
|
.string()
|
|
35
32
|
.trim()
|
|
36
33
|
.min(1)
|
|
37
34
|
.max(100)
|
|
38
35
|
.parse(environment.APP_NAME || config.appId);
|
|
39
|
-
const administration = new
|
|
40
|
-
const
|
|
36
|
+
const administration = new IdentityAdministrationComposition(database, appName, permissions);
|
|
37
|
+
const user = createIdentityUserProvider(database, config, permissions, administration.userOwnership(), options);
|
|
38
|
+
const service = user.identity;
|
|
39
|
+
const lifecycle = user.lifecycle;
|
|
41
40
|
const controller = new IdentityController(service, config, administration, lifecycle);
|
|
42
41
|
return {
|
|
43
|
-
registerPermissions: (declaration) =>
|
|
42
|
+
registerPermissions: (declaration) => permissions.register(config.appId, declaration),
|
|
44
43
|
handle: controller.handle.bind(controller),
|
|
45
44
|
authenticate: service.authenticate.bind(service),
|
|
46
45
|
authenticateRequest: controller.authenticateRequest.bind(controller),
|
|
@@ -53,67 +52,14 @@ export function createIdentityProvider(database, environment, options = {}) {
|
|
|
53
52
|
remove: administration.remove.bind(administration),
|
|
54
53
|
profile: administration.profile.bind(administration),
|
|
55
54
|
settings: administration.settings.bind(administration),
|
|
56
|
-
presentation: administration.presentation.bind(administration)
|
|
55
|
+
presentation: administration.presentation.bind(administration)
|
|
57
56
|
},
|
|
58
57
|
async verify() {
|
|
59
|
-
await
|
|
58
|
+
await permissions.verify();
|
|
59
|
+
await user.verify();
|
|
60
|
+
await administration.verify();
|
|
60
61
|
for (const declaration of options.permissions ?? [])
|
|
61
|
-
await
|
|
62
|
-
|
|
63
|
-
.selectFrom("identity_roles")
|
|
64
|
-
.select("id")
|
|
65
|
-
.limit(1)
|
|
66
|
-
.execute();
|
|
67
|
-
await database
|
|
68
|
-
.selectFrom("identity_users")
|
|
69
|
-
.select("version")
|
|
70
|
-
.limit(1)
|
|
71
|
-
.execute();
|
|
72
|
-
await database
|
|
73
|
-
.selectFrom("identity_tenants")
|
|
74
|
-
.select("version")
|
|
75
|
-
.limit(1)
|
|
76
|
-
.execute();
|
|
77
|
-
await database
|
|
78
|
-
.selectFrom("identity_roles")
|
|
79
|
-
.select("version")
|
|
80
|
-
.limit(1)
|
|
81
|
-
.execute();
|
|
82
|
-
await database
|
|
83
|
-
.selectFrom("identity_settings")
|
|
84
|
-
.select("version")
|
|
85
|
-
.limit(1)
|
|
86
|
-
.execute();
|
|
87
|
-
await database
|
|
88
|
-
.selectFrom("identity_app_settings")
|
|
89
|
-
.select(["version", "session_seconds"])
|
|
90
|
-
.limit(1)
|
|
91
|
-
.execute();
|
|
92
|
-
await database
|
|
93
|
-
.selectFrom("identity_tokens")
|
|
94
|
-
.select(["delivered", "consumed_at"])
|
|
95
|
-
.limit(1)
|
|
96
|
-
.execute();
|
|
97
|
-
await database
|
|
98
|
-
.selectFrom("identity_audit_events")
|
|
99
|
-
.select("created_at")
|
|
100
|
-
.limit(1)
|
|
101
|
-
.execute();
|
|
102
|
-
await database
|
|
103
|
-
.selectFrom("identity_custom_roles")
|
|
104
|
-
.select(["app_id", "tenant_id", "version"])
|
|
105
|
-
.limit(1)
|
|
106
|
-
.execute();
|
|
107
|
-
await database
|
|
108
|
-
.selectFrom("identity_custom_role_permissions")
|
|
109
|
-
.select("permission_id")
|
|
110
|
-
.limit(1)
|
|
111
|
-
.execute();
|
|
112
|
-
await database
|
|
113
|
-
.selectFrom("identity_memberships")
|
|
114
|
-
.select(["custom_role_id", "active", "version"])
|
|
115
|
-
.limit(1)
|
|
116
|
-
.execute();
|
|
117
|
-
},
|
|
62
|
+
await permissions.register(config.appId, declaration);
|
|
63
|
+
}
|
|
118
64
|
};
|
|
119
65
|
}
|