gdc-sdk-node-ts 2.0.8 → 2.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/UserProfileIndexStore.d.ts +47 -0
- package/dist/UserProfileIndexStore.js +66 -0
- package/dist/UserProfileIndexStore.types.d.ts +16 -0
- package/dist/UserProfileIndexStore.types.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/node-crypto-helper.d.ts +19 -0
- package/dist/node-crypto-helper.js +27 -0
- package/dist/node-managed-wallet.d.ts +154 -0
- package/dist/node-managed-wallet.js +604 -0
- package/dist/resource-operations.d.ts +13 -3
- package/dist/resource-operations.js +10 -0
- package/dist/wallet-backed-job-manager.d.ts +19 -0
- package/dist/wallet-backed-job-manager.js +301 -0
- package/dist/wallet-backed-job-manager.types.d.ts +57 -0
- package/dist/wallet-backed-job-manager.types.js +2 -0
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -208,7 +208,7 @@ Current live `101` flow covered by the test suite:
|
|
|
208
208
|
Run the main live `101`:
|
|
209
209
|
|
|
210
210
|
```bash
|
|
211
|
-
npm run test:e2e:
|
|
211
|
+
npm run test:e2e:live-full-cycle
|
|
212
212
|
```
|
|
213
213
|
|
|
214
214
|
What is still not fully covered as one single root lifecycle:
|
|
@@ -694,6 +694,9 @@ Existing-tenant recovery/reverification:
|
|
|
694
694
|
or directly `_exchange -> _dcr`
|
|
695
695
|
- for a reproducible local/staging runtime check, use:
|
|
696
696
|
`npm run test:e2e:live-gw:issue-recovery`
|
|
697
|
+
- for the deterministic controller-lifecycle contract that also proves
|
|
698
|
+
post-registration seat preservation and final tenant teardown, use:
|
|
699
|
+
[docs/101-ORGANIZATION_CONTROLLER_LIFECYCLE.md](docs/101-ORGANIZATION_CONTROLLER_LIFECYCLE.md)
|
|
697
700
|
|
|
698
701
|
Rules:
|
|
699
702
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { IVaultRepository, UserProfileLookupKey } from 'gdc-sdk-core-ts';
|
|
2
|
+
import type { UserProfileIndexRecord } from './UserProfileIndexStore.types.js';
|
|
3
|
+
export type { UserProfileIndexRecord } from './UserProfileIndexStore.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Node/server persistence adapter for hashed local user-profile indexes.
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - store ordered local profile indexes
|
|
9
|
+
* - list stored index documents
|
|
10
|
+
* - resolve one index by hashed lookup key before PIN unlock
|
|
11
|
+
*
|
|
12
|
+
* Non-responsibilities:
|
|
13
|
+
* - hashing raw email/phone input
|
|
14
|
+
* - unlocking profiles with PIN
|
|
15
|
+
* - storing seeds or decrypted private key material
|
|
16
|
+
*/
|
|
17
|
+
export declare class UserProfileIndexStore {
|
|
18
|
+
private readonly vault;
|
|
19
|
+
constructor(vault: IVaultRepository);
|
|
20
|
+
/**
|
|
21
|
+
* Initializes the underlying storage adapter.
|
|
22
|
+
*/
|
|
23
|
+
initialize(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Creates or replaces one stored user-profile index record.
|
|
26
|
+
*/
|
|
27
|
+
upsert(record: UserProfileIndexRecord): Promise<UserProfileIndexRecord>;
|
|
28
|
+
/**
|
|
29
|
+
* Returns every stored user-profile index record.
|
|
30
|
+
*/
|
|
31
|
+
list(): Promise<UserProfileIndexRecord[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Returns one stored index by storage id.
|
|
34
|
+
*/
|
|
35
|
+
get(id: string): Promise<UserProfileIndexRecord | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* Resolves the first stored index that contains the given hashed lookup key.
|
|
38
|
+
*
|
|
39
|
+
* This intentionally compares hashed lookup tokens only. Raw phone/email
|
|
40
|
+
* values are outside this store contract.
|
|
41
|
+
*/
|
|
42
|
+
findByLookup(lookup: UserProfileLookupKey): Promise<UserProfileIndexRecord | undefined>;
|
|
43
|
+
/**
|
|
44
|
+
* Deletes one stored index by storage id.
|
|
45
|
+
*/
|
|
46
|
+
remove(id: string): Promise<boolean>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
const COLLECTION = 'user-profile-index';
|
|
3
|
+
/**
|
|
4
|
+
* Node/server persistence adapter for hashed local user-profile indexes.
|
|
5
|
+
*
|
|
6
|
+
* Responsibilities:
|
|
7
|
+
* - store ordered local profile indexes
|
|
8
|
+
* - list stored index documents
|
|
9
|
+
* - resolve one index by hashed lookup key before PIN unlock
|
|
10
|
+
*
|
|
11
|
+
* Non-responsibilities:
|
|
12
|
+
* - hashing raw email/phone input
|
|
13
|
+
* - unlocking profiles with PIN
|
|
14
|
+
* - storing seeds or decrypted private key material
|
|
15
|
+
*/
|
|
16
|
+
export class UserProfileIndexStore {
|
|
17
|
+
constructor(vault) {
|
|
18
|
+
this.vault = vault;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Initializes the underlying storage adapter.
|
|
22
|
+
*/
|
|
23
|
+
async initialize() {
|
|
24
|
+
await this.vault.initialize();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Creates or replaces one stored user-profile index record.
|
|
28
|
+
*/
|
|
29
|
+
async upsert(record) {
|
|
30
|
+
await this.vault.put(COLLECTION, record);
|
|
31
|
+
return record;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns every stored user-profile index record.
|
|
35
|
+
*/
|
|
36
|
+
async list() {
|
|
37
|
+
return this.vault.query(COLLECTION, {});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns one stored index by storage id.
|
|
41
|
+
*/
|
|
42
|
+
async get(id) {
|
|
43
|
+
return this.vault.get(COLLECTION, id);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolves the first stored index that contains the given hashed lookup key.
|
|
47
|
+
*
|
|
48
|
+
* This intentionally compares hashed lookup tokens only. Raw phone/email
|
|
49
|
+
* values are outside this store contract.
|
|
50
|
+
*/
|
|
51
|
+
async findByLookup(lookup) {
|
|
52
|
+
const records = await this.list();
|
|
53
|
+
return records.find((record) => record.lookup.some((item) => lookupEquals(item, lookup)));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Deletes one stored index by storage id.
|
|
57
|
+
*/
|
|
58
|
+
async remove(id) {
|
|
59
|
+
return this.vault.delete(COLLECTION, id);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function lookupEquals(left, right) {
|
|
63
|
+
return left.kind === right.kind
|
|
64
|
+
&& left.algorithm === right.algorithm
|
|
65
|
+
&& left.value === right.value;
|
|
66
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { UserProfileIndex } from 'gdc-sdk-core-ts';
|
|
2
|
+
/**
|
|
3
|
+
* Persisted local user-profile index document for node/server runtimes.
|
|
4
|
+
*
|
|
5
|
+
* The shared `UserProfileIndex` contract from `gdc-sdk-core-ts` is
|
|
6
|
+
* runtime-neutral and intentionally omits any storage identifier. Node
|
|
7
|
+
* runtimes need a stable document id so one logical index record can be
|
|
8
|
+
* replaced atomically in a concrete vault adapter such as Firestore, Redis,
|
|
9
|
+
* SQLite, or an in-memory test vault.
|
|
10
|
+
*/
|
|
11
|
+
export interface UserProfileIndexRecord extends UserProfileIndex {
|
|
12
|
+
/**
|
|
13
|
+
* Stable storage identifier for one local profile-index document.
|
|
14
|
+
*/
|
|
15
|
+
id: string;
|
|
16
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export * from './order-offer-summary.js';
|
|
|
19
19
|
export * from './organization-license-order.js';
|
|
20
20
|
export * from './resource-operations.js';
|
|
21
21
|
export * from './profile-workspace.js';
|
|
22
|
+
export * from './UserProfileIndexStore.js';
|
|
23
|
+
export * from './wallet-backed-job-manager.js';
|
|
24
|
+
export * from './node-crypto-helper.js';
|
|
25
|
+
export * from './node-managed-wallet.js';
|
|
22
26
|
export * from './constants/lifecycle.js';
|
|
23
27
|
export * from './consent-claim-helpers.js';
|
|
24
28
|
export * from './session.js';
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,10 @@ export * from './order-offer-summary.js';
|
|
|
20
20
|
export * from './organization-license-order.js';
|
|
21
21
|
export * from './resource-operations.js';
|
|
22
22
|
export * from './profile-workspace.js';
|
|
23
|
+
export * from './UserProfileIndexStore.js';
|
|
24
|
+
export * from './wallet-backed-job-manager.js';
|
|
25
|
+
export * from './node-crypto-helper.js';
|
|
26
|
+
export * from './node-managed-wallet.js';
|
|
23
27
|
export * from './constants/lifecycle.js';
|
|
24
28
|
export * from './consent-claim-helpers.js';
|
|
25
29
|
export * from './session.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ICryptoHelper } from 'gdc-common-utils-ts/interfaces/ICryptoHelper';
|
|
2
|
+
/**
|
|
3
|
+
* Node.js implementation of the low-level crypto helper contract used by
|
|
4
|
+
* `CryptographyService` and managed wallet adapters.
|
|
5
|
+
*/
|
|
6
|
+
export declare class NodeCryptoHelper implements ICryptoHelper {
|
|
7
|
+
/**
|
|
8
|
+
* Returns cryptographically secure random bytes from the Node runtime.
|
|
9
|
+
*/
|
|
10
|
+
getRandomBytes(byteCount: number): Promise<Uint8Array>;
|
|
11
|
+
/**
|
|
12
|
+
* Computes a digest for the provided string using one Node-supported hash algorithm.
|
|
13
|
+
*/
|
|
14
|
+
digestString(data: string, algorithm: string): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Returns a cryptographically secure UUID v4 from the Node runtime.
|
|
17
|
+
*/
|
|
18
|
+
randomUUID(): string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { createHash, randomBytes, randomUUID } from 'crypto';
|
|
3
|
+
/**
|
|
4
|
+
* Node.js implementation of the low-level crypto helper contract used by
|
|
5
|
+
* `CryptographyService` and managed wallet adapters.
|
|
6
|
+
*/
|
|
7
|
+
export class NodeCryptoHelper {
|
|
8
|
+
/**
|
|
9
|
+
* Returns cryptographically secure random bytes from the Node runtime.
|
|
10
|
+
*/
|
|
11
|
+
async getRandomBytes(byteCount) {
|
|
12
|
+
return randomBytes(byteCount);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Computes a digest for the provided string using one Node-supported hash algorithm.
|
|
16
|
+
*/
|
|
17
|
+
async digestString(data, algorithm) {
|
|
18
|
+
const normalized = String(algorithm).replace(/-/g, '').toLowerCase();
|
|
19
|
+
return createHash(normalized).update(data, 'utf8').digest('hex');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns a cryptographically secure UUID v4 from the Node runtime.
|
|
23
|
+
*/
|
|
24
|
+
randomUUID() {
|
|
25
|
+
return randomUUID();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { CryptographyService } from 'gdc-common-utils-ts/CryptographyService';
|
|
2
|
+
import type { ICryptoHelper } from 'gdc-common-utils-ts/interfaces/ICryptoHelper';
|
|
3
|
+
import type { IWallet, WalletAlgorithm, WalletCompactJweRequest, WalletCompactJwsRequest, WalletDetachedJwsRequest, WalletExecutionContext, WalletKeyDescriptor, WalletKeyPurpose, WalletKeySelection, WalletPackOptions, WalletProvisionRequest, WalletUnpackOptions } from 'gdc-sdk-core-ts';
|
|
4
|
+
import type { JWK, JwkSet } from 'gdc-common-utils-ts/models/jwk';
|
|
5
|
+
export type NodeManagedWalletPolicy = {
|
|
6
|
+
defaults: Partial<Record<WalletKeyPurpose, WalletAlgorithm>>;
|
|
7
|
+
};
|
|
8
|
+
export type NodeManagedWalletOptions = {
|
|
9
|
+
cryptoHelper?: ICryptoHelper;
|
|
10
|
+
cryptography?: CryptographyService;
|
|
11
|
+
resolveRecipientJwk?: (recipientDid: string) => Promise<JWK>;
|
|
12
|
+
policy?: Partial<NodeManagedWalletPolicy>;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Node-focused managed wallet implementation for BFF, portal, and backend flows.
|
|
16
|
+
*
|
|
17
|
+
* This adapter keeps actor/profile keys separate from runtime/channel keys and
|
|
18
|
+
* exposes one shared `IWallet` contract suitable for:
|
|
19
|
+
* - user/domain signing
|
|
20
|
+
* - OpenID/JWT signing
|
|
21
|
+
* - DIDComm-style transport wrapping
|
|
22
|
+
* - confidential document protection
|
|
23
|
+
*/
|
|
24
|
+
export declare class NodeManagedWallet implements IWallet {
|
|
25
|
+
private readonly cryptoHelper;
|
|
26
|
+
private readonly cryptography;
|
|
27
|
+
private readonly resolveRecipientJwk?;
|
|
28
|
+
private readonly policy;
|
|
29
|
+
private readonly owners;
|
|
30
|
+
/**
|
|
31
|
+
* Creates one managed wallet backed by `CryptographyService` and Node crypto.
|
|
32
|
+
*/
|
|
33
|
+
constructor(options?: NodeManagedWalletOptions);
|
|
34
|
+
/**
|
|
35
|
+
* Legacy provisioning shape kept for app compatibility.
|
|
36
|
+
*
|
|
37
|
+
* It provisions one profile-owned signing key, one runtime communication
|
|
38
|
+
* signing key, and one runtime communication encryption key while returning
|
|
39
|
+
* the signing/encryption public keys expected by older app-facing flows.
|
|
40
|
+
*/
|
|
41
|
+
provisionKeys(entityId: string): Promise<JwkSet>;
|
|
42
|
+
/**
|
|
43
|
+
* Rich provisioning shape for actor/profile keys and runtime/channel keys.
|
|
44
|
+
*/
|
|
45
|
+
provisionManagedKeys(context: WalletExecutionContext, request: WalletProvisionRequest): Promise<JwkSet>;
|
|
46
|
+
/**
|
|
47
|
+
* Returns the currently available public JWKs for the selected context and filter.
|
|
48
|
+
*/
|
|
49
|
+
getPublicJwks(context?: WalletExecutionContext, filter?: WalletKeySelection): Promise<WalletKeyDescriptor[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Computes a digest of a string using the configured runtime helper.
|
|
52
|
+
*/
|
|
53
|
+
digest(data: string, algorithm: string): Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Protects one confidential document using one owner-specific symmetric storage key.
|
|
56
|
+
*/
|
|
57
|
+
protectConfidentialData(doc: any, entityId: string): Promise<any>;
|
|
58
|
+
/**
|
|
59
|
+
* Protects one confidential document using the richer execution-context model.
|
|
60
|
+
*/
|
|
61
|
+
protectManagedConfidentialData(doc: any, context: WalletExecutionContext, _options?: {
|
|
62
|
+
key?: WalletKeySelection;
|
|
63
|
+
}): Promise<any>;
|
|
64
|
+
/**
|
|
65
|
+
* Decrypts one confidential document using the legacy entity id shape.
|
|
66
|
+
*/
|
|
67
|
+
unprotectConfidentialData(doc: any, entityId: string): Promise<any>;
|
|
68
|
+
/**
|
|
69
|
+
* Decrypts one confidential document using the richer execution-context model.
|
|
70
|
+
*/
|
|
71
|
+
unprotectManagedConfidentialData(doc: any, context: WalletExecutionContext, _options?: {
|
|
72
|
+
key?: WalletKeySelection;
|
|
73
|
+
}): Promise<any>;
|
|
74
|
+
/**
|
|
75
|
+
* Signs arbitrary bytes or one UTF-8 string using the selected managed key.
|
|
76
|
+
*/
|
|
77
|
+
sign(payload: Uint8Array | string, context: WalletExecutionContext, options: WalletKeySelection): Promise<string>;
|
|
78
|
+
/**
|
|
79
|
+
* Verifies one signature against the provided public JWK.
|
|
80
|
+
*/
|
|
81
|
+
verify(payload: Uint8Array | string, signature: string, jwk: JWK, options?: {
|
|
82
|
+
alg?: WalletAlgorithm;
|
|
83
|
+
}): Promise<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* Encrypts one payload for the provided recipient public JWK.
|
|
86
|
+
*/
|
|
87
|
+
encrypt(plaintext: Uint8Array | string, recipientJwk: JWK, options?: {
|
|
88
|
+
context?: WalletExecutionContext;
|
|
89
|
+
key?: WalletKeySelection;
|
|
90
|
+
contentType?: string;
|
|
91
|
+
}): Promise<string>;
|
|
92
|
+
/**
|
|
93
|
+
* Decrypts one ciphertext using one selected local encryption key.
|
|
94
|
+
*/
|
|
95
|
+
decrypt(ciphertext: string, context: WalletExecutionContext, options?: {
|
|
96
|
+
key?: WalletKeySelection;
|
|
97
|
+
}): Promise<Uint8Array>;
|
|
98
|
+
/**
|
|
99
|
+
* Builds one compact JWS using one managed signing key.
|
|
100
|
+
*/
|
|
101
|
+
signCompactJws(context: WalletExecutionContext, request: WalletCompactJwsRequest): Promise<string>;
|
|
102
|
+
/**
|
|
103
|
+
* Builds one detached compact JWS using one managed signing key.
|
|
104
|
+
*/
|
|
105
|
+
signDetachedJws(context: WalletExecutionContext, request: WalletDetachedJwsRequest): Promise<string>;
|
|
106
|
+
/**
|
|
107
|
+
* Builds one compact JWE using one selected local ML-KEM key and one recipient public JWK.
|
|
108
|
+
*/
|
|
109
|
+
buildCompactJwe(context: WalletExecutionContext, request: WalletCompactJweRequest): Promise<string>;
|
|
110
|
+
/**
|
|
111
|
+
* Decrypts one compact JWE using one selected local ML-KEM key.
|
|
112
|
+
*/
|
|
113
|
+
decryptCompactJwe(jwe: string, context: WalletExecutionContext, options: {
|
|
114
|
+
key: WalletKeySelection;
|
|
115
|
+
}): Promise<Uint8Array>;
|
|
116
|
+
/**
|
|
117
|
+
* Legacy pack shape retained for app compatibility.
|
|
118
|
+
*/
|
|
119
|
+
packForRecipient(content: any, recipientDid: string): Promise<string>;
|
|
120
|
+
/**
|
|
121
|
+
* Packs one payload into a transport envelope signed and encrypted by the runtime.
|
|
122
|
+
*/
|
|
123
|
+
packForRecipientWithContext(content: any, recipientDidOrJwk: string | JWK, options: WalletPackOptions): Promise<string>;
|
|
124
|
+
/**
|
|
125
|
+
* Legacy unpack shape retained for app compatibility.
|
|
126
|
+
*/
|
|
127
|
+
unpack(packedMessage: string): Promise<{
|
|
128
|
+
content: any;
|
|
129
|
+
meta: any;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Unpacks one transport envelope and returns the decoded business payload plus JOSE metadata.
|
|
133
|
+
*/
|
|
134
|
+
unpackWithContext(packedMessage: string, options: WalletUnpackOptions): Promise<{
|
|
135
|
+
content: any;
|
|
136
|
+
meta: any;
|
|
137
|
+
}>;
|
|
138
|
+
private getOrCreateOwnerState;
|
|
139
|
+
private tryGetOwnerState;
|
|
140
|
+
private resolveOwnerId;
|
|
141
|
+
private resolveStorageOwnerId;
|
|
142
|
+
private createManagedKey;
|
|
143
|
+
private createStorageKey;
|
|
144
|
+
private requireStorageKey;
|
|
145
|
+
private requireManagedKey;
|
|
146
|
+
private inferRelevantScopes;
|
|
147
|
+
private matchesSelection;
|
|
148
|
+
private resolveAlgorithmForPurpose;
|
|
149
|
+
private deriveSignerSeed;
|
|
150
|
+
private deriveSeedBytes;
|
|
151
|
+
private deriveDeterministicBlock;
|
|
152
|
+
private resolveNodeDigestForAlgorithm;
|
|
153
|
+
private resolveRecipientPublicJwk;
|
|
154
|
+
}
|