gdc-sdk-node-ts 2.4.13 → 2.4.16
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/node-runtime-client.d.ts +1 -1
- package/dist/node-runtime-client.js +2 -1
- package/dist/orchestration/organization-controller-sdk.d.ts +1 -1
- package/dist/orchestration/organization-controller-sdk.js +1 -1
- package/dist/organization-employee-lifecycle.d.ts +23 -2
- package/dist/organization-employee-lifecycle.js +45 -3
- package/dist/resource-operations.d.ts +2 -8
- package/dist/resource-operations.js +3 -23
- package/package.json +3 -2
|
@@ -297,7 +297,7 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
297
297
|
* route with optional filters.
|
|
298
298
|
*/
|
|
299
299
|
listOrganizationLicenses(ctx: RouteContext, input?: LicenseListRuntimeSearchInput): Promise<SubmitAndPollResult>;
|
|
300
|
-
/**
|
|
300
|
+
/** @deprecated Professional seats use Employee Offer and confirmed Order. */
|
|
301
301
|
addFreeOrganizationEmployeeLicenses(ctx: RouteContext, input: OrganizationEmployeeLicenseAddInput): Promise<SubmitAndPollResult>;
|
|
302
302
|
searchOrganizationLicenseOffers(ctx: RouteContext, input: LicenseOfferRuntimeSearchInput): Promise<SubmitAndPollResult>;
|
|
303
303
|
listOrganizationLicenseOffers(ctx: RouteContext, input?: LicenseOfferRuntimeSearchInput): Promise<SubmitAndPollResult>;
|
|
@@ -371,6 +371,7 @@ export class HttpRuntimeClient {
|
|
|
371
371
|
async provisionOrganizationEmployee(ctx, input) {
|
|
372
372
|
return provisionOrganizationEmployeeWithDeps(ctx, input, {
|
|
373
373
|
createEmployee: (routeContext, creation) => this.createOrganizationEmployee(routeContext, creation),
|
|
374
|
+
confirmLicenseOrder: (routeContext, licenseOrder) => this.confirmOrganizationLicenseOrder(routeContext, licenseOrder),
|
|
374
375
|
issueLicense: (routeContext, invitation) => this.issueOrganizationEmployeeLicense(routeContext, invitation),
|
|
375
376
|
});
|
|
376
377
|
}
|
|
@@ -473,7 +474,7 @@ export class HttpRuntimeClient {
|
|
|
473
474
|
submitAndPoll: this.submitAndPoll.bind(this),
|
|
474
475
|
});
|
|
475
476
|
}
|
|
476
|
-
/**
|
|
477
|
+
/** @deprecated Professional seats use Employee Offer and confirmed Order. */
|
|
477
478
|
async addFreeOrganizationEmployeeLicenses(ctx, input) {
|
|
478
479
|
return addFreeOrganizationEmployeeLicensesWithDeps(ctx, input, {
|
|
479
480
|
organizationLicenseActionPath: this.paths.organizationLicenseActionPath.bind(this.paths),
|
|
@@ -83,7 +83,7 @@ export declare class OrganizationControllerSdk {
|
|
|
83
83
|
* Lists organization-owned license seats with optional filters.
|
|
84
84
|
*/
|
|
85
85
|
listLicenses(ctx: RouteContext, input?: LicenseListRuntimeSearchInput): Promise<SubmitAndPollResult>;
|
|
86
|
-
/**
|
|
86
|
+
/** @deprecated Professional seats use Employee Offer and confirmed Order. */
|
|
87
87
|
addFreeEmployeeLicenses(ctx: RouteContext, input: OrganizationEmployeeLicenseAddInput): Promise<SubmitAndPollResult>;
|
|
88
88
|
/**
|
|
89
89
|
* Searches commercial license offers known for the current organization.
|
|
@@ -111,7 +111,7 @@ export class OrganizationControllerSdk {
|
|
|
111
111
|
listLicenses(ctx, input = {}) {
|
|
112
112
|
return requireClientMethod(this.client, 'listOrganizationLicenses')(ctx, input);
|
|
113
113
|
}
|
|
114
|
-
/**
|
|
114
|
+
/** @deprecated Professional seats use Employee Offer and confirmed Order. */
|
|
115
115
|
addFreeEmployeeLicenses(ctx, input) {
|
|
116
116
|
return requireClientMethod(this.client, 'addFreeOrganizationEmployeeLicenses')(ctx, input);
|
|
117
117
|
}
|
|
@@ -1,26 +1,47 @@
|
|
|
1
1
|
import { type EmployeeActivationGrant, type OrganizationEmployeeLifecycleRecord } from 'gdc-common-utils-ts';
|
|
2
2
|
import type { RouteContext } from './individual-onboarding.js';
|
|
3
3
|
import type { SubmitAndPollResult } from './orchestration/client-port.js';
|
|
4
|
+
import type { OrganizationLicenseOrderConfirmInput } from './organization-license-order.js';
|
|
4
5
|
import type { ServerProfileEnrollmentInput, ServerProfileRecord } from './server-profile-session.js';
|
|
5
6
|
import type { LicenseListRuntimeSearchInput, OrganizationEmployeeCreationInput, OrganizationEmployeeLicenseInvitationInput, OrganizationEmployeeSearchInput } from './resource-operations.js';
|
|
6
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Input for atomic interactive provisioning. Every current employee create is
|
|
9
|
+
* seat-required. Supplying `licenseOrder` authorizes the SDK to close a
|
|
10
|
+
* GW-issued Offer before retrying creation and issuing the activation
|
|
11
|
+
* credential. A future batch import requires a separate explicit operation.
|
|
12
|
+
*/
|
|
7
13
|
export type OrganizationEmployeeProvisioningInput = Readonly<{
|
|
8
14
|
creation: OrganizationEmployeeCreationInput;
|
|
9
15
|
invitation: OrganizationEmployeeLicenseInvitationInput;
|
|
16
|
+
licenseOrder?: Omit<OrganizationLicenseOrderConfirmInput, 'offerId'>;
|
|
10
17
|
}>;
|
|
11
18
|
/** Results required by a portal to persist routing and display the credential once. */
|
|
12
19
|
export type OrganizationEmployeeProvisioningResult = Readonly<{
|
|
13
20
|
employee: SubmitAndPollResult;
|
|
14
21
|
license: SubmitAndPollResult;
|
|
22
|
+
licenseOrder?: SubmitAndPollResult;
|
|
15
23
|
activationCode: string;
|
|
16
24
|
}>;
|
|
17
25
|
/** Shared dependencies for the create plus seat issuance workflow. */
|
|
18
26
|
export type OrganizationEmployeeProvisioningDeps = Readonly<{
|
|
19
27
|
createEmployee(routeContext: RouteContext, input: OrganizationEmployeeCreationInput): Promise<SubmitAndPollResult>;
|
|
20
28
|
issueLicense(routeContext: RouteContext, input: OrganizationEmployeeLicenseInvitationInput): Promise<SubmitAndPollResult>;
|
|
29
|
+
confirmLicenseOrder?(routeContext: RouteContext, input: OrganizationLicenseOrderConfirmInput): Promise<SubmitAndPollResult>;
|
|
21
30
|
}>;
|
|
22
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Creates the employee, closing Offer/Order first when the strict request has
|
|
33
|
+
* no available seat, then reserves that seat through `License/_issue` and
|
|
34
|
+
* returns the exact GW activation credential.
|
|
35
|
+
*/
|
|
23
36
|
export declare function provisionOrganizationEmployeeWithDeps(routeContext: RouteContext, input: OrganizationEmployeeProvisioningInput, deps: OrganizationEmployeeProvisioningDeps): Promise<OrganizationEmployeeProvisioningResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Reads the pending seat Offer from an employee-create response.
|
|
39
|
+
*
|
|
40
|
+
* Portal BFFs use this boundary when payment is asynchronous: persist the
|
|
41
|
+
* server-owned creation intent, redirect to hosted Checkout, then submit the
|
|
42
|
+
* paid reference in Order before retrying employee creation and License/_issue.
|
|
43
|
+
*/
|
|
44
|
+
export declare function readEmployeeLicenseOfferId(value: unknown): string | undefined;
|
|
24
45
|
/**
|
|
25
46
|
* Rejects failed outer HTTP responses and failed entries hidden inside a
|
|
26
47
|
* successful async poll envelope before a caller starts the next mutation.
|
|
@@ -2,17 +2,59 @@
|
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { ActorKinds, EmployeeActivationGrantVersions, projectOrganizationEmployeeLifecycle, readEmployeeActivationCode, } from 'gdc-common-utils-ts';
|
|
4
4
|
import { buildStableActorIdentifier } from 'gdc-common-utils-ts/utils/actor-identifier';
|
|
5
|
-
|
|
5
|
+
import { ClaimsOfferSchemaorg } from 'gdc-common-utils-ts/constants/schemaorg';
|
|
6
|
+
/**
|
|
7
|
+
* Creates the employee, closing Offer/Order first when the strict request has
|
|
8
|
+
* no available seat, then reserves that seat through `License/_issue` and
|
|
9
|
+
* returns the exact GW activation credential.
|
|
10
|
+
*/
|
|
6
11
|
export async function provisionOrganizationEmployeeWithDeps(routeContext, input, deps) {
|
|
7
|
-
const
|
|
12
|
+
const creation = input.creation;
|
|
13
|
+
let employee = await deps.createEmployee(routeContext, creation);
|
|
8
14
|
assertSuccessfulEmployeeOperation('employee creation', employee);
|
|
15
|
+
let licenseOrder;
|
|
16
|
+
const offerId = readEmployeeLicenseOfferId(employee.poll.body);
|
|
17
|
+
if (offerId) {
|
|
18
|
+
if (!input.licenseOrder || !deps.confirmLicenseOrder) {
|
|
19
|
+
throw new Error('provisionOrganizationEmployee: employee creation requires Offer/Order confirmation before licence issue.');
|
|
20
|
+
}
|
|
21
|
+
licenseOrder = await deps.confirmLicenseOrder(routeContext, {
|
|
22
|
+
...input.licenseOrder,
|
|
23
|
+
offerId,
|
|
24
|
+
});
|
|
25
|
+
assertSuccessfulEmployeeOperation('licence order confirmation', licenseOrder);
|
|
26
|
+
employee = await deps.createEmployee(routeContext, creation);
|
|
27
|
+
assertSuccessfulEmployeeOperation('employee creation retry', employee);
|
|
28
|
+
if (readEmployeeLicenseOfferId(employee.poll.body)) {
|
|
29
|
+
throw new Error('provisionOrganizationEmployee: employee creation still requires a licence after Order confirmation.');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
9
32
|
const license = await deps.issueLicense(routeContext, input.invitation);
|
|
10
33
|
assertSuccessfulEmployeeOperation('licence issue', license);
|
|
11
34
|
const activationCode = readEmployeeActivationCode(license.poll.body);
|
|
12
35
|
if (!activationCode) {
|
|
13
36
|
throw new Error('provisionOrganizationEmployee: GW response did not contain an employee activation credential.');
|
|
14
37
|
}
|
|
15
|
-
return { employee, license, activationCode };
|
|
38
|
+
return { employee, license, licenseOrder, activationCode };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Reads the pending seat Offer from an employee-create response.
|
|
42
|
+
*
|
|
43
|
+
* Portal BFFs use this boundary when payment is asynchronous: persist the
|
|
44
|
+
* server-owned creation intent, redirect to hosted Checkout, then submit the
|
|
45
|
+
* paid reference in Order before retrying employee creation and License/_issue.
|
|
46
|
+
*/
|
|
47
|
+
export function readEmployeeLicenseOfferId(value) {
|
|
48
|
+
for (const candidate of nestedRecords(value)) {
|
|
49
|
+
if (candidate.type !== 'Employee-license-offer-v1.0')
|
|
50
|
+
continue;
|
|
51
|
+
const meta = record(candidate.meta);
|
|
52
|
+
const claims = record(meta?.claims);
|
|
53
|
+
const offerId = String(claims?.[ClaimsOfferSchemaorg.identifier] || '').trim();
|
|
54
|
+
if (offerId)
|
|
55
|
+
return offerId;
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
16
58
|
}
|
|
17
59
|
/**
|
|
18
60
|
* Rejects failed outer HTTP responses and failed entries hidden inside a
|
|
@@ -669,14 +669,8 @@ type OrganizationLicenseMutationDeps = {
|
|
|
669
669
|
organizationLicenseActionPollPath: (ctx: RouteContext, action: string) => string;
|
|
670
670
|
submitAndPoll: IndividualLicenseMutationDeps['submitAndPoll'];
|
|
671
671
|
};
|
|
672
|
-
/**
|
|
673
|
-
|
|
674
|
-
* Production callers must use the provider-payment and confirmed Order flow;
|
|
675
|
-
* the gateway enforces that environment boundary independently of this SDK.
|
|
676
|
-
* The request keeps the canonical outer DIDComm identity fields because secure
|
|
677
|
-
* transports sign this envelope before encrypting it for the gateway.
|
|
678
|
-
*/
|
|
679
|
-
export declare function addFreeOrganizationEmployeeLicensesWithDeps(routeCtx: RouteContext, input: OrganizationEmployeeLicenseAddInput, deps: OrganizationLicenseMutationDeps): Promise<SubmitAndPollResult>;
|
|
672
|
+
/** @deprecated Professional seats always use Employee Offer and confirmed Order. */
|
|
673
|
+
export declare function addFreeOrganizationEmployeeLicensesWithDeps(_routeCtx: RouteContext, _input: OrganizationEmployeeLicenseAddInput, _deps: OrganizationLicenseMutationDeps): Promise<SubmitAndPollResult>;
|
|
680
674
|
/**
|
|
681
675
|
* Reserves one available household/member seat for a selected contact.
|
|
682
676
|
*
|
|
@@ -243,29 +243,9 @@ export async function searchIndividualLicensesWithDeps(routeCtx, input, deps) {
|
|
|
243
243
|
export async function listIndividualLicensesWithDeps(routeCtx, input, deps) {
|
|
244
244
|
return searchIndividualLicensesWithDeps(routeCtx, input || {}, deps);
|
|
245
245
|
}
|
|
246
|
-
/**
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
* the gateway enforces that environment boundary independently of this SDK.
|
|
250
|
-
* The request keeps the canonical outer DIDComm identity fields because secure
|
|
251
|
-
* transports sign this envelope before encrypting it for the gateway.
|
|
252
|
-
*/
|
|
253
|
-
export async function addFreeOrganizationEmployeeLicensesWithDeps(routeCtx, input, deps) {
|
|
254
|
-
const entry = buildLicensePurchaseEntry({
|
|
255
|
-
quantity: input.quantity,
|
|
256
|
-
userClass: 'employee',
|
|
257
|
-
type: 'web',
|
|
258
|
-
price: 0,
|
|
259
|
-
priceCurrency: 'EUR',
|
|
260
|
-
});
|
|
261
|
-
return deps.submitAndPoll(deps.organizationLicenseActionPath(routeCtx, '_add'), deps.organizationLicenseActionPollPath(routeCtx, '_add'), {
|
|
262
|
-
jti: `jti-${createRuntimeUuid()}`,
|
|
263
|
-
iss: routeCtx.tenantId,
|
|
264
|
-
aud: routeCtx.tenantId,
|
|
265
|
-
type: 'application/didcomm-plain+json',
|
|
266
|
-
thid: input.requestThid || `organization-license-add-${createRuntimeUuid()}`,
|
|
267
|
-
body: { resourceType: 'Bundle', type: 'batch', data: [entry] },
|
|
268
|
-
}, input.pollOptions);
|
|
246
|
+
/** @deprecated Professional seats always use Employee Offer and confirmed Order. */
|
|
247
|
+
export async function addFreeOrganizationEmployeeLicensesWithDeps(_routeCtx, _input, _deps) {
|
|
248
|
+
throw new Error('Professional seats require Employee Offer and Order payment verification; License/_add is not supported.');
|
|
269
249
|
}
|
|
270
250
|
/**
|
|
271
251
|
* Reserves one available household/member seat for a selected contact.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdc-sdk-node-ts",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.16",
|
|
4
4
|
"description": "Next-generation Node runtime package for the GDC SDK family",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Antifraud Services Inc.",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc -p tsconfig.json",
|
|
15
|
+
"prepare": "npm run build",
|
|
15
16
|
"type-check": "tsc -p tsconfig.json --noEmit",
|
|
16
17
|
"check:product-neutrality": "node scripts/check-product-neutrality.mjs",
|
|
17
18
|
"prepublishOnly": "npm run check:product-neutrality && npm run type-check && npm test",
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"test:e2e:live-gw:clean": "bash ./scripts/run-live-gw-clean.sh"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
40
|
-
"gdc-common-utils-ts": "2.5.
|
|
41
|
+
"gdc-common-utils-ts": "2.5.12",
|
|
41
42
|
"gdc-sdk-core-ts": "~2.3.18"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|