gdc-sdk-node-ts 2.9.10 → 2.9.12
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/individual-onboarding.d.ts +9 -2
- package/dist/individual-onboarding.js +6 -1
- package/dist/individual-start.d.ts +6 -0
- package/dist/individual-start.js +19 -1
- package/dist/orchestration/individual-controller-sdk.d.ts +12 -2
- package/dist/orchestration/individual-controller-sdk.js +7 -2
- package/dist/organization-registration-authorization.d.ts +16 -0
- package/dist/organization-registration-authorization.js +34 -0
- package/dist/server-profile-session.d.ts +30 -1
- package/dist/server-profile-session.js +69 -14
- package/package.json +1 -1
|
@@ -28,8 +28,15 @@ export type IndividualOrganizationConfirmOrderInput = {
|
|
|
28
28
|
export type IndividualOrganizationOrderResult = SubmitAndPollResult & Readonly<{
|
|
29
29
|
activationCode: string;
|
|
30
30
|
/**
|
|
31
|
-
* Governed RelatedPerson
|
|
32
|
-
* the principal Organization owner/controller.
|
|
31
|
+
* Governed `RelatedPerson.identifier` automatically materialized by GW for
|
|
32
|
+
* the principal Organization owner/controller. GW reuses the bare UUID from
|
|
33
|
+
* `Organization.owner.identifier.value`; document helpers expose it as an
|
|
34
|
+
* `urn:uuid:<UUID>` FHIR reference only when a reference is required.
|
|
35
|
+
*/
|
|
36
|
+
controllerRelatedPersonIdentifier: string;
|
|
37
|
+
/**
|
|
38
|
+
* @deprecated Use `controllerRelatedPersonIdentifier`, which states the
|
|
39
|
+
* resource represented by this identifier.
|
|
33
40
|
*/
|
|
34
41
|
controllerAssignmentIdentifier: string;
|
|
35
42
|
}>;
|
|
@@ -44,7 +44,12 @@ export async function confirmIndividualOrganizationOrderWithDeps(deps) {
|
|
|
44
44
|
if (!controllerAssignmentIdentifier) {
|
|
45
45
|
throw new Error('confirmIndividualOrganizationOrder failed: missing automatic controller RESPRSN assignment in GW Order response.');
|
|
46
46
|
}
|
|
47
|
-
return {
|
|
47
|
+
return {
|
|
48
|
+
...order,
|
|
49
|
+
activationCode,
|
|
50
|
+
controllerRelatedPersonIdentifier: controllerAssignmentIdentifier,
|
|
51
|
+
controllerAssignmentIdentifier,
|
|
52
|
+
};
|
|
48
53
|
}
|
|
49
54
|
/**
|
|
50
55
|
* Reads the opaque controller activation code from a completed individual
|
|
@@ -53,6 +53,12 @@ export type IndividualOrganizationRegistrationInput = {
|
|
|
53
53
|
* a product gateway extension.
|
|
54
54
|
*/
|
|
55
55
|
controllerTelephone?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Stable UUID of the principal controller/RESPRSN assignment. In a self
|
|
58
|
+
* registration this may be the same UUID already assigned to the person.
|
|
59
|
+
* Omit only for a brand-new assignment so the SDK creates it once.
|
|
60
|
+
*/
|
|
61
|
+
controllerIdentifier?: string;
|
|
56
62
|
controllerRole?: string;
|
|
57
63
|
additionalClaims?: Record<string, unknown>;
|
|
58
64
|
timeoutSeconds?: number;
|
package/dist/individual-start.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
2
3
|
import { ClaimsOfferSchemaorg, ClaimsOrganizationSchemaorg, ClaimsPersonSchemaorg, ClaimsServiceSchemaorg, } from 'gdc-common-utils-ts/constants';
|
|
3
|
-
import { buildIndividualDidWeb, buildSecureIdValueIndividual, extractPrimaryClaims, readFamilyOrganizationSummaryFromResponseBody, SecureIdTypesIndividual, } from 'gdc-common-utils-ts';
|
|
4
|
+
import { buildIndividualDidWeb, buildSecureIdValueIndividual, extractPrimaryClaims, normalizeUuid, readFamilyOrganizationSummaryFromResponseBody, SecureIdTypesIndividual, } from 'gdc-common-utils-ts';
|
|
4
5
|
export { buildIndividualMemberDidWebFromPrivateIdentifiers } from 'gdc-common-utils-ts';
|
|
5
6
|
import { GwCoreLifecycleRequestType } from './constants/lifecycle.js';
|
|
6
7
|
import { resolvePollOptionsFromSeconds } from './poll-options.js';
|
|
@@ -32,10 +33,14 @@ export async function registerIndividualOrganizationWithDeps(deps) {
|
|
|
32
33
|
throw new Error('registerIndividualOrganization requires controllerEmail, or controllerTelephone only for compatibility/extension flows.');
|
|
33
34
|
}
|
|
34
35
|
const controllerRole = String(deps.input.controllerRole || 'RESPRSN').trim();
|
|
36
|
+
const controllerIdentifier = canonicalControllerUuid(deps.input.controllerIdentifier
|
|
37
|
+
|| deps.input.additionalClaims?.[ClaimsOrganizationSchemaorg.ownerIdentifierValue]
|
|
38
|
+
|| randomUUID());
|
|
35
39
|
const claims = {
|
|
36
40
|
'@context': 'org.schema',
|
|
37
41
|
...(deps.input.additionalClaims || {}),
|
|
38
42
|
[ClaimsOrganizationSchemaorg.alternateName]: alternateName,
|
|
43
|
+
[ClaimsOrganizationSchemaorg.ownerIdentifierValue]: controllerIdentifier,
|
|
39
44
|
[ClaimsServiceSchemaorg.category]: deps.routeCtx.sector,
|
|
40
45
|
[ClaimsPersonSchemaorg.hasOccupationalRoleValue]: controllerRole,
|
|
41
46
|
...(controllerEmail
|
|
@@ -93,6 +98,19 @@ export async function registerIndividualOrganizationWithDeps(deps) {
|
|
|
93
98
|
identity: readIndividualOrganizationBootstrapIdentity(registration.poll.body),
|
|
94
99
|
};
|
|
95
100
|
}
|
|
101
|
+
function canonicalControllerUuid(value) {
|
|
102
|
+
const hexadecimal = normalizeUuid(String(value || '').trim());
|
|
103
|
+
if (!hexadecimal) {
|
|
104
|
+
throw new TypeError('controllerIdentifier must be a UUID or urn:uuid identifier.');
|
|
105
|
+
}
|
|
106
|
+
return [
|
|
107
|
+
hexadecimal.slice(0, 8),
|
|
108
|
+
hexadecimal.slice(8, 12),
|
|
109
|
+
hexadecimal.slice(12, 16),
|
|
110
|
+
hexadecimal.slice(16, 20),
|
|
111
|
+
hexadecimal.slice(20),
|
|
112
|
+
].join('-');
|
|
113
|
+
}
|
|
96
114
|
/** @deprecated Use `registerIndividualOrganizationWithDeps`. */
|
|
97
115
|
export async function startIndividualOrganizationWithDeps(deps) {
|
|
98
116
|
return registerIndividualOrganizationWithDeps(deps);
|
|
@@ -9,6 +9,15 @@ import type { NodeCapability } from '../session.js';
|
|
|
9
9
|
import type { IndividualOrganizationLifecycleInput } from 'gdc-sdk-core-ts';
|
|
10
10
|
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, SubjectSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, DigitalTwinSecondaryUseConsentInput, DigitalTwinSecondaryUseConsentResult, DigitalTwinSubjectLinkPurgeInput, DigitalTwinSubjectLinkPurgeResult, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, ProfessionalAccessRequestDecisionInput, ProfessionalAccessRequestSearchInput, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
11
11
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
12
|
+
/** Profile-owned defaults applied to subject-section mutations after unlock. */
|
|
13
|
+
export type IndividualControllerProfileDefaults = Readonly<{
|
|
14
|
+
attester: SubjectSectionUpdateInput['attester'];
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* High-level section input. An opened controller profile supplies its own
|
|
18
|
+
* protected RESPRSN attester; standalone facades must still provide one.
|
|
19
|
+
*/
|
|
20
|
+
export type IndividualControllerSubjectSectionUpdateInput = Omit<SubjectSectionUpdateInput, 'attester'> & Partial<Pick<SubjectSectionUpdateInput, 'attester'>>;
|
|
12
21
|
/**
|
|
13
22
|
* Individual-controller oriented facade over a `NodeRuntimeClient`.
|
|
14
23
|
*
|
|
@@ -18,10 +27,11 @@ import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-
|
|
|
18
27
|
export declare class IndividualControllerSdk {
|
|
19
28
|
private readonly client;
|
|
20
29
|
private readonly capabilities?;
|
|
30
|
+
private readonly profileDefaults?;
|
|
21
31
|
/**
|
|
22
32
|
* @param client Runtime client implementation used to submit and poll GW flows.
|
|
23
33
|
*/
|
|
24
|
-
constructor(client: NodeRuntimeClient, capabilities?: readonly NodeCapability[] | undefined);
|
|
34
|
+
constructor(client: NodeRuntimeClient, capabilities?: readonly NodeCapability[] | undefined, profileDefaults?: IndividualControllerProfileDefaults | undefined);
|
|
25
35
|
/**
|
|
26
36
|
* Registers the personal organization/subject index and returns its Offer.
|
|
27
37
|
* Wallet creation, activation exchange, DCR, and session opening are later
|
|
@@ -118,7 +128,7 @@ export declare class IndividualControllerSdk {
|
|
|
118
128
|
* appointments or contracts, while preserving the indexed Composition
|
|
119
129
|
* author/attester compatibility contract.
|
|
120
130
|
*/
|
|
121
|
-
updateSubjectSection(ctx: RouteContext, input:
|
|
131
|
+
updateSubjectSection(ctx: RouteContext, input: IndividualControllerSubjectSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
122
132
|
/**
|
|
123
133
|
* Updates the multi-section summary through a Composition-first document.
|
|
124
134
|
* On a direct call, use the authenticated profile `actorDid` as `sender` and
|
|
@@ -18,9 +18,10 @@ export class IndividualControllerSdk {
|
|
|
18
18
|
/**
|
|
19
19
|
* @param client Runtime client implementation used to submit and poll GW flows.
|
|
20
20
|
*/
|
|
21
|
-
constructor(client, capabilities) {
|
|
21
|
+
constructor(client, capabilities, profileDefaults) {
|
|
22
22
|
this.client = client;
|
|
23
23
|
this.capabilities = capabilities;
|
|
24
|
+
this.profileDefaults = profileDefaults;
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
27
|
* Registers the personal organization/subject index and returns its Offer.
|
|
@@ -173,7 +174,11 @@ export class IndividualControllerSdk {
|
|
|
173
174
|
*/
|
|
174
175
|
updateSubjectSection(ctx, input) {
|
|
175
176
|
assertFacadeCapability(this.capabilities, ActorCapabilities.IndividualIngestCommunication, ActorKinds.IndividualController, 'updateSubjectSection');
|
|
176
|
-
|
|
177
|
+
const attester = input.attester || this.profileDefaults?.attester;
|
|
178
|
+
if (!attester) {
|
|
179
|
+
throw new Error('updateSubjectSection requires an explicit attester unless the facade comes from an opened controller profile.');
|
|
180
|
+
}
|
|
181
|
+
return requireClientMethod(this.client, 'updateSubjectSection')(ctx, { ...input, attester });
|
|
177
182
|
}
|
|
178
183
|
/**
|
|
179
184
|
* Updates the multi-section summary through a Composition-first document.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { VerifiableCredentialV2 } from 'gdc-common-utils-ts/models/verifiable-credential';
|
|
2
|
+
import type { IWallet, WalletExecutionContext, WalletKeySelection } from 'gdc-sdk-core-ts';
|
|
3
|
+
/** Input required to add one human-authorizer proof to the out-of-band VC. */
|
|
4
|
+
export type SignOrganizationRegistrationAuthorizationInput = Readonly<{
|
|
5
|
+
credential: VerifiableCredentialV2;
|
|
6
|
+
wallet: IWallet;
|
|
7
|
+
context: WalletExecutionContext;
|
|
8
|
+
key: WalletKeySelection;
|
|
9
|
+
verificationMethod: string;
|
|
10
|
+
createdAt?: string;
|
|
11
|
+
}>;
|
|
12
|
+
/**
|
|
13
|
+
* Adds one detached JWS proof made by the already-unlocked professional
|
|
14
|
+
* profile. The browser never receives the private key or clear wallet seed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function signOrganizationRegistrationAuthorizationCredential(input: SignOrganizationRegistrationAuthorizationInput): Promise<VerifiableCredentialV2>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { canonicalizeOrganizationRegistrationAuthorizationCredential, } from 'gdc-common-utils-ts/utils/organization-registration-authorization';
|
|
2
|
+
/**
|
|
3
|
+
* Adds one detached JWS proof made by the already-unlocked professional
|
|
4
|
+
* profile. The browser never receives the private key or clear wallet seed.
|
|
5
|
+
*/
|
|
6
|
+
export async function signOrganizationRegistrationAuthorizationCredential(input) {
|
|
7
|
+
if (!input.wallet.signDetachedJws) {
|
|
8
|
+
throw new Error('Wallet does not support detached organization authorization proofs.');
|
|
9
|
+
}
|
|
10
|
+
const verificationMethod = String(input.verificationMethod || '').trim();
|
|
11
|
+
if (!verificationMethod)
|
|
12
|
+
throw new Error('Organization authorization proof requires verificationMethod.');
|
|
13
|
+
const payload = canonicalizeOrganizationRegistrationAuthorizationCredential(input.credential);
|
|
14
|
+
const jws = await input.wallet.signDetachedJws(input.context, {
|
|
15
|
+
payload,
|
|
16
|
+
header: { typ: 'application/vc+ld+json' },
|
|
17
|
+
key: input.key,
|
|
18
|
+
});
|
|
19
|
+
const existingProofs = Array.isArray(input.credential.proof)
|
|
20
|
+
? input.credential.proof
|
|
21
|
+
: input.credential.proof
|
|
22
|
+
? [input.credential.proof]
|
|
23
|
+
: [];
|
|
24
|
+
return {
|
|
25
|
+
...input.credential,
|
|
26
|
+
proof: [...existingProofs, {
|
|
27
|
+
type: 'JsonWebSignature2020',
|
|
28
|
+
created: input.createdAt || new Date().toISOString(),
|
|
29
|
+
proofPurpose: 'contractAgreement',
|
|
30
|
+
verificationMethod,
|
|
31
|
+
jws,
|
|
32
|
+
}],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -11,7 +11,8 @@ import { ProfessionalSdk } from './orchestration/professional-sdk.js';
|
|
|
11
11
|
import { DigitalTwinSdk } from './orchestration/digital-twin-sdk.js';
|
|
12
12
|
import type { SmartTokenExchangeResult } from './smart-token.js';
|
|
13
13
|
import type { DigitalTwinSearchInput, DigitalTwinSearchResult } from './digital-twin.js';
|
|
14
|
-
import type { RouteContext } from './individual-onboarding.js';
|
|
14
|
+
import type { IndividualOrganizationOrderResult, RouteContext } from './individual-onboarding.js';
|
|
15
|
+
import type { IndividualOrganizationRegistrationResult } from './individual-start.js';
|
|
15
16
|
import type { HostRouteContext } from './host-onboarding.js';
|
|
16
17
|
import type { SecureDidcommTransportAdapter } from 'gdc-sdk-core-ts';
|
|
17
18
|
import { type PinProtectedProfileSecret, type ProfileProtectionOptions, type ServerProfileSealer } from './server-profile-protection.js';
|
|
@@ -145,6 +146,13 @@ export type ServerProfileEnrollmentInput = Readonly<{
|
|
|
145
146
|
idToken: string;
|
|
146
147
|
/** One-time code returned by the completed organization flow or employee `License/_issue`. */
|
|
147
148
|
activationCode: string;
|
|
149
|
+
/**
|
|
150
|
+
* Principal controller identifier projected by the SDK from
|
|
151
|
+
* `Organization.owner.identifier.value` and the matching automatic
|
|
152
|
+
* `RelatedPerson.identifier`. Individual-controller callers pass this
|
|
153
|
+
* identifier; the SDK constructs protected document-attester metadata.
|
|
154
|
+
*/
|
|
155
|
+
controllerRelatedPersonIdentifier?: string;
|
|
148
156
|
/**
|
|
149
157
|
* Optional explicit installation identity. Normally omit it so the SDK
|
|
150
158
|
* derives the identity from the wallet key it creates for this profile.
|
|
@@ -292,6 +300,20 @@ export type OpenedServerIndividualController = Readonly<{
|
|
|
292
300
|
session: ResolvedServerProfileSession;
|
|
293
301
|
profile: ServerProfileRecord;
|
|
294
302
|
sdk: IndividualControllerSdk;
|
|
303
|
+
/** Returns the protected RelatedPerson URI for FHIR document attestation. */
|
|
304
|
+
getAttesterUriForDocs(): string;
|
|
305
|
+
}>;
|
|
306
|
+
/** One-time self-controller enrollment. It never opens a working session. */
|
|
307
|
+
export type ServerSelfIndividualControllerEnrollmentInput = Readonly<{
|
|
308
|
+
ownerId: string;
|
|
309
|
+
profileId: string;
|
|
310
|
+
registration: Pick<IndividualOrganizationRegistrationResult, 'identity'>;
|
|
311
|
+
order: Pick<IndividualOrganizationOrderResult, 'activationCode' | 'controllerRelatedPersonIdentifier'>;
|
|
312
|
+
routeContext: RouteContext;
|
|
313
|
+
pin: string;
|
|
314
|
+
idToken: string;
|
|
315
|
+
redirectUris: string[];
|
|
316
|
+
clientName: string;
|
|
295
317
|
}>;
|
|
296
318
|
/** Server-owned role evidence used to sign a fresh professional VP. */
|
|
297
319
|
export type ServerProfessionalProofInput = Readonly<{
|
|
@@ -383,6 +405,13 @@ export declare class ServerProfileSessionManager {
|
|
|
383
405
|
*/
|
|
384
406
|
sourceAuthor?: ClinicalSourceAuthorSelection;
|
|
385
407
|
}>): Promise<ClinicalCreatorIpsExport>;
|
|
408
|
+
/**
|
|
409
|
+
* Enrolls the controller of a self-managed individual from SDK-owned
|
|
410
|
+
* registration and Order projections. The caller never parses claims or
|
|
411
|
+
* constructs FHIR attester metadata, and this operation does not open the
|
|
412
|
+
* resulting profile.
|
|
413
|
+
*/
|
|
414
|
+
enrollSelfIndividualController(input: ServerSelfIndividualControllerEnrollmentInput): Promise<ServerProfileRecord>;
|
|
386
415
|
enroll(input: ServerProfileEnrollmentInput): Promise<ServerProfileRecord>;
|
|
387
416
|
/**
|
|
388
417
|
* Rotates an employee wallet after a fresh OTP-authenticated GW recovery.
|
|
@@ -24,20 +24,23 @@ import { ProfilePinRejectedError, openServerProfileSecret, protectServerProfileS
|
|
|
24
24
|
* RelatedPerson/PractitionerRole assignment returned by GW.
|
|
25
25
|
*/
|
|
26
26
|
export function buildProfileAttester(input) {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
const assignmentIdentifier = String(input.assignmentIdentifier || '').trim();
|
|
28
|
+
const hexadecimal = normalizeUuid(assignmentIdentifier);
|
|
29
|
+
const reference = hexadecimal
|
|
30
|
+
? `${UrnPrefixes.Uuid}${[
|
|
31
|
+
hexadecimal.slice(0, 8),
|
|
32
|
+
hexadecimal.slice(8, 12),
|
|
33
|
+
hexadecimal.slice(12, 16),
|
|
34
|
+
hexadecimal.slice(16, 20),
|
|
35
|
+
hexadecimal.slice(20),
|
|
36
|
+
].join('-')}`
|
|
37
|
+
: assignmentIdentifier;
|
|
38
|
+
if (!/^(?:urn:|https?:\/\/)/i.test(reference)) {
|
|
39
|
+
throw new TypeError('Profile attester assignmentIdentifier must be a governed RelatedPerson or PractitionerRole URI.');
|
|
40
|
+
}
|
|
38
41
|
return Object.freeze({
|
|
39
42
|
mode: input.mode,
|
|
40
|
-
party: Object.freeze({ reference
|
|
43
|
+
party: Object.freeze({ reference }),
|
|
41
44
|
});
|
|
42
45
|
}
|
|
43
46
|
/**
|
|
@@ -76,11 +79,46 @@ export class ServerProfileSessionManager {
|
|
|
76
79
|
async exportClinicalCreatorIps(input) {
|
|
77
80
|
return exportServerProfileClinicalCreatorIps(await this.requireOwnedProfile(input.ownerId, input.profileId), { sourceAuthor: input.sourceAuthor });
|
|
78
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Enrolls the controller of a self-managed individual from SDK-owned
|
|
84
|
+
* registration and Order projections. The caller never parses claims or
|
|
85
|
+
* constructs FHIR attester metadata, and this operation does not open the
|
|
86
|
+
* resulting profile.
|
|
87
|
+
*/
|
|
88
|
+
async enrollSelfIndividualController(input) {
|
|
89
|
+
const identity = input.registration.identity;
|
|
90
|
+
if (!identity) {
|
|
91
|
+
throw new Error('Self individual-controller enrollment requires the registered individual identity.');
|
|
92
|
+
}
|
|
93
|
+
return this.enroll({
|
|
94
|
+
ownerId: input.ownerId,
|
|
95
|
+
profileId: input.profileId,
|
|
96
|
+
actorKind: ActorKinds.IndividualController,
|
|
97
|
+
actorMode: 'self',
|
|
98
|
+
actorDid: identity.subjectDid,
|
|
99
|
+
profileDid: identity.subjectDid,
|
|
100
|
+
providerDid: identity.providerDidWeb,
|
|
101
|
+
routeContext: input.routeContext,
|
|
102
|
+
allowedSubjectDids: [identity.subjectDid],
|
|
103
|
+
pin: input.pin,
|
|
104
|
+
idToken: input.idToken,
|
|
105
|
+
activationCode: input.order.activationCode,
|
|
106
|
+
controllerRelatedPersonIdentifier: input.order.controllerRelatedPersonIdentifier,
|
|
107
|
+
redirectUris: input.redirectUris,
|
|
108
|
+
clientName: input.clientName,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
79
111
|
async enroll(input) {
|
|
80
112
|
const normalizedClinicalCreatorBinding = input.clinicalCreatorBinding
|
|
81
113
|
? normalizeClinicalCreatorBinding(input.clinicalCreatorBinding)
|
|
82
114
|
: undefined;
|
|
83
|
-
const
|
|
115
|
+
const controllerAttester = input.controllerRelatedPersonIdentifier
|
|
116
|
+
? buildProfileAttester({
|
|
117
|
+
assignmentIdentifier: input.controllerRelatedPersonIdentifier,
|
|
118
|
+
mode: CompositionAttesterModes.Personal,
|
|
119
|
+
})
|
|
120
|
+
: undefined;
|
|
121
|
+
const attester = controllerAttester || input.attester || (normalizedClinicalCreatorBinding
|
|
84
122
|
? buildProfileAttester({
|
|
85
123
|
assignmentIdentifier: normalizedClinicalCreatorBinding.authorIdentifier,
|
|
86
124
|
mode: normalizedClinicalCreatorBinding.kind === FhirIpsCreatorKinds.Professional
|
|
@@ -562,6 +600,10 @@ export class ServerProfileSessionManager {
|
|
|
562
600
|
|| (profile.actorMode !== 'self' && profile.actorMode !== 'controller')) {
|
|
563
601
|
throw new Error('Profile is not an individual controller.');
|
|
564
602
|
}
|
|
603
|
+
const profileAttester = profile.attester;
|
|
604
|
+
if (!profileAttester) {
|
|
605
|
+
throw new Error('The opened individual-controller profile has no RelatedPerson attester.');
|
|
606
|
+
}
|
|
565
607
|
const client = new NodeHttpClient({
|
|
566
608
|
baseUrl: this.options.gatewayBaseUrl,
|
|
567
609
|
ctx: profile.routeContext,
|
|
@@ -571,7 +613,20 @@ export class ServerProfileSessionManager {
|
|
|
571
613
|
transportProfile: TransportProfiles.DidcommEncryptedForm,
|
|
572
614
|
secureTransportAdapter: session.secureTransportAdapter,
|
|
573
615
|
});
|
|
574
|
-
return {
|
|
616
|
+
return {
|
|
617
|
+
session,
|
|
618
|
+
profile,
|
|
619
|
+
sdk: new IndividualControllerSdk(client, undefined, {
|
|
620
|
+
attester: profileAttester,
|
|
621
|
+
}),
|
|
622
|
+
getAttesterUriForDocs: () => {
|
|
623
|
+
const reference = String(profileAttester.party.reference || '').trim();
|
|
624
|
+
if (!reference) {
|
|
625
|
+
throw new Error('The opened individual-controller profile has no RelatedPerson attester URI.');
|
|
626
|
+
}
|
|
627
|
+
return reference;
|
|
628
|
+
},
|
|
629
|
+
};
|
|
575
630
|
}
|
|
576
631
|
/**
|
|
577
632
|
* Opens the high-level organization-controller API without exposing wallet,
|