gdc-common-utils-ts 2.4.0 → 2.4.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.
|
@@ -161,7 +161,11 @@ export interface DeviceLicense {
|
|
|
161
161
|
maxDevices?: number;
|
|
162
162
|
/** All DCR installations bound to this user/member seat. */
|
|
163
163
|
deviceBindings?: DeviceBinding[];
|
|
164
|
-
/**
|
|
164
|
+
/**
|
|
165
|
+
* Stable private actor identifier:
|
|
166
|
+
* `urn:multibase:<hash(normalized email or phone)>:<professional|personal>`.
|
|
167
|
+
* Portal DIDs, IdP subjects, wallets and DCR clients bind to this value but do not define it.
|
|
168
|
+
*/
|
|
165
169
|
activatedBy?: string;
|
|
166
170
|
/**
|
|
167
171
|
* Optional, pre-defined restrictions on which devices are allowed to activate this license.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Cross-portal actor classes. These are intentionally broader than job roles. */
|
|
2
|
+
export declare const StableActorRoles: Readonly<{
|
|
3
|
+
readonly Professional: "professional";
|
|
4
|
+
readonly Personal: "personal";
|
|
5
|
+
}>;
|
|
6
|
+
export type StableActorRole = typeof StableActorRoles[keyof typeof StableActorRoles];
|
|
7
|
+
export type StableActorContactKind = 'email' | 'phone';
|
|
8
|
+
/**
|
|
9
|
+
* Builds the private, stable actor identifier shared by independent portals.
|
|
10
|
+
*
|
|
11
|
+
* Wire format: `urn:multibase:<multibase(multihash(SHA3-256, normalized-contact))>:<role>`.
|
|
12
|
+
* Examples end in `:professional` or `:personal`; the clear email/phone is
|
|
13
|
+
* never embedded. A portal-specific `did:web`, IdP `sub`, wallet and DCR
|
|
14
|
+
* `client_id` are bindings to this identifier, not replacements for it.
|
|
15
|
+
*
|
|
16
|
+
* Email is trimmed, stripped of `mailto:` and lower-cased. Phone is stripped
|
|
17
|
+
* of `tel:` and formatting while preserving an E.164 leading `+`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildStableActorIdentifier(input: {
|
|
20
|
+
contactKind: StableActorContactKind;
|
|
21
|
+
contact: string;
|
|
22
|
+
role: StableActorRole;
|
|
23
|
+
}): string;
|
|
24
|
+
/**
|
|
25
|
+
* Builds a portal-specific DID binding that carries the stable actor payload.
|
|
26
|
+
* The portal root can change while the final actor payload remains identical.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildPortalActorDidWeb(input: {
|
|
29
|
+
portalDidWeb: string;
|
|
30
|
+
actorIdentifier: string;
|
|
31
|
+
}): string;
|
|
32
|
+
/**
|
|
33
|
+
* Extracts the stable actor URN from a canonical GDC portal actor DID.
|
|
34
|
+
* This is extraction, not reversal of the contact hash.
|
|
35
|
+
*/
|
|
36
|
+
export declare function stableActorIdentifierFromDidWeb(didWeb: string): string;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { normalizePhone } from './consent.js';
|
|
2
|
+
import { multibase58MultihashSha3_256 } from './same-as.js';
|
|
3
|
+
/** Cross-portal actor classes. These are intentionally broader than job roles. */
|
|
4
|
+
export const StableActorRoles = Object.freeze({
|
|
5
|
+
Professional: 'professional',
|
|
6
|
+
Personal: 'personal',
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* Builds the private, stable actor identifier shared by independent portals.
|
|
10
|
+
*
|
|
11
|
+
* Wire format: `urn:multibase:<multibase(multihash(SHA3-256, normalized-contact))>:<role>`.
|
|
12
|
+
* Examples end in `:professional` or `:personal`; the clear email/phone is
|
|
13
|
+
* never embedded. A portal-specific `did:web`, IdP `sub`, wallet and DCR
|
|
14
|
+
* `client_id` are bindings to this identifier, not replacements for it.
|
|
15
|
+
*
|
|
16
|
+
* Email is trimmed, stripped of `mailto:` and lower-cased. Phone is stripped
|
|
17
|
+
* of `tel:` and formatting while preserving an E.164 leading `+`.
|
|
18
|
+
*/
|
|
19
|
+
export function buildStableActorIdentifier(input) {
|
|
20
|
+
const role = String(input.role || '').trim();
|
|
21
|
+
if (!Object.values(StableActorRoles).includes(role)) {
|
|
22
|
+
throw new Error('Stable actor role must be professional or personal.');
|
|
23
|
+
}
|
|
24
|
+
const rawContact = String(input.contact || '').trim();
|
|
25
|
+
const normalizedContact = input.contactKind === 'email'
|
|
26
|
+
? rawContact.replace(/^mailto:/i, '').replace(/\s+/g, '').toLowerCase()
|
|
27
|
+
: normalizePhone(rawContact.replace(/^tel:/i, ''));
|
|
28
|
+
if (!normalizedContact) {
|
|
29
|
+
throw new Error(`Stable actor ${input.contactKind} is required.`);
|
|
30
|
+
}
|
|
31
|
+
return `urn:multibase:${multibase58MultihashSha3_256(normalizedContact)}:${role}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Builds a portal-specific DID binding that carries the stable actor payload.
|
|
35
|
+
* The portal root can change while the final actor payload remains identical.
|
|
36
|
+
*/
|
|
37
|
+
export function buildPortalActorDidWeb(input) {
|
|
38
|
+
const portalDidWeb = String(input.portalDidWeb || '').trim();
|
|
39
|
+
const match = /^urn:multibase:(z[^:]+):(professional|personal)$/.exec(String(input.actorIdentifier || '').trim());
|
|
40
|
+
if (!portalDidWeb.startsWith('did:web:')) {
|
|
41
|
+
throw new Error('Portal actor binding requires a did:web root.');
|
|
42
|
+
}
|
|
43
|
+
if (!match) {
|
|
44
|
+
throw new Error('Portal actor binding requires a stable actor URN.');
|
|
45
|
+
}
|
|
46
|
+
return `${portalDidWeb}:actor:multibase:${match[1]}:${match[2]}`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extracts the stable actor URN from a canonical GDC portal actor DID.
|
|
50
|
+
* This is extraction, not reversal of the contact hash.
|
|
51
|
+
*/
|
|
52
|
+
export function stableActorIdentifierFromDidWeb(didWeb) {
|
|
53
|
+
const match = /:actor:multibase:(z[^:]+):(professional|personal)(?::|$)/.exec(String(didWeb || '').trim());
|
|
54
|
+
if (!match) {
|
|
55
|
+
throw new Error('DID does not contain a canonical GDC actor binding.');
|
|
56
|
+
}
|
|
57
|
+
return `urn:multibase:${match[1]}:${match[2]}`;
|
|
58
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -104,6 +104,7 @@ export * from './service-act-reasons';
|
|
|
104
104
|
export * from './same-as';
|
|
105
105
|
export * from './subject-identity-binding';
|
|
106
106
|
export * from './activation-request';
|
|
107
|
+
export * from './actor-identifier';
|
|
107
108
|
export * from './vp-token';
|
|
108
109
|
export * from './vital-sign-day-batch';
|
|
109
110
|
export * from './wallet-mem';
|
package/dist/utils/index.js
CHANGED
|
@@ -104,6 +104,7 @@ export * from './service-act-reasons.js';
|
|
|
104
104
|
export * from './same-as.js';
|
|
105
105
|
export * from './subject-identity-binding.js';
|
|
106
106
|
export * from './activation-request.js';
|
|
107
|
+
export * from './actor-identifier.js';
|
|
107
108
|
export * from './vp-token.js';
|
|
108
109
|
export * from './vital-sign-day-batch.js';
|
|
109
110
|
export * from './wallet-mem.js';
|