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
- /** Identity-provider subject that first activated this seat. */
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
+ }
@@ -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';
@@ -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';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdc-common-utils-ts",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },