gdc-common-utils-ts 1.0.3 → 1.0.5

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.
@@ -6,17 +6,41 @@ describe('parseActorFromSub', () => {
6
6
  });
7
7
 
8
8
  it('parses did:web subject with organization, email, and role', () => {
9
- const sub = 'did:web:api.acme.org:employee:Doctor1@ACME.org:role:ISCO-08|2211';
9
+ const sub = 'did:web:api.acme.org:employee:doctor1@acme.org:ISCO-08|2211';
10
10
  const parsed = parseActorFromSub(sub);
11
11
  expect(parsed.sub).toBe(sub);
12
12
  expect(parsed.organization).toBe('did:web:api.acme.org');
13
- expect(parsed.email).toBe('doctor1@acme.org');
13
+ expect(parsed.identifier).toBe('doctor1@acme.org');
14
14
  expect(parsed.role).toBe('ISCO-08|2211');
15
15
  });
16
16
 
17
+ it('parses did:web subject with role and device uuid', () => {
18
+ const sub = 'did:web:api.acme.org:employee:doctor1@acme.org:ISCO-08|2211:550e8400-e29b-41d4-a716-446655440000';
19
+ const parsed = parseActorFromSub(sub);
20
+ expect(parsed.organization).toBe('did:web:api.acme.org');
21
+ expect(parsed.identifier).toBe('doctor1@acme.org');
22
+ expect(parsed.role).toBe('ISCO-08|2211');
23
+ });
24
+
25
+ it('parses family subject with role and device uuid', () => {
26
+ const sub = 'did:web:api.acme.org:family:zQmHash123:v3-RoleCode|CHILD:550e8400-e29b-41d4-a716-446655440000';
27
+ const parsed = parseActorFromSub(sub);
28
+ expect(parsed.organization).toBe('did:web:api.acme.org');
29
+ expect(parsed.identifier).toBe('zQmHash123');
30
+ expect(parsed.role).toBe('v3-RoleCode|CHILD');
31
+ });
32
+
33
+ it('parses family subject with ONESELF role and no device uuid', () => {
34
+ const sub = 'did:web:api.acme.org:family:zQmHash123:v3-RoleCode|ONESELF';
35
+ const parsed = parseActorFromSub(sub);
36
+ expect(parsed.organization).toBe('did:web:api.acme.org');
37
+ expect(parsed.identifier).toBe('zQmHash123');
38
+ expect(parsed.role).toBe('v3-RoleCode|ONESELF');
39
+ });
40
+
17
41
  it('parses raw email subject', () => {
18
42
  const parsed = parseActorFromSub(' User@Example.com ');
19
43
  expect(parsed.sub).toBe('User@Example.com');
20
- expect(parsed.email).toBe('user@example.com');
44
+ expect(parsed.identifier).toBe('user@example.com');
21
45
  });
22
46
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdc-common-utils-ts",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -4,12 +4,14 @@ export type ParsedActor = {
4
4
  /**
5
5
  * The token subject / authenticated actor identifier (as provided in the token request).
6
6
  * Examples:
7
- * - did:web:api.acme.org:employee:doctor1@acme.org:role:ISCO-08|2211
8
- * - doctor1@acme.org
7
+ * - did:web:api.acme.org:employee:doctor1@acme.org:ISCO-08|2211
8
+ * - did:web:api.acme.org:employee:doctor1@acme.org:ISCO-08|2211:<device-uuid>
9
+ * - did:web:api.acme.org:family:<id>:v3-RoleCode|ONESELF
10
+ * - did:web:api.acme.org:family:<id>:v3-RoleCode|CHILD:<device-uuid>
9
11
  */
10
12
  sub: string;
11
- /** The employee email if present (either from did:web employee DID or raw email). */
12
- email?: string;
13
+ /** The actor identifier (employee email, familyId, or raw email). */
14
+ identifier?: string;
13
15
  /** The employee role code if present (e.g. "ISCO-08|2211"). */
14
16
  role?: string;
15
17
  /** The base organization did:web if `sub` is did:web (e.g. "did:web:api.acme.org"). */
@@ -28,25 +30,27 @@ export function parseActorFromSub(sub: string): ParsedActor {
28
30
  const host = after.split(':')[0];
29
31
  if (host) parsed.organization = `did:web:${host}`;
30
32
 
31
- // Extract email and role from the canonical employee DID shape:
32
- // did:web:<host>:employee:<email>:role:<roleCode>[:device:<uuid>]
33
+ // Extract email and role from endpoint-style DID shapes:
34
+ // did:web:<host>:(employee|family):<id>:<roleSystem>|<roleCode>[:<uuid>]
33
35
  const parts = after.split(':');
34
36
  const employeeIdx = parts.indexOf('employee');
35
- if (employeeIdx >= 0 && parts.length > employeeIdx + 1) {
36
- const email = parts[employeeIdx + 1];
37
- if (email && email.includes('@')) parsed.email = email.toLowerCase();
37
+ const familyIdx = parts.indexOf('family');
38
+ const idIdx = employeeIdx >= 0 ? employeeIdx + 1 : familyIdx >= 0 ? familyIdx + 1 : -1;
39
+ const identifier = idIdx >= 0 ? parts[idIdx] : undefined;
40
+ if (identifier) {
41
+ parsed.identifier = identifier.includes('@') ? identifier.toLowerCase() : identifier;
38
42
  }
39
- const roleIdx = parts.indexOf('role');
40
- if (roleIdx >= 0 && parts.length > roleIdx + 1) {
41
- parsed.role = parts[roleIdx + 1];
43
+
44
+ if (idIdx >= 0 && parts.length > idIdx + 1) {
45
+ const roleCandidate = parts[idIdx + 1];
46
+ if (roleCandidate && roleCandidate.includes('|')) parsed.role = roleCandidate;
42
47
  }
43
48
  return parsed;
44
49
  }
45
50
 
46
51
  // Raw email actor identifier
47
52
  if (trimmed.includes('@') && !/\s/.test(trimmed)) {
48
- parsed.email = trimmed.toLowerCase();
53
+ parsed.identifier = trimmed.toLowerCase();
49
54
  }
50
55
  return parsed;
51
56
  }
52
-