gdc-common-utils-ts 2.5.3 → 2.5.4
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/dist/constants/device.d.ts +6 -0
- package/dist/constants/device.js +5 -0
- package/dist/constants/employee-lifecycle.d.ts +52 -0
- package/dist/constants/employee-lifecycle.js +48 -0
- package/dist/constants/http.d.ts +28 -0
- package/dist/constants/http.js +28 -0
- package/dist/constants/identity-auth.d.ts +57 -0
- package/dist/constants/identity-auth.js +57 -0
- package/dist/constants/index.d.ts +4 -0
- package/dist/constants/index.js +4 -0
- package/dist/constants/organization-application.d.ts +27 -0
- package/dist/constants/organization-application.js +29 -0
- package/dist/examples/license.d.ts +111 -0
- package/dist/examples/license.js +85 -2
- package/dist/examples/shared.d.ts +33 -0
- package/dist/examples/shared.js +32 -0
- package/dist/models/device-license.d.ts +2 -2
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.js +1 -0
- package/dist/models/organization-employee-lifecycle.d.ts +45 -0
- package/dist/models/organization-employee-lifecycle.js +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/jwk-thumbprint.d.ts +2 -0
- package/dist/utils/jwk-thumbprint.js +8 -0
- package/dist/utils/license.js +3 -3
- package/dist/utils/organization-employee-lifecycle.d.ts +12 -0
- package/dist/utils/organization-employee-lifecycle.js +125 -0
- package/package.json +1 -1
|
@@ -14,3 +14,9 @@ export declare const DeviceAppTypes: Readonly<{
|
|
|
14
14
|
readonly Web: "web";
|
|
15
15
|
}>;
|
|
16
16
|
export type DeviceAppType = typeof DeviceAppTypes[keyof typeof DeviceAppTypes];
|
|
17
|
+
/** Lifecycle states for one concrete DCR installation bound to a seat. */
|
|
18
|
+
export declare const DeviceBindingStatuses: Readonly<{
|
|
19
|
+
readonly Active: "active";
|
|
20
|
+
readonly Revoked: "revoked";
|
|
21
|
+
}>;
|
|
22
|
+
export type DeviceBindingStatus = typeof DeviceBindingStatuses[keyof typeof DeviceBindingStatuses];
|
package/dist/constants/device.js
CHANGED
|
@@ -13,3 +13,8 @@ export const DeviceAppTypes = Object.freeze({
|
|
|
13
13
|
Mobile: 'mobile',
|
|
14
14
|
Web: 'web',
|
|
15
15
|
});
|
|
16
|
+
/** Lifecycle states for one concrete DCR installation bound to a seat. */
|
|
17
|
+
export const DeviceBindingStatuses = Object.freeze({
|
|
18
|
+
Active: 'active',
|
|
19
|
+
Revoked: 'revoked',
|
|
20
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Employee directory states exposed by organization lifecycle projections. */
|
|
2
|
+
export declare const EmployeeDirectoryStatuses: Readonly<{
|
|
3
|
+
readonly Active: "active";
|
|
4
|
+
readonly Inactive: "inactive";
|
|
5
|
+
readonly Purged: "purged";
|
|
6
|
+
readonly Unknown: "unknown";
|
|
7
|
+
}>;
|
|
8
|
+
export type EmployeeDirectoryStatus = typeof EmployeeDirectoryStatuses[keyof typeof EmployeeDirectoryStatuses];
|
|
9
|
+
/** Controller actions supported by the reusable employee lifecycle service. */
|
|
10
|
+
export declare const EmployeeLifecycleActions: Readonly<{
|
|
11
|
+
readonly Disable: "disable";
|
|
12
|
+
readonly Purge: "purge";
|
|
13
|
+
readonly RevokeDevice: "revoke_device";
|
|
14
|
+
}>;
|
|
15
|
+
/** Read-only API actions kept separate from mutating employee lifecycle actions. */
|
|
16
|
+
export declare const EmployeeLifecycleQueryActions: Readonly<{
|
|
17
|
+
readonly List: "list";
|
|
18
|
+
}>;
|
|
19
|
+
export type EmployeeLifecycleAction = typeof EmployeeLifecycleActions[keyof typeof EmployeeLifecycleActions];
|
|
20
|
+
/** Version tag for routing metadata stored outside the high-entropy GW credential. */
|
|
21
|
+
export declare const EmployeeActivationGrantVersions: Readonly<{
|
|
22
|
+
readonly V1: "employee-activation-grant-v1";
|
|
23
|
+
}>;
|
|
24
|
+
/** Supported durable routing-grant schema versions. */
|
|
25
|
+
export type EmployeeActivationGrantVersion = typeof EmployeeActivationGrantVersions[keyof typeof EmployeeActivationGrantVersions];
|
|
26
|
+
/** Shared durable-storage layout for hashed employee activation routing grants. */
|
|
27
|
+
export declare const EmployeeActivationGrantStorage: Readonly<{
|
|
28
|
+
readonly ScopedLayout: "scoped-v2";
|
|
29
|
+
readonly CollectionSegment: "employee-activation-grants";
|
|
30
|
+
readonly ScopeSeparator: "__";
|
|
31
|
+
readonly DefaultTtlMs: number;
|
|
32
|
+
}>;
|
|
33
|
+
/** JSON field names shared by employee lifecycle portal adapters. */
|
|
34
|
+
export declare const OrganizationEmployeeApiFields: Readonly<{
|
|
35
|
+
readonly Action: "action";
|
|
36
|
+
readonly ProfileId: "profileId";
|
|
37
|
+
readonly Pin: "pin";
|
|
38
|
+
readonly PasskeyAccessToken: "passkeyAccessToken";
|
|
39
|
+
readonly ResourceId: "resourceId";
|
|
40
|
+
readonly LicenseId: "licenseId";
|
|
41
|
+
readonly ClientId: "clientId";
|
|
42
|
+
readonly ActivationCode: "activationCode";
|
|
43
|
+
readonly ClientInstanceId: "clientInstanceId";
|
|
44
|
+
readonly Email: "email";
|
|
45
|
+
readonly Role: "role";
|
|
46
|
+
}>;
|
|
47
|
+
/** Stable employee portal error identifiers. */
|
|
48
|
+
export declare const OrganizationEmployeePortalErrors: Readonly<{
|
|
49
|
+
readonly InvitationFailed: "invitation_failed";
|
|
50
|
+
readonly LifecycleFailed: "employee_lifecycle_failed";
|
|
51
|
+
readonly ActivationFailed: "employee_activation_failed";
|
|
52
|
+
}>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Employee directory states exposed by organization lifecycle projections. */
|
|
2
|
+
export const EmployeeDirectoryStatuses = Object.freeze({
|
|
3
|
+
Active: 'active',
|
|
4
|
+
Inactive: 'inactive',
|
|
5
|
+
Purged: 'purged',
|
|
6
|
+
Unknown: 'unknown',
|
|
7
|
+
});
|
|
8
|
+
/** Controller actions supported by the reusable employee lifecycle service. */
|
|
9
|
+
export const EmployeeLifecycleActions = Object.freeze({
|
|
10
|
+
Disable: 'disable',
|
|
11
|
+
Purge: 'purge',
|
|
12
|
+
RevokeDevice: 'revoke_device',
|
|
13
|
+
});
|
|
14
|
+
/** Read-only API actions kept separate from mutating employee lifecycle actions. */
|
|
15
|
+
export const EmployeeLifecycleQueryActions = Object.freeze({
|
|
16
|
+
List: 'list',
|
|
17
|
+
});
|
|
18
|
+
/** Version tag for routing metadata stored outside the high-entropy GW credential. */
|
|
19
|
+
export const EmployeeActivationGrantVersions = Object.freeze({
|
|
20
|
+
V1: 'employee-activation-grant-v1',
|
|
21
|
+
});
|
|
22
|
+
/** Shared durable-storage layout for hashed employee activation routing grants. */
|
|
23
|
+
export const EmployeeActivationGrantStorage = Object.freeze({
|
|
24
|
+
ScopedLayout: 'scoped-v2',
|
|
25
|
+
CollectionSegment: 'employee-activation-grants',
|
|
26
|
+
ScopeSeparator: '__',
|
|
27
|
+
DefaultTtlMs: 365 * 24 * 60 * 60 * 1_000,
|
|
28
|
+
});
|
|
29
|
+
/** JSON field names shared by employee lifecycle portal adapters. */
|
|
30
|
+
export const OrganizationEmployeeApiFields = Object.freeze({
|
|
31
|
+
Action: 'action',
|
|
32
|
+
ProfileId: 'profileId',
|
|
33
|
+
Pin: 'pin',
|
|
34
|
+
PasskeyAccessToken: 'passkeyAccessToken',
|
|
35
|
+
ResourceId: 'resourceId',
|
|
36
|
+
LicenseId: 'licenseId',
|
|
37
|
+
ClientId: 'clientId',
|
|
38
|
+
ActivationCode: 'activationCode',
|
|
39
|
+
ClientInstanceId: 'clientInstanceId',
|
|
40
|
+
Email: 'email',
|
|
41
|
+
Role: 'role',
|
|
42
|
+
});
|
|
43
|
+
/** Stable employee portal error identifiers. */
|
|
44
|
+
export const OrganizationEmployeePortalErrors = Object.freeze({
|
|
45
|
+
InvitationFailed: 'invitation_failed',
|
|
46
|
+
LifecycleFailed: 'employee_lifecycle_failed',
|
|
47
|
+
ActivationFailed: 'employee_activation_failed',
|
|
48
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Numeric HTTP status values shared by route adapters and tests. */
|
|
2
|
+
export declare const HttpStatusCodes: Readonly<{
|
|
3
|
+
readonly Ok: 200;
|
|
4
|
+
readonly Created: 201;
|
|
5
|
+
readonly BadRequest: 400;
|
|
6
|
+
readonly Unauthorized: 401;
|
|
7
|
+
readonly Forbidden: 403;
|
|
8
|
+
readonly NotFound: 404;
|
|
9
|
+
readonly Conflict: 409;
|
|
10
|
+
readonly Gone: 410;
|
|
11
|
+
readonly InternalServerError: 500;
|
|
12
|
+
readonly ServiceUnavailable: 503;
|
|
13
|
+
}>;
|
|
14
|
+
/** HTTP methods used by SDK and portal request builders. */
|
|
15
|
+
export declare const HttpRequestMethods: Readonly<{
|
|
16
|
+
readonly Get: "GET";
|
|
17
|
+
readonly Post: "POST";
|
|
18
|
+
readonly Patch: "PATCH";
|
|
19
|
+
}>;
|
|
20
|
+
/** Canonical HTTP header names. */
|
|
21
|
+
export declare const HttpHeaderNames: Readonly<{
|
|
22
|
+
readonly Authorization: "authorization";
|
|
23
|
+
readonly ContentType: "content-type";
|
|
24
|
+
}>;
|
|
25
|
+
/** Media types shared by JSON route adapters. */
|
|
26
|
+
export declare const HttpMediaTypes: Readonly<{
|
|
27
|
+
readonly Json: "application/json";
|
|
28
|
+
}>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Numeric HTTP status values shared by route adapters and tests. */
|
|
2
|
+
export const HttpStatusCodes = Object.freeze({
|
|
3
|
+
Ok: 200,
|
|
4
|
+
Created: 201,
|
|
5
|
+
BadRequest: 400,
|
|
6
|
+
Unauthorized: 401,
|
|
7
|
+
Forbidden: 403,
|
|
8
|
+
NotFound: 404,
|
|
9
|
+
Conflict: 409,
|
|
10
|
+
Gone: 410,
|
|
11
|
+
InternalServerError: 500,
|
|
12
|
+
ServiceUnavailable: 503,
|
|
13
|
+
});
|
|
14
|
+
/** HTTP methods used by SDK and portal request builders. */
|
|
15
|
+
export const HttpRequestMethods = Object.freeze({
|
|
16
|
+
Get: 'GET',
|
|
17
|
+
Post: 'POST',
|
|
18
|
+
Patch: 'PATCH',
|
|
19
|
+
});
|
|
20
|
+
/** Canonical HTTP header names. */
|
|
21
|
+
export const HttpHeaderNames = Object.freeze({
|
|
22
|
+
Authorization: 'authorization',
|
|
23
|
+
ContentType: 'content-type',
|
|
24
|
+
});
|
|
25
|
+
/** Media types shared by JSON route adapters. */
|
|
26
|
+
export const HttpMediaTypes = Object.freeze({
|
|
27
|
+
Json: 'application/json',
|
|
28
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Canonical identity/auth route actions shared by gateways, SDKs and portals. */
|
|
2
|
+
export declare const IdentityAuthActions: Readonly<{
|
|
3
|
+
readonly Exchange: "_exchange";
|
|
4
|
+
readonly ExchangeResponse: "_exchange-response";
|
|
5
|
+
readonly Dcr: "_dcr";
|
|
6
|
+
readonly DcrResponse: "_dcr-response";
|
|
7
|
+
readonly Issue: "_issue";
|
|
8
|
+
readonly IssueResponse: "_issue-response";
|
|
9
|
+
readonly Revoke: "_revoke";
|
|
10
|
+
readonly RevokeResponse: "_revoke-response";
|
|
11
|
+
readonly Search: "_search";
|
|
12
|
+
readonly SearchResponse: "_search-response";
|
|
13
|
+
}>;
|
|
14
|
+
/** Canonical identity/auth route segments shared by all products. */
|
|
15
|
+
export declare const IdentityAuthRouteSegments: Readonly<{
|
|
16
|
+
readonly Host: "host";
|
|
17
|
+
readonly Version: "v1";
|
|
18
|
+
readonly Section: "identity";
|
|
19
|
+
readonly Format: "auth";
|
|
20
|
+
}>;
|
|
21
|
+
/** Wire-level request keys used by identity/auth operations. */
|
|
22
|
+
export declare const IdentityAuthRequestFields: Readonly<{
|
|
23
|
+
readonly SubjectToken: "subject_token";
|
|
24
|
+
readonly ClientInstanceId: "client_instance_id";
|
|
25
|
+
readonly LicenseId: "license_id";
|
|
26
|
+
readonly ClientId: "client_id";
|
|
27
|
+
readonly Code: "code";
|
|
28
|
+
}>;
|
|
29
|
+
/** Response keys accepted from token exchange during the compatibility window. */
|
|
30
|
+
export declare const IdentityAuthResponseFields: Readonly<{
|
|
31
|
+
readonly InitialAccessToken: "initial_access_token";
|
|
32
|
+
readonly AccessToken: "access_token";
|
|
33
|
+
}>;
|
|
34
|
+
/** DCR metadata keys used to derive and register one installation identity. */
|
|
35
|
+
export declare const IdentityDcrMetadataFields: Readonly<{
|
|
36
|
+
readonly ExtendedDeviceInfo: "ext_device_info";
|
|
37
|
+
readonly RedirectUris: "redirect_uris";
|
|
38
|
+
readonly Jwks: "jwks";
|
|
39
|
+
readonly SoftwareId: "software_id";
|
|
40
|
+
readonly ApplicationType: "application_type";
|
|
41
|
+
readonly ClientName: "client_name";
|
|
42
|
+
readonly ActorDid: "actor_did";
|
|
43
|
+
readonly ProfileDid: "profile_did";
|
|
44
|
+
}>;
|
|
45
|
+
/** Device metadata keys nested below `ext_device_info`. */
|
|
46
|
+
export declare const IdentityDeviceInfoFields: Readonly<{
|
|
47
|
+
readonly DeviceId: "device_id";
|
|
48
|
+
}>;
|
|
49
|
+
/** Stable entry type emitted by license issuance responses. */
|
|
50
|
+
export declare const IdentityAuthResponseEntryTypes: Readonly<{
|
|
51
|
+
readonly LicenseIssued: "License:Issued";
|
|
52
|
+
readonly DeviceRevoked: "Device:Revoked";
|
|
53
|
+
}>;
|
|
54
|
+
/** DIDComm response type values emitted by identity/auth managers. */
|
|
55
|
+
export declare const IdentityAuthResponseTypes: Readonly<{
|
|
56
|
+
readonly DeviceRevoke: "device-revoke-response";
|
|
57
|
+
}>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Canonical identity/auth route actions shared by gateways, SDKs and portals. */
|
|
2
|
+
export const IdentityAuthActions = Object.freeze({
|
|
3
|
+
Exchange: '_exchange',
|
|
4
|
+
ExchangeResponse: '_exchange-response',
|
|
5
|
+
Dcr: '_dcr',
|
|
6
|
+
DcrResponse: '_dcr-response',
|
|
7
|
+
Issue: '_issue',
|
|
8
|
+
IssueResponse: '_issue-response',
|
|
9
|
+
Revoke: '_revoke',
|
|
10
|
+
RevokeResponse: '_revoke-response',
|
|
11
|
+
Search: '_search',
|
|
12
|
+
SearchResponse: '_search-response',
|
|
13
|
+
});
|
|
14
|
+
/** Canonical identity/auth route segments shared by all products. */
|
|
15
|
+
export const IdentityAuthRouteSegments = Object.freeze({
|
|
16
|
+
Host: 'host',
|
|
17
|
+
Version: 'v1',
|
|
18
|
+
Section: 'identity',
|
|
19
|
+
Format: 'auth',
|
|
20
|
+
});
|
|
21
|
+
/** Wire-level request keys used by identity/auth operations. */
|
|
22
|
+
export const IdentityAuthRequestFields = Object.freeze({
|
|
23
|
+
SubjectToken: 'subject_token',
|
|
24
|
+
ClientInstanceId: 'client_instance_id',
|
|
25
|
+
LicenseId: 'license_id',
|
|
26
|
+
ClientId: 'client_id',
|
|
27
|
+
Code: 'code',
|
|
28
|
+
});
|
|
29
|
+
/** Response keys accepted from token exchange during the compatibility window. */
|
|
30
|
+
export const IdentityAuthResponseFields = Object.freeze({
|
|
31
|
+
InitialAccessToken: 'initial_access_token',
|
|
32
|
+
AccessToken: 'access_token',
|
|
33
|
+
});
|
|
34
|
+
/** DCR metadata keys used to derive and register one installation identity. */
|
|
35
|
+
export const IdentityDcrMetadataFields = Object.freeze({
|
|
36
|
+
ExtendedDeviceInfo: 'ext_device_info',
|
|
37
|
+
RedirectUris: 'redirect_uris',
|
|
38
|
+
Jwks: 'jwks',
|
|
39
|
+
SoftwareId: 'software_id',
|
|
40
|
+
ApplicationType: 'application_type',
|
|
41
|
+
ClientName: 'client_name',
|
|
42
|
+
ActorDid: 'actor_did',
|
|
43
|
+
ProfileDid: 'profile_did',
|
|
44
|
+
});
|
|
45
|
+
/** Device metadata keys nested below `ext_device_info`. */
|
|
46
|
+
export const IdentityDeviceInfoFields = Object.freeze({
|
|
47
|
+
DeviceId: 'device_id',
|
|
48
|
+
});
|
|
49
|
+
/** Stable entry type emitted by license issuance responses. */
|
|
50
|
+
export const IdentityAuthResponseEntryTypes = Object.freeze({
|
|
51
|
+
LicenseIssued: 'License:Issued',
|
|
52
|
+
DeviceRevoked: 'Device:Revoked',
|
|
53
|
+
});
|
|
54
|
+
/** DIDComm response type values emitted by identity/auth managers. */
|
|
55
|
+
export const IdentityAuthResponseTypes = Object.freeze({
|
|
56
|
+
DeviceRevoke: 'device-revoke-response',
|
|
57
|
+
});
|
|
@@ -8,6 +8,10 @@ export * from './dataspace-discovery';
|
|
|
8
8
|
export * from './dataspace-protocol';
|
|
9
9
|
export * from './didcomm';
|
|
10
10
|
export * from './device';
|
|
11
|
+
export * from './employee-lifecycle';
|
|
12
|
+
export * from './identity-auth';
|
|
13
|
+
export * from './http';
|
|
14
|
+
export * from './organization-application';
|
|
11
15
|
export * from './did-services';
|
|
12
16
|
export * from './eu-countries';
|
|
13
17
|
export * from './fhir-code-systems';
|
package/dist/constants/index.js
CHANGED
|
@@ -8,6 +8,10 @@ export * from './dataspace-discovery.js';
|
|
|
8
8
|
export * from './dataspace-protocol.js';
|
|
9
9
|
export * from './didcomm.js';
|
|
10
10
|
export * from './device.js';
|
|
11
|
+
export * from './employee-lifecycle.js';
|
|
12
|
+
export * from './identity-auth.js';
|
|
13
|
+
export * from './http.js';
|
|
14
|
+
export * from './organization-application.js';
|
|
11
15
|
export * from './did-services.js';
|
|
12
16
|
export * from './eu-countries.js';
|
|
13
17
|
export * from './fhir-code-systems.js';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Actions accepted by the reusable organization-registration review route. */
|
|
2
|
+
export declare const OrganizationRegistrationReviewActions: Readonly<{
|
|
3
|
+
readonly MarkPostalDelivered: "mark_postal_delivered";
|
|
4
|
+
readonly IssuePostalLicense: "issue_postal_license";
|
|
5
|
+
readonly DownloadDraft: "download_draft";
|
|
6
|
+
readonly Authorize: "authorize";
|
|
7
|
+
readonly Reject: "reject";
|
|
8
|
+
}>;
|
|
9
|
+
export type OrganizationRegistrationReviewAction = typeof OrganizationRegistrationReviewActions[keyof typeof OrganizationRegistrationReviewActions];
|
|
10
|
+
/** Narrows untrusted request input to one supported review action. */
|
|
11
|
+
export declare function isOrganizationRegistrationReviewAction(value: unknown): value is OrganizationRegistrationReviewAction;
|
|
12
|
+
/** Stable error identifiers shared by route handlers, services and tests. */
|
|
13
|
+
export declare const OrganizationRegistrationErrors: Readonly<{
|
|
14
|
+
readonly InvalidReviewAction: "invalid_review_action";
|
|
15
|
+
readonly ApplicationNotReviewable: "application_not_reviewable";
|
|
16
|
+
readonly AuthorizationCredentialRequired: "organization_authorization_credential_required";
|
|
17
|
+
readonly ReviewFailed: "review_failed";
|
|
18
|
+
readonly InvalidOrganization: "invalid_organization";
|
|
19
|
+
readonly ApplicationFailed: "application_failed";
|
|
20
|
+
}>;
|
|
21
|
+
/** Default and accepted authorization validity window for registration evidence. */
|
|
22
|
+
export declare const OrganizationRegistrationValidity: Readonly<{
|
|
23
|
+
readonly DefaultDays: 180;
|
|
24
|
+
readonly MinimumDays: 1;
|
|
25
|
+
readonly MaximumDays: 730;
|
|
26
|
+
readonly MillisecondsPerDay: 86400000;
|
|
27
|
+
}>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Actions accepted by the reusable organization-registration review route. */
|
|
2
|
+
export const OrganizationRegistrationReviewActions = Object.freeze({
|
|
3
|
+
MarkPostalDelivered: 'mark_postal_delivered',
|
|
4
|
+
IssuePostalLicense: 'issue_postal_license',
|
|
5
|
+
DownloadDraft: 'download_draft',
|
|
6
|
+
Authorize: 'authorize',
|
|
7
|
+
Reject: 'reject',
|
|
8
|
+
});
|
|
9
|
+
/** Narrows untrusted request input to one supported review action. */
|
|
10
|
+
export function isOrganizationRegistrationReviewAction(value) {
|
|
11
|
+
return typeof value === 'string'
|
|
12
|
+
&& Object.values(OrganizationRegistrationReviewActions).includes(value);
|
|
13
|
+
}
|
|
14
|
+
/** Stable error identifiers shared by route handlers, services and tests. */
|
|
15
|
+
export const OrganizationRegistrationErrors = Object.freeze({
|
|
16
|
+
InvalidReviewAction: 'invalid_review_action',
|
|
17
|
+
ApplicationNotReviewable: 'application_not_reviewable',
|
|
18
|
+
AuthorizationCredentialRequired: 'organization_authorization_credential_required',
|
|
19
|
+
ReviewFailed: 'review_failed',
|
|
20
|
+
InvalidOrganization: 'invalid_organization',
|
|
21
|
+
ApplicationFailed: 'application_failed',
|
|
22
|
+
});
|
|
23
|
+
/** Default and accepted authorization validity window for registration evidence. */
|
|
24
|
+
export const OrganizationRegistrationValidity = Object.freeze({
|
|
25
|
+
DefaultDays: 180,
|
|
26
|
+
MinimumDays: 1,
|
|
27
|
+
MaximumDays: 730,
|
|
28
|
+
MillisecondsPerDay: 86_400_000,
|
|
29
|
+
});
|
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
export declare const EXAMPLE_EMPLOYEE_DEVICE_BINDINGS: readonly [Readonly<{
|
|
2
|
+
clientId: "client-employee-primary";
|
|
3
|
+
clientInstanceId: "installation-employee-primary";
|
|
4
|
+
status: "active";
|
|
5
|
+
deviceInfo: Readonly<{
|
|
6
|
+
clientInstanceId: "installation-employee-primary";
|
|
7
|
+
model: "Shared browser profile";
|
|
8
|
+
}>;
|
|
9
|
+
activatedAt: 1786570800;
|
|
10
|
+
}>, Readonly<{
|
|
11
|
+
clientId: "client-employee-secondary";
|
|
12
|
+
clientInstanceId: "installation-employee-secondary";
|
|
13
|
+
status: "revoked";
|
|
14
|
+
deviceInfo: Readonly<{
|
|
15
|
+
clientInstanceId: "installation-employee-secondary";
|
|
16
|
+
}>;
|
|
17
|
+
activatedAt: 1786570900;
|
|
18
|
+
revokedAt: 1786571000;
|
|
19
|
+
}>];
|
|
20
|
+
/** Two simultaneously active installations used to test the default allowance. */
|
|
21
|
+
export declare const EXAMPLE_EMPLOYEE_ACTIVE_DEVICE_BINDINGS: readonly Readonly<{
|
|
22
|
+
status: "active";
|
|
23
|
+
revokedAt: undefined;
|
|
24
|
+
clientId: "client-employee-primary";
|
|
25
|
+
clientInstanceId: "installation-employee-primary";
|
|
26
|
+
deviceInfo: Readonly<{
|
|
27
|
+
clientInstanceId: "installation-employee-primary";
|
|
28
|
+
model: "Shared browser profile";
|
|
29
|
+
}>;
|
|
30
|
+
activatedAt: 1786570800;
|
|
31
|
+
} | {
|
|
32
|
+
status: "active";
|
|
33
|
+
revokedAt: undefined;
|
|
34
|
+
clientId: "client-employee-secondary";
|
|
35
|
+
clientInstanceId: "installation-employee-secondary";
|
|
36
|
+
deviceInfo: Readonly<{
|
|
37
|
+
clientInstanceId: "installation-employee-secondary";
|
|
38
|
+
}>;
|
|
39
|
+
activatedAt: 1786570900;
|
|
40
|
+
}>[];
|
|
1
41
|
export declare const EXAMPLE_LICENSE_SEAT_UUIDS: readonly ["8a8a5e1b-0d8e-4a7c-8c39-3b8034440001", "8a8a5e1b-0d8e-4a7c-8c39-3b8034440002"];
|
|
2
42
|
export declare const EXAMPLE_LICENSE_ISSUE_INPUT: Readonly<{
|
|
3
43
|
readonly email: "controller@acme.org";
|
|
@@ -67,6 +107,77 @@ export declare const EXAMPLE_LICENSE_LIST_RESPONSE_BODY: Readonly<{
|
|
|
67
107
|
};
|
|
68
108
|
}];
|
|
69
109
|
}>;
|
|
110
|
+
/** Shared async GW response for a controller-issued employee activation credential. */
|
|
111
|
+
export declare const EXAMPLE_LICENSE_ISSUE_RESPONSE_BODY: Readonly<{
|
|
112
|
+
readonly body: {
|
|
113
|
+
readonly data: readonly [{
|
|
114
|
+
readonly resource: {
|
|
115
|
+
readonly data: readonly [{
|
|
116
|
+
readonly type: "License:Issued";
|
|
117
|
+
readonly id: "ACT-001";
|
|
118
|
+
readonly meta: {
|
|
119
|
+
readonly claims: {
|
|
120
|
+
readonly "org.schema.IndividualProduct.serialNumber": "ACT-001";
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
}];
|
|
124
|
+
};
|
|
125
|
+
}];
|
|
126
|
+
};
|
|
127
|
+
}>;
|
|
128
|
+
/** Shared license search response containing the default two-installation state. */
|
|
129
|
+
export declare const EXAMPLE_LICENSE_LIST_RESPONSE_BODY_WITH_DEVICES: Readonly<{
|
|
130
|
+
readonly body: {
|
|
131
|
+
readonly resource: {
|
|
132
|
+
readonly data: readonly [{
|
|
133
|
+
readonly id: "8a8a5e1b-0d8e-4a7c-8c39-3b8034440001";
|
|
134
|
+
readonly meta: {
|
|
135
|
+
readonly status: "active";
|
|
136
|
+
readonly subjectId: string;
|
|
137
|
+
readonly maxDevices: 2;
|
|
138
|
+
readonly deviceBindings: readonly [Readonly<{
|
|
139
|
+
clientId: "client-employee-primary";
|
|
140
|
+
clientInstanceId: "installation-employee-primary";
|
|
141
|
+
status: "active";
|
|
142
|
+
deviceInfo: Readonly<{
|
|
143
|
+
clientInstanceId: "installation-employee-primary";
|
|
144
|
+
model: "Shared browser profile";
|
|
145
|
+
}>;
|
|
146
|
+
activatedAt: 1786570800;
|
|
147
|
+
}>, Readonly<{
|
|
148
|
+
clientId: "client-employee-secondary";
|
|
149
|
+
clientInstanceId: "installation-employee-secondary";
|
|
150
|
+
status: "revoked";
|
|
151
|
+
deviceInfo: Readonly<{
|
|
152
|
+
clientInstanceId: "installation-employee-secondary";
|
|
153
|
+
}>;
|
|
154
|
+
activatedAt: 1786570900;
|
|
155
|
+
revokedAt: 1786571000;
|
|
156
|
+
}>];
|
|
157
|
+
};
|
|
158
|
+
}];
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
}>;
|
|
162
|
+
/** Canonical controller-facing employee projection reused across SDK and portal tests. */
|
|
163
|
+
export declare const EXAMPLE_EMPLOYEE_LIFECYCLE_RECORD: Readonly<{
|
|
164
|
+
readonly resourceId: string;
|
|
165
|
+
readonly email: string;
|
|
166
|
+
readonly roleCode: string;
|
|
167
|
+
readonly employeeDid: string;
|
|
168
|
+
readonly status: "active" | "inactive" | "purged";
|
|
169
|
+
readonly license: Readonly<{
|
|
170
|
+
id: "8a8a5e1b-0d8e-4a7c-8c39-3b8034440001";
|
|
171
|
+
status: "active";
|
|
172
|
+
maxDevices: 2;
|
|
173
|
+
activeDevices: number;
|
|
174
|
+
devices: readonly Readonly<{
|
|
175
|
+
clientId: "client-employee-primary" | "client-employee-secondary";
|
|
176
|
+
name: "installation-employee-primary" | "installation-employee-secondary" | "Shared browser profile";
|
|
177
|
+
status: "active" | "revoked";
|
|
178
|
+
}>[];
|
|
179
|
+
}>;
|
|
180
|
+
}>;
|
|
70
181
|
export declare function buildExampleLicenseIssueClaims(): Readonly<Record<string, unknown>>;
|
|
71
182
|
export declare function buildExampleLicensePurchaseClaims(): Readonly<Record<string, unknown>>;
|
|
72
183
|
export declare const EXAMPLE_LICENSE_PURCHASE_CLAIMS: Readonly<Record<string, unknown>>;
|
package/dist/examples/license.js
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
|
-
import { DeviceAppTypes, DeviceUserClasses } from '../constants/device.js';
|
|
1
|
+
import { DeviceAppTypes, DeviceBindingStatuses, DeviceUserClasses } from '../constants/device.js';
|
|
2
2
|
import { ClaimsOrderSchemaorg, ClaimsIndividualProductSchemaorg, ClaimsOfferSchemaorg, ClaimsPersonSchemaorg, } from '../constants/schemaorg.js';
|
|
3
3
|
import { buildLicenseIssueClaims, buildLicensePurchaseClaims, LicenseClaimContext, LicenseCategories, LicenseStatuses, } from '../utils/license.js';
|
|
4
4
|
import { createLicenseOfferOrderEditor } from '../utils/license-offer-order.js';
|
|
5
|
-
import { EXAMPLE_LICENSE_ACCEPTED_OFFER_ID, EXAMPLE_LICENSE_AMOUNT, EXAMPLE_LICENSE_CHECKOUT_URL, EXAMPLE_LICENSE_CURRENCY, EXAMPLE_EMAIL_CONTROLLER_ORG, EXAMPLE_EMPLOYEE_ACTIVATION_CODE, EXAMPLE_HEALTHCARE_ACTOR_ROLE_GENERALIST_MEDICAL_PRACTITIONER, EXAMPLE_LICENSE_INVOICE_ID, EXAMPLE_LICENSE_OFFER_ID, EXAMPLE_LICENSE_PLAN_DEFAULT, EXAMPLE_LICENSE_PAYMENT_METHOD_INVOICE, EXAMPLE_LICENSE_PAYMENT_URL, EXAMPLE_LICENSE_RENEWAL_CYCLE_YEARLY, EXAMPLE_LICENSE_PLAN_NAME, EXAMPLE_LICENSE_SEAT_UUID_ACTIVE, EXAMPLE_LICENSE_SEAT_UUID_AVAILABLE, EXAMPLE_LICENSE_SEAT_UUID_SECONDARY, EXAMPLE_LICENSE_SKU, EXAMPLE_LICENSE_SUBJECT_ID_ACTIVE, EXAMPLE_LICENSE_SUBJECT_ID_AVAILABLE, } from './shared.js';
|
|
5
|
+
import { EXAMPLE_LICENSE_ACCEPTED_OFFER_ID, EXAMPLE_LICENSE_AMOUNT, EXAMPLE_LICENSE_CHECKOUT_URL, EXAMPLE_LICENSE_CURRENCY, EXAMPLE_EMAIL_CONTROLLER_ORG, EXAMPLE_EMPLOYEE_ACTIVATION_CODE, EXAMPLE_EMPLOYEE_DEVICE_CLIENT_ID_PRIMARY, EXAMPLE_EMPLOYEE_DEVICE_CLIENT_ID_SECONDARY, EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_PRIMARY, EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_SECONDARY, EXAMPLE_EMPLOYEE_DEVICE_MODEL_PRIMARY, EXAMPLE_HEALTHCARE_ACTOR_ROLE_GENERALIST_MEDICAL_PRACTITIONER, EXAMPLE_LICENSE_INVOICE_ID, EXAMPLE_LICENSE_OFFER_ID, EXAMPLE_LICENSE_PLAN_DEFAULT, EXAMPLE_LICENSE_PAYMENT_METHOD_INVOICE, EXAMPLE_LICENSE_PAYMENT_URL, EXAMPLE_LICENSE_RENEWAL_CYCLE_YEARLY, EXAMPLE_LICENSE_PLAN_NAME, EXAMPLE_LICENSE_SEAT_UUID_ACTIVE, EXAMPLE_LICENSE_SEAT_UUID_AVAILABLE, EXAMPLE_LICENSE_SEAT_UUID_SECONDARY, EXAMPLE_LICENSE_SKU, EXAMPLE_LICENSE_SUBJECT_ID_ACTIVE, EXAMPLE_LICENSE_SUBJECT_ID_AVAILABLE, } from './shared.js';
|
|
6
|
+
import { DEFAULT_LICENSE_DEVICE_ALLOWANCE } from '../utils/license.js';
|
|
7
|
+
import { EXAMPLE_EMPLOYEE_CONTROLLER_ACTIVE } from './employee.js';
|
|
8
|
+
export const EXAMPLE_EMPLOYEE_DEVICE_BINDINGS = Object.freeze([
|
|
9
|
+
Object.freeze({
|
|
10
|
+
clientId: EXAMPLE_EMPLOYEE_DEVICE_CLIENT_ID_PRIMARY,
|
|
11
|
+
clientInstanceId: EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_PRIMARY,
|
|
12
|
+
status: DeviceBindingStatuses.Active,
|
|
13
|
+
deviceInfo: Object.freeze({
|
|
14
|
+
clientInstanceId: EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_PRIMARY,
|
|
15
|
+
model: EXAMPLE_EMPLOYEE_DEVICE_MODEL_PRIMARY,
|
|
16
|
+
}),
|
|
17
|
+
activatedAt: 1_786_570_800,
|
|
18
|
+
}),
|
|
19
|
+
Object.freeze({
|
|
20
|
+
clientId: EXAMPLE_EMPLOYEE_DEVICE_CLIENT_ID_SECONDARY,
|
|
21
|
+
clientInstanceId: EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_SECONDARY,
|
|
22
|
+
status: DeviceBindingStatuses.Revoked,
|
|
23
|
+
deviceInfo: Object.freeze({ clientInstanceId: EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_SECONDARY }),
|
|
24
|
+
activatedAt: 1_786_570_900,
|
|
25
|
+
revokedAt: 1_786_571_000,
|
|
26
|
+
}),
|
|
27
|
+
]);
|
|
28
|
+
/** Two simultaneously active installations used to test the default allowance. */
|
|
29
|
+
export const EXAMPLE_EMPLOYEE_ACTIVE_DEVICE_BINDINGS = Object.freeze(EXAMPLE_EMPLOYEE_DEVICE_BINDINGS.map((binding) => Object.freeze({
|
|
30
|
+
...binding,
|
|
31
|
+
status: DeviceBindingStatuses.Active,
|
|
32
|
+
revokedAt: undefined,
|
|
33
|
+
})));
|
|
6
34
|
export const EXAMPLE_LICENSE_SEAT_UUIDS = Object.freeze([
|
|
7
35
|
EXAMPLE_LICENSE_SEAT_UUID_ACTIVE,
|
|
8
36
|
EXAMPLE_LICENSE_SEAT_UUID_SECONDARY,
|
|
@@ -60,6 +88,61 @@ export const EXAMPLE_LICENSE_LIST_RESPONSE_BODY = Object.freeze({
|
|
|
60
88
|
},
|
|
61
89
|
],
|
|
62
90
|
});
|
|
91
|
+
/** Shared async GW response for a controller-issued employee activation credential. */
|
|
92
|
+
export const EXAMPLE_LICENSE_ISSUE_RESPONSE_BODY = Object.freeze({
|
|
93
|
+
body: {
|
|
94
|
+
data: [{
|
|
95
|
+
resource: {
|
|
96
|
+
data: [{
|
|
97
|
+
type: 'License:Issued',
|
|
98
|
+
id: EXAMPLE_EMPLOYEE_ACTIVATION_CODE,
|
|
99
|
+
meta: {
|
|
100
|
+
claims: {
|
|
101
|
+
[ClaimsIndividualProductSchemaorg.serialNumber]: EXAMPLE_EMPLOYEE_ACTIVATION_CODE,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
}],
|
|
105
|
+
},
|
|
106
|
+
}],
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
/** Shared license search response containing the default two-installation state. */
|
|
110
|
+
export const EXAMPLE_LICENSE_LIST_RESPONSE_BODY_WITH_DEVICES = Object.freeze({
|
|
111
|
+
body: {
|
|
112
|
+
resource: {
|
|
113
|
+
data: [{
|
|
114
|
+
id: EXAMPLE_LICENSE_ACTIVE_RECORD.id,
|
|
115
|
+
meta: {
|
|
116
|
+
status: EXAMPLE_LICENSE_ACTIVE_RECORD.status,
|
|
117
|
+
subjectId: EXAMPLE_EMPLOYEE_CONTROLLER_ACTIVE.resourceId,
|
|
118
|
+
maxDevices: DEFAULT_LICENSE_DEVICE_ALLOWANCE,
|
|
119
|
+
deviceBindings: EXAMPLE_EMPLOYEE_DEVICE_BINDINGS,
|
|
120
|
+
},
|
|
121
|
+
}],
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
/** Canonical controller-facing employee projection reused across SDK and portal tests. */
|
|
126
|
+
export const EXAMPLE_EMPLOYEE_LIFECYCLE_RECORD = Object.freeze({
|
|
127
|
+
resourceId: EXAMPLE_EMPLOYEE_CONTROLLER_ACTIVE.resourceId,
|
|
128
|
+
email: EXAMPLE_EMPLOYEE_CONTROLLER_ACTIVE.email,
|
|
129
|
+
roleCode: EXAMPLE_EMPLOYEE_CONTROLLER_ACTIVE.role,
|
|
130
|
+
employeeDid: EXAMPLE_EMPLOYEE_CONTROLLER_ACTIVE.identifier,
|
|
131
|
+
status: EXAMPLE_EMPLOYEE_CONTROLLER_ACTIVE.status,
|
|
132
|
+
license: Object.freeze({
|
|
133
|
+
id: EXAMPLE_LICENSE_ACTIVE_RECORD.id,
|
|
134
|
+
status: EXAMPLE_LICENSE_ACTIVE_RECORD.status,
|
|
135
|
+
maxDevices: DEFAULT_LICENSE_DEVICE_ALLOWANCE,
|
|
136
|
+
activeDevices: EXAMPLE_EMPLOYEE_DEVICE_BINDINGS.filter((binding) => binding.status === DeviceBindingStatuses.Active).length,
|
|
137
|
+
devices: Object.freeze(EXAMPLE_EMPLOYEE_DEVICE_BINDINGS.map((binding) => Object.freeze({
|
|
138
|
+
clientId: binding.clientId,
|
|
139
|
+
name: ('model' in binding.deviceInfo ? binding.deviceInfo.model : undefined)
|
|
140
|
+
|| binding.deviceInfo.clientInstanceId
|
|
141
|
+
|| binding.clientId,
|
|
142
|
+
status: binding.status,
|
|
143
|
+
}))),
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
63
146
|
export function buildExampleLicenseIssueClaims() {
|
|
64
147
|
return Object.freeze(buildLicenseIssueClaims(EXAMPLE_LICENSE_ISSUE_INPUT));
|
|
65
148
|
}
|
|
@@ -86,6 +86,32 @@ export declare const EXAMPLE_OTP_INVITATION_ID: "invitation-demo-001";
|
|
|
86
86
|
export declare const EXAMPLE_OTP_CHALLENGE_ID: "otp-challenge-demo-001";
|
|
87
87
|
export declare const EXAMPLE_OTP_CODE: "123456";
|
|
88
88
|
export declare const EXAMPLE_DEMO_PORTAL_ID_TOKEN: "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJkZW1vLXVzZXIiLCJlbWFpbCI6ImRlbW9AZXhhbXBsZS5vcmcifQ.demo";
|
|
89
|
+
export declare const EXAMPLE_ACCOUNT_OWNER_ID: "account-owner-example";
|
|
90
|
+
export declare const EXAMPLE_PROFILE_PIN: "482951";
|
|
91
|
+
export declare const EXAMPLE_JWK_THUMBPRINT_SHA256_URN: "urn:ietf:params:oauth:jwk-thumbprint:sha-256:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
|
|
92
|
+
export declare const EXAMPLE_DCR_REDIRECT_URI: "https://portal.example.org/auth/callback";
|
|
93
|
+
export declare const EXAMPLE_EMPLOYEE_DCR_CLIENT_NAME: "Example Professional Employee";
|
|
94
|
+
export declare const EXAMPLE_ASYNC_SUBMIT_STATUS: 202;
|
|
95
|
+
export declare const EXAMPLE_ASYNC_POLL_STATUS: 200;
|
|
96
|
+
export declare const EXAMPLE_ASYNC_POLL_ATTEMPTS: 1;
|
|
97
|
+
export declare const ExampleHttpStatusText: Readonly<{
|
|
98
|
+
readonly Ok: "200";
|
|
99
|
+
readonly Conflict: "409";
|
|
100
|
+
}>;
|
|
101
|
+
export declare const EXAMPLE_ACTIVATION_GRANT_CREATED_AT: "2026-08-13T19:20:00.000Z";
|
|
102
|
+
export declare const EXAMPLE_ACTIVATION_GRANT_EXPIRES_AT: "2027-08-13T19:20:00.000Z";
|
|
103
|
+
/** Wraps any shared response body in the canonical successful async result. */
|
|
104
|
+
export declare function buildExampleSubmitAndPollResult(body: unknown): Readonly<{
|
|
105
|
+
submit: Readonly<{
|
|
106
|
+
status: 202;
|
|
107
|
+
body: Readonly<{}>;
|
|
108
|
+
}>;
|
|
109
|
+
poll: Readonly<{
|
|
110
|
+
status: 200;
|
|
111
|
+
body: unknown;
|
|
112
|
+
attempts: 1;
|
|
113
|
+
}>;
|
|
114
|
+
}>;
|
|
89
115
|
export declare const EXAMPLE_TENANT_ROUTE_CONTEXT: {
|
|
90
116
|
readonly tenantId: "acme-id";
|
|
91
117
|
readonly jurisdiction: "ES";
|
|
@@ -255,6 +281,13 @@ export declare const EXAMPLE_CONTENT_ADDRESSED_CONSENT_IDENTIFIER: "zQmYwAPJzv5C
|
|
|
255
281
|
export declare const EXAMPLE_CONTENT_ADDRESSED_SOURCE_REFERENCE: "zQmWvM9dQmWvM9dQmWvM9dQmWvM9dQmWvM9dQmWvM9dQmWv";
|
|
256
282
|
export declare const EXAMPLE_CONTENT_ADDRESSED_EVIDENCE_RECORD_IDENTIFIER: "zQmXh8Y3mJQ4d7MmX7o9nP5sQ2uT1vW6xY8zA3bC4dE5fG";
|
|
257
283
|
export declare const EXAMPLE_EMPLOYEE_ACTIVATION_CODE: "ACT-001";
|
|
284
|
+
export declare const EXAMPLE_EMPLOYEE_DEVICE_CLIENT_ID_PRIMARY: "client-employee-primary";
|
|
285
|
+
export declare const EXAMPLE_EMPLOYEE_DEVICE_CLIENT_ID_SECONDARY: "client-employee-secondary";
|
|
286
|
+
export declare const EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_PRIMARY: "installation-employee-primary";
|
|
287
|
+
export declare const EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_SECONDARY: "installation-employee-secondary";
|
|
288
|
+
export declare const EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_TERTIARY: "installation-employee-tertiary";
|
|
289
|
+
export declare const EXAMPLE_CLIENT_INSTANCE_UUID: "7f5e8d6c-91f4-4f6d-a29f-8bd42e44f101";
|
|
290
|
+
export declare const EXAMPLE_EMPLOYEE_DEVICE_MODEL_PRIMARY: "Shared browser profile";
|
|
258
291
|
export declare const EXAMPLE_LICENSE_OFFER_ID: "urn:offer:family-003";
|
|
259
292
|
export declare const EXAMPLE_LICENSE_INVALID_OFFER_ID: "urn:offer:invalid-001";
|
|
260
293
|
export declare const EXAMPLE_LICENSE_ACCEPTED_OFFER_ID: "urn:offer:family-003";
|
package/dist/examples/shared.js
CHANGED
|
@@ -101,6 +101,31 @@ export const EXAMPLE_OTP_INVITATION_ID = 'invitation-demo-001';
|
|
|
101
101
|
export const EXAMPLE_OTP_CHALLENGE_ID = 'otp-challenge-demo-001';
|
|
102
102
|
export const EXAMPLE_OTP_CODE = '123456';
|
|
103
103
|
export const EXAMPLE_DEMO_PORTAL_ID_TOKEN = 'eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJkZW1vLXVzZXIiLCJlbWFpbCI6ImRlbW9AZXhhbXBsZS5vcmcifQ.demo';
|
|
104
|
+
export const EXAMPLE_ACCOUNT_OWNER_ID = 'account-owner-example';
|
|
105
|
+
export const EXAMPLE_PROFILE_PIN = '482951';
|
|
106
|
+
export const EXAMPLE_JWK_THUMBPRINT_SHA256_URN = 'urn:ietf:params:oauth:jwk-thumbprint:sha-256:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB';
|
|
107
|
+
export const EXAMPLE_DCR_REDIRECT_URI = 'https://portal.example.org/auth/callback';
|
|
108
|
+
export const EXAMPLE_EMPLOYEE_DCR_CLIENT_NAME = 'Example Professional Employee';
|
|
109
|
+
export const EXAMPLE_ASYNC_SUBMIT_STATUS = 202;
|
|
110
|
+
export const EXAMPLE_ASYNC_POLL_STATUS = 200;
|
|
111
|
+
export const EXAMPLE_ASYNC_POLL_ATTEMPTS = 1;
|
|
112
|
+
export const ExampleHttpStatusText = Object.freeze({
|
|
113
|
+
Ok: '200',
|
|
114
|
+
Conflict: '409',
|
|
115
|
+
});
|
|
116
|
+
export const EXAMPLE_ACTIVATION_GRANT_CREATED_AT = '2026-08-13T19:20:00.000Z';
|
|
117
|
+
export const EXAMPLE_ACTIVATION_GRANT_EXPIRES_AT = '2027-08-13T19:20:00.000Z';
|
|
118
|
+
/** Wraps any shared response body in the canonical successful async result. */
|
|
119
|
+
export function buildExampleSubmitAndPollResult(body) {
|
|
120
|
+
return Object.freeze({
|
|
121
|
+
submit: Object.freeze({ status: EXAMPLE_ASYNC_SUBMIT_STATUS, body: Object.freeze({}) }),
|
|
122
|
+
poll: Object.freeze({
|
|
123
|
+
status: EXAMPLE_ASYNC_POLL_STATUS,
|
|
124
|
+
body,
|
|
125
|
+
attempts: EXAMPLE_ASYNC_POLL_ATTEMPTS,
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
104
129
|
export const EXAMPLE_TENANT_ROUTE_CONTEXT = {
|
|
105
130
|
tenantId: EXAMPLE_TENANT_IDENTIFIER,
|
|
106
131
|
jurisdiction: EXAMPLE_JURISDICTION,
|
|
@@ -298,6 +323,13 @@ export const EXAMPLE_CONTENT_ADDRESSED_CONSENT_IDENTIFIER = 'zQmYwAPJzv5CZsnAzt8
|
|
|
298
323
|
export const EXAMPLE_CONTENT_ADDRESSED_SOURCE_REFERENCE = 'zQmWvM9dQmWvM9dQmWvM9dQmWvM9dQmWvM9dQmWvM9dQmWv';
|
|
299
324
|
export const EXAMPLE_CONTENT_ADDRESSED_EVIDENCE_RECORD_IDENTIFIER = 'zQmXh8Y3mJQ4d7MmX7o9nP5sQ2uT1vW6xY8zA3bC4dE5fG';
|
|
300
325
|
export const EXAMPLE_EMPLOYEE_ACTIVATION_CODE = 'ACT-001';
|
|
326
|
+
export const EXAMPLE_EMPLOYEE_DEVICE_CLIENT_ID_PRIMARY = 'client-employee-primary';
|
|
327
|
+
export const EXAMPLE_EMPLOYEE_DEVICE_CLIENT_ID_SECONDARY = 'client-employee-secondary';
|
|
328
|
+
export const EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_PRIMARY = 'installation-employee-primary';
|
|
329
|
+
export const EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_SECONDARY = 'installation-employee-secondary';
|
|
330
|
+
export const EXAMPLE_EMPLOYEE_DEVICE_INSTANCE_ID_TERTIARY = 'installation-employee-tertiary';
|
|
331
|
+
export const EXAMPLE_CLIENT_INSTANCE_UUID = '7f5e8d6c-91f4-4f6d-a29f-8bd42e44f101';
|
|
332
|
+
export const EXAMPLE_EMPLOYEE_DEVICE_MODEL_PRIMARY = 'Shared browser profile';
|
|
301
333
|
export const EXAMPLE_LICENSE_OFFER_ID = 'urn:offer:family-003';
|
|
302
334
|
export const EXAMPLE_LICENSE_INVALID_OFFER_ID = 'urn:offer:invalid-001';
|
|
303
335
|
export const EXAMPLE_LICENSE_ACCEPTED_OFFER_ID = EXAMPLE_LICENSE_OFFER_ID;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeviceAppType, DeviceUserClass } from '../constants/device';
|
|
1
|
+
import type { DeviceAppType, DeviceBindingStatus, DeviceUserClass } from '../constants/device';
|
|
2
2
|
/**
|
|
3
3
|
* A fingerprint of a specific device, used for binding a license to it.
|
|
4
4
|
*/
|
|
@@ -24,7 +24,7 @@ export interface DeviceBinding {
|
|
|
24
24
|
/** Stable application installation fingerprint supplied by the client. */
|
|
25
25
|
clientInstanceId: string;
|
|
26
26
|
/** Current relationship between this installation and the seat. */
|
|
27
|
-
status:
|
|
27
|
+
status: DeviceBindingStatus;
|
|
28
28
|
/** Device/application metadata captured during DCR. */
|
|
29
29
|
deviceInfo: DeviceInfo;
|
|
30
30
|
activatedAt: number;
|
package/dist/models/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from './dataspace-discovery';
|
|
|
19
19
|
export * from './dataspace-discovery-defaults';
|
|
20
20
|
export * from './dataspace-protocol';
|
|
21
21
|
export * from './device-license';
|
|
22
|
+
export * from './organization-employee-lifecycle';
|
|
22
23
|
export * from './did';
|
|
23
24
|
export * from './fhir-documents';
|
|
24
25
|
export * from './gaia-x';
|
package/dist/models/index.js
CHANGED
|
@@ -19,6 +19,7 @@ export * from './dataspace-discovery.js';
|
|
|
19
19
|
export * from './dataspace-discovery-defaults.js';
|
|
20
20
|
export * from './dataspace-protocol.js';
|
|
21
21
|
export * from './device-license.js';
|
|
22
|
+
export * from './organization-employee-lifecycle.js';
|
|
22
23
|
export * from './did.js';
|
|
23
24
|
export * from './fhir-documents.js';
|
|
24
25
|
export * from './gaia-x.js';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { DeviceBindingStatus } from '../constants/device';
|
|
2
|
+
import type { EmployeeActivationGrantVersion, EmployeeDirectoryStatus } from '../constants/employee-lifecycle';
|
|
3
|
+
/** One installation in the controller-facing employee lifecycle projection. */
|
|
4
|
+
export type OrganizationEmployeeDeviceRecord = Readonly<{
|
|
5
|
+
clientId: string;
|
|
6
|
+
name: string;
|
|
7
|
+
status: DeviceBindingStatus;
|
|
8
|
+
}>;
|
|
9
|
+
/** License state attached to one employee directory entry. */
|
|
10
|
+
export type OrganizationEmployeeLicenseRecord = Readonly<{
|
|
11
|
+
id: string;
|
|
12
|
+
status: string;
|
|
13
|
+
maxDevices: number;
|
|
14
|
+
activeDevices: number;
|
|
15
|
+
devices: ReadonlyArray<OrganizationEmployeeDeviceRecord>;
|
|
16
|
+
}>;
|
|
17
|
+
/** Product-neutral employee, seat and installation lifecycle projection. */
|
|
18
|
+
export type OrganizationEmployeeLifecycleRecord = Readonly<{
|
|
19
|
+
resourceId: string;
|
|
20
|
+
email: string;
|
|
21
|
+
roleCode: string;
|
|
22
|
+
employeeDid: string;
|
|
23
|
+
status: EmployeeDirectoryStatus;
|
|
24
|
+
license?: OrganizationEmployeeLicenseRecord;
|
|
25
|
+
}>;
|
|
26
|
+
/** Typed wire request for revoking one installation without releasing its seat. */
|
|
27
|
+
export type EmployeeDeviceRevocationTarget = Readonly<{
|
|
28
|
+
licenseId: string;
|
|
29
|
+
clientId: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** Tenant routing metadata bound to an employee activation credential digest. */
|
|
32
|
+
export type EmployeeActivationGrant = Readonly<{
|
|
33
|
+
version: EmployeeActivationGrantVersion;
|
|
34
|
+
employeeDid: string;
|
|
35
|
+
employeeRoleCode: string;
|
|
36
|
+
employeeActorIdentifier: string;
|
|
37
|
+
providerDid: string;
|
|
38
|
+
routeContext: Readonly<{
|
|
39
|
+
tenantId: string;
|
|
40
|
+
jurisdiction: string;
|
|
41
|
+
sector: string;
|
|
42
|
+
}>;
|
|
43
|
+
createdAt: string;
|
|
44
|
+
expiresAt: string;
|
|
45
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -67,6 +67,7 @@ export * from './individual-organization-claims';
|
|
|
67
67
|
export * from './inter-tenant-access-contract';
|
|
68
68
|
export * from './legal-organization-onboarding-editor';
|
|
69
69
|
export * from './organization-lifecycle';
|
|
70
|
+
export * from './organization-employee-lifecycle';
|
|
70
71
|
export * from './organization-did-binding';
|
|
71
72
|
export * from './organization-authorization-urn';
|
|
72
73
|
export * from './individual-organization-lifecycle';
|
package/dist/utils/index.js
CHANGED
|
@@ -67,6 +67,7 @@ export * from './individual-organization-claims.js';
|
|
|
67
67
|
export * from './inter-tenant-access-contract.js';
|
|
68
68
|
export * from './legal-organization-onboarding-editor.js';
|
|
69
69
|
export * from './organization-lifecycle.js';
|
|
70
|
+
export * from './organization-employee-lifecycle.js';
|
|
70
71
|
export * from './organization-did-binding.js';
|
|
71
72
|
export * from './organization-authorization-urn.js';
|
|
72
73
|
export * from './individual-organization-lifecycle.js';
|
|
@@ -38,6 +38,8 @@ export declare function computeRfc7638JwkThumbprint(jwk: ThumbprintableJwk): str
|
|
|
38
38
|
* `urn:ietf:params:oauth:jwk-thumbprint:sha-256:<base64url>`
|
|
39
39
|
*/
|
|
40
40
|
export declare function toJwkThumbprintSha256Urn(jwk: ThumbprintableJwk): string;
|
|
41
|
+
/** True only for an RFC 9278 SHA-256 JWK thumbprint URI. */
|
|
42
|
+
export declare function isJwkThumbprintSha256Urn(value: unknown): value is string;
|
|
41
43
|
/**
|
|
42
44
|
* Returns a public JWK whose `kid` is derived exclusively from its public key
|
|
43
45
|
* material. Caller-provided aliases are deliberately replaced so DID methods,
|
|
@@ -55,6 +55,14 @@ export function computeRfc7638JwkThumbprint(jwk) {
|
|
|
55
55
|
export function toJwkThumbprintSha256Urn(jwk) {
|
|
56
56
|
return `${UrnPrefixes.JwkThumbprintSha256KeyId}${computeRfc7638JwkThumbprint(jwk)}`;
|
|
57
57
|
}
|
|
58
|
+
/** True only for an RFC 9278 SHA-256 JWK thumbprint URI. */
|
|
59
|
+
export function isJwkThumbprintSha256Urn(value) {
|
|
60
|
+
const normalized = typeof value === 'string' ? value.trim() : '';
|
|
61
|
+
if (!normalized.startsWith(UrnPrefixes.JwkThumbprintSha256KeyId))
|
|
62
|
+
return false;
|
|
63
|
+
const thumbprint = normalized.slice(UrnPrefixes.JwkThumbprintSha256KeyId.length);
|
|
64
|
+
return /^[A-Za-z0-9_-]{43}$/.test(thumbprint);
|
|
65
|
+
}
|
|
58
66
|
/**
|
|
59
67
|
* Returns a public JWK whose `kid` is derived exclusively from its public key
|
|
60
68
|
* material. Caller-provided aliases are deliberately replaced so DID methods,
|
package/dist/utils/license.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DeviceAppTypes, DeviceUserClasses } from '../constants/device.js';
|
|
1
|
+
import { DeviceAppTypes, DeviceBindingStatuses, DeviceUserClasses } from '../constants/device.js';
|
|
2
2
|
import { ClaimsIndividualProductSchemaorg, ClaimsOfferSchemaorg, ClaimsPersonSchemaorg, } from '../constants/schemaorg.js';
|
|
3
3
|
/** Default simultaneous installation allowance for one professional/member seat. */
|
|
4
4
|
export const DEFAULT_LICENSE_DEVICE_ALLOWANCE = 2;
|
|
@@ -13,7 +13,7 @@ export function resolveLicenseDeviceAllowance(license) {
|
|
|
13
13
|
*/
|
|
14
14
|
export function listActiveLicenseDeviceBindings(license) {
|
|
15
15
|
if (Array.isArray(license.deviceBindings)) {
|
|
16
|
-
return license.deviceBindings.filter((binding) => binding.status ===
|
|
16
|
+
return license.deviceBindings.filter((binding) => binding.status === DeviceBindingStatuses.Active);
|
|
17
17
|
}
|
|
18
18
|
const clientId = String(license.deviceId || '').trim();
|
|
19
19
|
if (!clientId)
|
|
@@ -22,7 +22,7 @@ export function listActiveLicenseDeviceBindings(license) {
|
|
|
22
22
|
return [{
|
|
23
23
|
clientId,
|
|
24
24
|
clientInstanceId: deviceInfo.clientInstanceId || clientId,
|
|
25
|
-
status:
|
|
25
|
+
status: DeviceBindingStatuses.Active,
|
|
26
26
|
deviceInfo,
|
|
27
27
|
activatedAt: Number(license.activatedAt || 0),
|
|
28
28
|
}];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EmployeeDeviceRevocationTarget, OrganizationEmployeeLifecycleRecord } from '../models/organization-employee-lifecycle';
|
|
2
|
+
/** Builds the exact identity/auth revoke request body from a typed target. */
|
|
3
|
+
export declare function buildEmployeeDeviceRevocationBody(target: EmployeeDeviceRevocationTarget): Readonly<Record<string, string>>;
|
|
4
|
+
/** Reads an employee activation credential from canonical and legacy GW envelopes. */
|
|
5
|
+
export declare function readEmployeeActivationCode(value: unknown): string;
|
|
6
|
+
/** Extracts GW search rows regardless of async job envelope depth. */
|
|
7
|
+
export declare function extractGwSearchResources(value: unknown): ReadonlyArray<Record<string, unknown>>;
|
|
8
|
+
/** Combines employee directory and license search results into one typed view. */
|
|
9
|
+
export declare function projectOrganizationEmployeeLifecycle(input: Readonly<{
|
|
10
|
+
employeeResponse: unknown;
|
|
11
|
+
licenseResponse: unknown;
|
|
12
|
+
}>): OrganizationEmployeeLifecycleRecord[];
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { ClaimsIndividualProductSchemaorg, ClaimsPersonSchemaorg } from '../constants/schemaorg.js';
|
|
2
|
+
import { DeviceBindingStatuses } from '../constants/device.js';
|
|
3
|
+
import { EmployeeDirectoryStatuses } from '../constants/employee-lifecycle.js';
|
|
4
|
+
import { IdentityAuthRequestFields, IdentityAuthResponseEntryTypes, } from '../constants/identity-auth.js';
|
|
5
|
+
import { DEFAULT_LICENSE_DEVICE_ALLOWANCE } from './license.js';
|
|
6
|
+
/** Builds the exact identity/auth revoke request body from a typed target. */
|
|
7
|
+
export function buildEmployeeDeviceRevocationBody(target) {
|
|
8
|
+
return Object.freeze({
|
|
9
|
+
[IdentityAuthRequestFields.LicenseId]: target.licenseId,
|
|
10
|
+
[IdentityAuthRequestFields.ClientId]: target.clientId,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/** Reads an employee activation credential from canonical and legacy GW envelopes. */
|
|
14
|
+
export function readEmployeeActivationCode(value) {
|
|
15
|
+
for (const candidate of listNestedRecords(value)) {
|
|
16
|
+
if (candidate.type === IdentityAuthResponseEntryTypes.LicenseIssued) {
|
|
17
|
+
const issuedId = text(candidate.id);
|
|
18
|
+
if (issuedId)
|
|
19
|
+
return issuedId;
|
|
20
|
+
}
|
|
21
|
+
const claims = record(candidate.claims) || record(record(candidate.meta)?.claims);
|
|
22
|
+
const serial = text(claims?.[ClaimsIndividualProductSchemaorg.serialNumber]);
|
|
23
|
+
if (serial)
|
|
24
|
+
return serial;
|
|
25
|
+
}
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
/** Extracts GW search rows regardless of async job envelope depth. */
|
|
29
|
+
export function extractGwSearchResources(value) {
|
|
30
|
+
for (const candidate of listNestedRecords(value)) {
|
|
31
|
+
const data = record(candidate.resource)?.data || candidate.data;
|
|
32
|
+
if (Array.isArray(data))
|
|
33
|
+
return data.map(record).filter(isRecord);
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
/** Combines employee directory and license search results into one typed view. */
|
|
38
|
+
export function projectOrganizationEmployeeLifecycle(input) {
|
|
39
|
+
const licenses = extractGwSearchResources(input.licenseResponse);
|
|
40
|
+
return extractGwSearchResources(input.employeeResponse).map((employee) => {
|
|
41
|
+
const claims = record(employee.claims) || record(record(employee.meta)?.claims) || {};
|
|
42
|
+
const resourceId = text(employee.id);
|
|
43
|
+
const employeeDid = text(claims[ClaimsPersonSchemaorg.identifier]);
|
|
44
|
+
const license = licenses.find((candidate) => {
|
|
45
|
+
const meta = record(candidate.meta) || {};
|
|
46
|
+
const subjectId = text(meta.subjectId);
|
|
47
|
+
return subjectId === resourceId || subjectId === employeeDid;
|
|
48
|
+
});
|
|
49
|
+
const status = normalizeEmployeeDirectoryStatus(text(employee.status) || text(record(employee.meta)?.status));
|
|
50
|
+
if (!license)
|
|
51
|
+
return {
|
|
52
|
+
resourceId,
|
|
53
|
+
email: text(claims[ClaimsPersonSchemaorg.email]),
|
|
54
|
+
roleCode: text(claims[ClaimsPersonSchemaorg.hasOccupationalRoleValue]),
|
|
55
|
+
employeeDid,
|
|
56
|
+
status,
|
|
57
|
+
};
|
|
58
|
+
const meta = record(license.meta) || {};
|
|
59
|
+
const bindings = Array.isArray(meta.deviceBindings) ? meta.deviceBindings.map(record).filter(isRecord) : [];
|
|
60
|
+
const devices = bindings.map((binding) => {
|
|
61
|
+
const info = record(binding.deviceInfo) || {};
|
|
62
|
+
const clientId = text(binding.clientId);
|
|
63
|
+
return {
|
|
64
|
+
clientId,
|
|
65
|
+
name: text(info.model) || text(info.clientInstanceId) || clientId,
|
|
66
|
+
status: binding.status === DeviceBindingStatuses.Revoked
|
|
67
|
+
? DeviceBindingStatuses.Revoked
|
|
68
|
+
: DeviceBindingStatuses.Active,
|
|
69
|
+
};
|
|
70
|
+
}).filter((device) => Boolean(device.clientId));
|
|
71
|
+
return {
|
|
72
|
+
resourceId,
|
|
73
|
+
email: text(claims[ClaimsPersonSchemaorg.email]),
|
|
74
|
+
roleCode: text(claims[ClaimsPersonSchemaorg.hasOccupationalRoleValue]),
|
|
75
|
+
employeeDid,
|
|
76
|
+
status,
|
|
77
|
+
license: {
|
|
78
|
+
id: text(license.id),
|
|
79
|
+
status: text(meta.status),
|
|
80
|
+
maxDevices: positiveInteger(meta.maxDevices) || DEFAULT_LICENSE_DEVICE_ALLOWANCE,
|
|
81
|
+
activeDevices: devices.filter((device) => device.status === DeviceBindingStatuses.Active).length,
|
|
82
|
+
devices,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}).filter((employee) => Boolean(employee.resourceId));
|
|
86
|
+
}
|
|
87
|
+
function normalizeEmployeeDirectoryStatus(value) {
|
|
88
|
+
return Object.values(EmployeeDirectoryStatuses).includes(value)
|
|
89
|
+
? value
|
|
90
|
+
: EmployeeDirectoryStatuses.Unknown;
|
|
91
|
+
}
|
|
92
|
+
function listNestedRecords(root) {
|
|
93
|
+
const result = [];
|
|
94
|
+
const pending = [root];
|
|
95
|
+
const visited = new Set();
|
|
96
|
+
while (pending.length > 0) {
|
|
97
|
+
const value = pending.shift();
|
|
98
|
+
if (!value || typeof value !== 'object' || visited.has(value))
|
|
99
|
+
continue;
|
|
100
|
+
visited.add(value);
|
|
101
|
+
if (Array.isArray(value)) {
|
|
102
|
+
pending.push(...value);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const item = value;
|
|
106
|
+
result.push(item);
|
|
107
|
+
pending.push(...Object.values(item));
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
function record(value) {
|
|
112
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
113
|
+
? value
|
|
114
|
+
: undefined;
|
|
115
|
+
}
|
|
116
|
+
function isRecord(value) {
|
|
117
|
+
return Boolean(value);
|
|
118
|
+
}
|
|
119
|
+
function text(value) {
|
|
120
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
121
|
+
}
|
|
122
|
+
function positiveInteger(value) {
|
|
123
|
+
const parsed = Number(value);
|
|
124
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
125
|
+
}
|