dataspace-client-sdk-node 0.1.2 → 0.2.1
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/CHANGELOG.md +4 -1
- package/README.md +21 -348
- package/dist/client.d.ts +40 -2
- package/dist/client.js +156 -82
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types.d.ts +20 -1
- package/dist/vp-token.d.ts +37 -0
- package/dist/vp-token.js +56 -0
- package/docs/API.md +19 -4
- package/docs/BACKEND_NODE_INTEGRATION.md +138 -8
- package/docs/CONTROLLER_FLOW_STEP_BY_STEP.md +283 -0
- package/docs/DEVELOPER_USE_CASES.md +10 -2
- package/docs/E2E_LOCAL_GW_UC5.md +49 -0
- package/docs/ENDPOINT_ID_CATALOG.md +90 -0
- package/docs/LEGAL_ORGANIZATION_FLOW_STEP_BY_STEP.md +84 -0
- package/docs/PERSONAL_FLOW_STEP_BY_STEP.md +70 -0
- package/docs/PORTAL_BACKEND_INTEGRATION_HANDOVER.md +11 -3
- package/docs/PRACTITIONER_FLOW_STEP_BY_STEP.md +182 -0
- package/examples/e2e-bootstrap-tenant.mjs +3 -2
- package/examples/e2e-individual-flow.mjs +13 -8
- package/examples/host-activate-and-employee.mjs +3 -2
- package/package.json +4 -3
- package/src/client.ts +175 -85
- package/src/index.ts +1 -0
- package/src/types.ts +22 -1
- package/src/vp-token.ts +91 -0
- package/tests/fixtures/ica-vp-minimal.json +67 -0
- package/tests/helpers/vp-token-fixture.mjs +23 -0
- package/tests/live-gw-uc5.e2e.test.mjs +108 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# LEGAL_ORGANIZATION_FLOW_STEP_BY_STEP
|
|
2
|
+
|
|
3
|
+
Canonical legal-organization flow index.
|
|
4
|
+
This file avoids duplicating controller/practitioner details and points to the source guides.
|
|
5
|
+
|
|
6
|
+
## Mandatory rules for integrators
|
|
7
|
+
|
|
8
|
+
Security planes:
|
|
9
|
+
- Transport plane: backend ↔ gateway channel protection (deployment-specific).
|
|
10
|
+
- Identity/business plane: user/controller/member authentication and authorization.
|
|
11
|
+
- Operator/hosting plane: infrastructure/operator lifecycle.
|
|
12
|
+
|
|
13
|
+
Keep these planes separated; do not treat transport credentials as user identity tokens.
|
|
14
|
+
|
|
15
|
+
Secure messaging note:
|
|
16
|
+
- Authentication for controller/member actions is identity-plane (`vp_token`, `idToken`, SMART/client_assertion).
|
|
17
|
+
- Backend-to-service P2P messages can additionally be signed/encrypted (embedded JWS/JWE) according to deployment communication mode.
|
|
18
|
+
|
|
19
|
+
Wallet profile:
|
|
20
|
+
- deterministic key derivation/profile rules are centralized in `BACKEND_NODE_INTEGRATION.md` ("Deterministic Wallet Profile").
|
|
21
|
+
- communication mode (`plain` / `strict` / `auto-detect`) is centralized in `BACKEND_NODE_INTEGRATION.md`.
|
|
22
|
+
|
|
23
|
+
- `jurisdiction` (country) is required in every step.
|
|
24
|
+
- Professional tenants are registered in one jurisdiction and all routes resolve against it.
|
|
25
|
+
- Identity auth routes and business/entity routes are different:
|
|
26
|
+
- identity: `/host/cds-{jurisdiction}/v1/{sector}/{tenantId}/identity/auth/...`
|
|
27
|
+
- business: `/{tenantId}/cds-{jurisdiction}/v1/{sector}/...`
|
|
28
|
+
- `vp_token` is for onboarding proof (`_activate`), not for runtime calls.
|
|
29
|
+
- Controller DCR/token and practitioner DCR/token are distinct flows.
|
|
30
|
+
|
|
31
|
+
## Runtime context pattern (high-level)
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const profileContext = {
|
|
35
|
+
baseUrl: process.env.BASE_URL!,
|
|
36
|
+
jurisdiction: process.env.JURISDICTION!, // REQUIRED
|
|
37
|
+
sector: process.env.SECTOR || 'health-care',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const sessionContext = {
|
|
41
|
+
tenantId: currentSession.tenantId,
|
|
42
|
+
controller: currentSession.controller,
|
|
43
|
+
practitioner: currentSession.practitioner,
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Use `profileContext` for role/organization runtime context and `sessionContext` for logged-in user/session data.
|
|
48
|
+
|
|
49
|
+
## Phase A: controller flow (authoritative)
|
|
50
|
+
|
|
51
|
+
1. Build/sign VP token (`nonce`, no `jti` in VP for this flow).
|
|
52
|
+
2. `_activate` organization in host registry.
|
|
53
|
+
3. Read offer and explicit user acceptance.
|
|
54
|
+
4. Submit `initialOrder`.
|
|
55
|
+
5. Controller DCR bootstrap (`_exchange` then `_dcr`).
|
|
56
|
+
6. Request controller runtime token (`_token`).
|
|
57
|
+
7. Create employee/member in entity route.
|
|
58
|
+
8. Extract activation code for practitioner.
|
|
59
|
+
9. If license seats are exhausted: receive `Employee-license-offer-v1.0`, accept, submit `licenseOrder`, retry employee create.
|
|
60
|
+
|
|
61
|
+
Detailed guide (single source of truth):
|
|
62
|
+
- `CONTROLLER_FLOW_STEP_BY_STEP.md`
|
|
63
|
+
|
|
64
|
+
## Phase B: practitioner flow (authoritative)
|
|
65
|
+
|
|
66
|
+
1. Receive practitioner activation code from controller flow.
|
|
67
|
+
2. Practitioner DCR bootstrap (`_exchange` then `_dcr`).
|
|
68
|
+
3. Request practitioner SMART/runtime token (`_token`) with required scopes.
|
|
69
|
+
4. Call protected organization/business endpoints.
|
|
70
|
+
|
|
71
|
+
Detailed guide (single source of truth):
|
|
72
|
+
- `PRACTITIONER_FLOW_STEP_BY_STEP.md`
|
|
73
|
+
|
|
74
|
+
## Scope of this file
|
|
75
|
+
|
|
76
|
+
- Keep this file as top-level legal organization map.
|
|
77
|
+
- Put implementation details in:
|
|
78
|
+
- `CONTROLLER_FLOW_STEP_BY_STEP.md`
|
|
79
|
+
- `PRACTITIONER_FLOW_STEP_BY_STEP.md`
|
|
80
|
+
- `BACKEND_NODE_INTEGRATION.md`
|
|
81
|
+
|
|
82
|
+
Related references:
|
|
83
|
+
- `ENDPOINT_ID_CATALOG.md`
|
|
84
|
+
- `DATA_MODEL_ALIGNMENT.md`
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# PERSONAL_FLOW_STEP_BY_STEP
|
|
2
|
+
|
|
3
|
+
Canonical flow for personal/family onboarding and consented access.
|
|
4
|
+
|
|
5
|
+
Security note:
|
|
6
|
+
- User authentication/authorization (id-token + scopes + consent) is independent from transport/message protection.
|
|
7
|
+
- Backend may enforce DIDComm message security (JWS/JWE) per deployment policy: `plain` / `strict` / `auto-detect`.
|
|
8
|
+
|
|
9
|
+
## 1) Start individual/family organization onboarding
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const started = await client.startIndividualOrganizationSimple({
|
|
13
|
+
alternateName,
|
|
14
|
+
controllerEmail, // or controllerTelephone
|
|
15
|
+
controllerRole: 'org.hl7.v3.RoleCode|RESPRSN',
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 2) Show offer in UI and accept
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const offerId = started.offerId;
|
|
23
|
+
const offerPreview = started.offerPreview;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 3) Confirm order (always)
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
const order = await client.confirmIndividualOrganizationOrderSimple({ offerId: offerId! });
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 4) Configure consent/preauthorization
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
const consent = await client.grantProfessionalAccessSimple(
|
|
36
|
+
{ tenantId, jurisdiction, sector },
|
|
37
|
+
{
|
|
38
|
+
subjectDid,
|
|
39
|
+
actor: { identifier: practitionerDid },
|
|
40
|
+
actorRole: 'Practitioner',
|
|
41
|
+
purpose: 'TREAT',
|
|
42
|
+
actions: ['organization/Composition.rs'],
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 5) Optional: import/update index data
|
|
48
|
+
|
|
49
|
+
Use your ingestion path (`/publisher/...`) and then subject-side runtime operations.
|
|
50
|
+
|
|
51
|
+
## 6) Professional requests token and reads allowed resources
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
const smart = await client.requestSmartTokenSimple({
|
|
55
|
+
idToken: practitionerIdToken,
|
|
56
|
+
targetEndpoint: client.getEndpointId({
|
|
57
|
+
section: 'organization',
|
|
58
|
+
format: 'org.hl7.fhir.r4',
|
|
59
|
+
resourceType: 'Composition',
|
|
60
|
+
action: '_search',
|
|
61
|
+
}, practitionerDid),
|
|
62
|
+
scopes: ['organization/Composition.rs'],
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Notes
|
|
67
|
+
|
|
68
|
+
- For personal onboarding in GW, verification is integrated in the onboarding flow (`individual/org.schema/Organization/_batch` + `Order/_batch`).
|
|
69
|
+
- Keep Offer/Order UX explicit even when amount is `0`.
|
|
70
|
+
- Use endpoint-id selectors from `docs/ENDPOINT_ID_CATALOG.md`.
|
|
@@ -177,14 +177,17 @@ Even if amount is `0`, user acceptance and Order submission still happen.
|
|
|
177
177
|
SDK method:
|
|
178
178
|
- `createOrganizationEmployee(...)`
|
|
179
179
|
|
|
180
|
+
Use claim constants:
|
|
181
|
+
- `ClaimsPersonSchemaorg` from `gdc-common-utils-ts/constants/schemaorg`
|
|
182
|
+
|
|
180
183
|
```ts
|
|
181
184
|
const employee = await client.createOrganizationEmployee(
|
|
182
185
|
{ tenantId, jurisdiction, sector },
|
|
183
186
|
{
|
|
184
187
|
employeeClaims: {
|
|
185
188
|
'@context': 'org.schema',
|
|
186
|
-
|
|
187
|
-
|
|
189
|
+
[ClaimsPersonSchemaorg.email]: 'doctor@example.com',
|
|
190
|
+
[ClaimsPersonSchemaorg.hasOccupation]: 'ISCO-08|2211',
|
|
188
191
|
},
|
|
189
192
|
},
|
|
190
193
|
);
|
|
@@ -217,7 +220,12 @@ SDK method:
|
|
|
217
220
|
```ts
|
|
218
221
|
const smart = await client.requestSmartTokenSimple({
|
|
219
222
|
idToken: doctorUserIdToken,
|
|
220
|
-
|
|
223
|
+
targetEndpoint: client.getEndpointId({
|
|
224
|
+
section: 'organization',
|
|
225
|
+
format: 'org.hl7.fhir.r4',
|
|
226
|
+
resourceType: 'Composition',
|
|
227
|
+
action: '_search',
|
|
228
|
+
}, doctorDidWeb),
|
|
221
229
|
scopes: ['organization/Composition.rs'],
|
|
222
230
|
});
|
|
223
231
|
```
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# PRACTITIONER_FLOW_STEP_BY_STEP
|
|
2
|
+
|
|
3
|
+
Flow for physician/practitioner employee after controller has issued `activationCode`.
|
|
4
|
+
|
|
5
|
+
## Rules first
|
|
6
|
+
|
|
7
|
+
- `jurisdiction` is mandatory (country context for tenant routing and authorization).
|
|
8
|
+
- `activationCode` is single-use bootstrap material for identity activation.
|
|
9
|
+
- Identity token endpoints and entity/business endpoints are different concerns:
|
|
10
|
+
- identity token flow path: `/host/cds-{jurisdiction}/v1/{sector}/{tenantId}/identity/auth/...`
|
|
11
|
+
- entity/business paths: `/{tenantId}/cds-{jurisdiction}/v1/{sector}/...`
|
|
12
|
+
- Practitioner signs `client_assertion` with their private signing key when required by the token endpoint.
|
|
13
|
+
- Message transport may also use backend wallet JWS/JWE protection (deployment policy: `plain` / `strict` / `auto-detect`).
|
|
14
|
+
|
|
15
|
+
## 1) Receive activation code
|
|
16
|
+
|
|
17
|
+
Input from controller flow:
|
|
18
|
+
- `activationCode`
|
|
19
|
+
|
|
20
|
+
Runtime context:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
const profileContext = {
|
|
24
|
+
baseUrl: process.env.BASE_URL!,
|
|
25
|
+
jurisdiction: process.env.JURISDICTION!, // REQUIRED
|
|
26
|
+
sector: process.env.SECTOR || 'health-care',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const sessionContext = {
|
|
30
|
+
tenantId: currentSession.tenantId,
|
|
31
|
+
practitionerDidWeb: currentSession.practitioner.didWeb,
|
|
32
|
+
practitionerIdToken: currentSession.idToken,
|
|
33
|
+
practitionerPublicJwk: currentSession.practitioner.publicJwk,
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 2) Activate device identity (DCR bootstrap)
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
const client = new DataspaceNodeClient({
|
|
41
|
+
baseUrl: profileContext.baseUrl,
|
|
42
|
+
ctx: {
|
|
43
|
+
tenantId: sessionContext.tenantId,
|
|
44
|
+
jurisdiction: profileContext.jurisdiction,
|
|
45
|
+
sector: profileContext.sector,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const device = await client.activateEmployeeDeviceWithActivationCodeSimple({
|
|
50
|
+
tenantId: sessionContext.tenantId,
|
|
51
|
+
jurisdiction: profileContext.jurisdiction,
|
|
52
|
+
sector: profileContext.sector,
|
|
53
|
+
activationCode,
|
|
54
|
+
idToken: sessionContext.practitionerIdToken,
|
|
55
|
+
dcrPayload: {
|
|
56
|
+
application_type: 'web',
|
|
57
|
+
token_endpoint_auth_method: 'private_key_jwt',
|
|
58
|
+
jwks: { keys: [sessionContext.practitionerPublicJwk] },
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 3) Request SMART token for protected operations
|
|
64
|
+
|
|
65
|
+
`targetEndpoint` is only a local token-target identifier. Authorization is defined by `scopes`.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const smart = await client.requestSmartTokenSimple({
|
|
69
|
+
tenantId: sessionContext.tenantId,
|
|
70
|
+
jurisdiction: profileContext.jurisdiction,
|
|
71
|
+
sector: profileContext.sector,
|
|
72
|
+
idToken: sessionContext.practitionerIdToken,
|
|
73
|
+
targetEndpoint: `smart:practitioner:${sessionContext.practitionerDidWeb}:ips-read`,
|
|
74
|
+
scopes: [
|
|
75
|
+
'organization/Composition.rs',
|
|
76
|
+
'organization/Consent.cruds',
|
|
77
|
+
'organization/Communication.cruds',
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
IPS note:
|
|
83
|
+
- Access to IPS sections is authorized via scopes (for example `organization/Composition.rs`) and consent/policy checks.
|
|
84
|
+
- Do not derive authorization from `targetEndpoint` or from a single endpoint selector.
|
|
85
|
+
|
|
86
|
+
## 3.1) Where JWT signing happens (`private_key_jwt`)
|
|
87
|
+
|
|
88
|
+
If your token endpoint requires `client_assertion` (`private_key_jwt`), the JWT must be signed with the practitioner's/controller's private key.
|
|
89
|
+
|
|
90
|
+
Option A (recommended): SDK signs and sends `client_assertion` for you.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
const token = await client.authenticateBackendSmartStandard({
|
|
94
|
+
clientId: sessionContext.practitionerDidWeb,
|
|
95
|
+
scopes: ['organization/Composition.rs'],
|
|
96
|
+
targetEndpoint: `smart:practitioner:${sessionContext.practitionerDidWeb}:ips-read`,
|
|
97
|
+
tokenUrl: `${profileContext.baseUrl}/token`,
|
|
98
|
+
audience: `${profileContext.baseUrl}/token`,
|
|
99
|
+
walletContext: {
|
|
100
|
+
tenantId: sessionContext.tenantId,
|
|
101
|
+
jurisdiction: profileContext.jurisdiction,
|
|
102
|
+
sector: profileContext.sector,
|
|
103
|
+
},
|
|
104
|
+
publicJwk: sessionContext.practitionerPublicJwk,
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Option B (manual): build/sign JWT yourself, then attach it in token request.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
const now = Math.floor(Date.now() / 1000);
|
|
112
|
+
const encodedHeader = base64url(JSON.stringify({
|
|
113
|
+
alg: 'ES384',
|
|
114
|
+
typ: 'JWT',
|
|
115
|
+
kid: sessionContext.practitionerPublicJwk.kid,
|
|
116
|
+
}));
|
|
117
|
+
const encodedPayload = base64url(JSON.stringify({
|
|
118
|
+
iss: sessionContext.practitionerDidWeb,
|
|
119
|
+
sub: sessionContext.practitionerDidWeb,
|
|
120
|
+
aud: `${profileContext.baseUrl}/token`,
|
|
121
|
+
iat: now,
|
|
122
|
+
exp: now + 300,
|
|
123
|
+
jti: crypto.randomUUID(),
|
|
124
|
+
}));
|
|
125
|
+
const signingInput = `${encodedHeader}.${encodedPayload}`; // what must be signed
|
|
126
|
+
|
|
127
|
+
const signatureBase64Url = await externalSigner(signingInput); // integrator-managed signer
|
|
128
|
+
const clientAssertion = `${encodedHeader}.${encodedPayload}.${signatureBase64Url}`;
|
|
129
|
+
|
|
130
|
+
// Equivalent high-level helper style:
|
|
131
|
+
// const clientAssertion = await wallet.signCompactJws({ header, claims });
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
const tokenRequestBody = {
|
|
136
|
+
grant_type: 'client_credentials',
|
|
137
|
+
client_id: sessionContext.practitionerDidWeb,
|
|
138
|
+
scope: 'organization/Composition.rs organization/Consent.cruds organization/Communication.cruds',
|
|
139
|
+
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
|
|
140
|
+
client_assertion, // signed JWT is attached here
|
|
141
|
+
};
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Integrator note:
|
|
145
|
+
- SDK can help generate/sign compact JWTs, but key custody/signature execution belongs to the integrator.
|
|
146
|
+
- The signer may be wallet SDK, secure enclave, KMS, HSM, or remote signature service.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
// Alternative helper form if your signer abstraction already returns compact JWS:
|
|
150
|
+
const clientAssertion = await wallet.signCompactJws({
|
|
151
|
+
header: {
|
|
152
|
+
alg: 'ES384',
|
|
153
|
+
typ: 'JWT',
|
|
154
|
+
kid: sessionContext.practitionerPublicJwk.kid,
|
|
155
|
+
},
|
|
156
|
+
claims: {
|
|
157
|
+
iss: sessionContext.practitionerDidWeb,
|
|
158
|
+
sub: sessionContext.practitionerDidWeb,
|
|
159
|
+
aud: `${profileContext.baseUrl}/token`,
|
|
160
|
+
iat: now,
|
|
161
|
+
exp: now + 300,
|
|
162
|
+
jti: crypto.randomUUID(),
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
For the current GW `identity/auth/_token` flow documented in this SDK, `requestSmartTokenSimple(...)` is id-token based.
|
|
168
|
+
Use `private_key_jwt` flow when your deployment exposes a standards token endpoint that requires `client_assertion`.
|
|
169
|
+
|
|
170
|
+
## 4) Call protected APIs with returned bearer
|
|
171
|
+
|
|
172
|
+
Use `smart.accessToken` in subsequent requests.
|
|
173
|
+
|
|
174
|
+
Complete path examples:
|
|
175
|
+
- exchange activation code:
|
|
176
|
+
`/host/cds-ES/v1/health-care/{tenantId}/identity/auth/_exchange`
|
|
177
|
+
- DCR:
|
|
178
|
+
`/host/cds-ES/v1/health-care/{tenantId}/identity/auth/_dcr`
|
|
179
|
+
- SMART token:
|
|
180
|
+
`/host/cds-ES/v1/health-care/{tenantId}/identity/auth/_token`
|
|
181
|
+
- example protected entity route (if practitioner is allowed):
|
|
182
|
+
`/{tenantId}/cds-ES/v1/health-care/entity/org.schema/Employee/_search`
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DataspaceNodeClient } from '../dist/index.js';
|
|
2
|
+
import { ClaimsPersonSchemaorg } from 'gdc-common-utils-ts/constants/schemaorg';
|
|
2
3
|
|
|
3
4
|
function parseCsv(value, fallback = []) {
|
|
4
5
|
const items = String(value || '')
|
|
@@ -106,8 +107,8 @@ async function main() {
|
|
|
106
107
|
{
|
|
107
108
|
employeeClaims: {
|
|
108
109
|
'@context': 'org.schema',
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
[ClaimsPersonSchemaorg.email]: process.env.CONTROLLER_EMAIL || 'controller@example.com',
|
|
111
|
+
[ClaimsPersonSchemaorg.hasOccupation]: process.env.CONTROLLER_ROLE || 'ISCO-08|1342',
|
|
111
112
|
},
|
|
112
113
|
},
|
|
113
114
|
pollOptions,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { DataspaceNodeClient, createDidcommPlainMessage } from '../dist/index.js';
|
|
2
|
+
import {
|
|
3
|
+
ClaimsOrganizationSchemaorg,
|
|
4
|
+
ClaimsPersonSchemaorg,
|
|
5
|
+
ClaimsServiceSchemaorg,
|
|
6
|
+
} from 'gdc-common-utils-ts/constants/schemaorg';
|
|
2
7
|
|
|
3
8
|
const baseUrl = process.env.BASE_URL || 'http://localhost:3000';
|
|
4
9
|
const bearerToken = process.env.AUTH_BEARER || 'demo-token';
|
|
@@ -21,14 +26,14 @@ const payload = createDidcommPlainMessage({
|
|
|
21
26
|
claims: {
|
|
22
27
|
'@context': 'org.schema',
|
|
23
28
|
'@type': 'template',
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
[ClaimsOrganizationSchemaorg.addressCountry]: 'ES',
|
|
30
|
+
[ClaimsOrganizationSchemaorg.identifierType]: 'UUID',
|
|
31
|
+
[ClaimsOrganizationSchemaorg.identifierValue]: `family-${Date.now()}`,
|
|
32
|
+
[ClaimsPersonSchemaorg.email]: 'adult1@example.com',
|
|
33
|
+
[ClaimsServiceSchemaorg.category]: ctx.sector,
|
|
34
|
+
[ClaimsServiceSchemaorg.identifier]: 'did:web:api-provider.example.com',
|
|
35
|
+
[ClaimsServiceSchemaorg.serviceType]: 'http://terminology.hl7.org/CodeSystem/v3-ActReason|SRVC',
|
|
36
|
+
[ClaimsServiceSchemaorg.termsOfService]: 'https://provider.example.com/terms',
|
|
32
37
|
},
|
|
33
38
|
},
|
|
34
39
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DataspaceNodeClient, createDidcommPlainMessage } from '../dist/index.js';
|
|
2
|
+
import { ClaimsPersonSchemaorg } from 'gdc-common-utils-ts/constants/schemaorg';
|
|
2
3
|
|
|
3
4
|
const baseUrl = process.env.BASE_URL || 'http://localhost:3000';
|
|
4
5
|
const bearerToken = process.env.AUTH_BEARER || 'demo-token';
|
|
@@ -56,8 +57,8 @@ const employeePayload = createDidcommPlainMessage({
|
|
|
56
57
|
meta: {
|
|
57
58
|
claims: {
|
|
58
59
|
'@context': 'org.schema',
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
[ClaimsPersonSchemaorg.email]: process.env.EMPLOYEE_EMAIL || 'doctor1@acme.org',
|
|
61
|
+
[ClaimsPersonSchemaorg.hasOccupation]: process.env.EMPLOYEE_ROLE || 'ISCO-08|2211',
|
|
61
62
|
},
|
|
62
63
|
},
|
|
63
64
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataspace-client-sdk-node",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Node.js SDK skeleton for GW/UNID DIDComm plain batch + async polling flows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"build": "tsc -p tsconfig.json",
|
|
10
10
|
"type-check": "tsc -p tsconfig.json --noEmit",
|
|
11
11
|
"test": "npm run build && node --test tests/*.test.mjs",
|
|
12
|
-
"example:e2e-bootstrap-tenant": "npm run build && node examples/e2e-bootstrap-tenant.mjs"
|
|
12
|
+
"example:e2e-bootstrap-tenant": "npm run build && node examples/e2e-bootstrap-tenant.mjs",
|
|
13
|
+
"test:e2e:live-gw-uc5": "npm run build && RUN_LIVE_GW_E2E=1 node --test tests/live-gw-uc5.e2e.test.mjs"
|
|
13
14
|
},
|
|
14
15
|
"engines": {
|
|
15
16
|
"node": ">=22"
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
23
|
"@noble/post-quantum": "^0.6.1",
|
|
23
|
-
"gdc-common-utils-ts": "^1.4.
|
|
24
|
+
"gdc-common-utils-ts": "^1.4.12",
|
|
24
25
|
"node-fetch": "^3.3.2"
|
|
25
26
|
}
|
|
26
27
|
}
|