@ibgib/web-gib 0.0.60 → 0.0.61

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.
Files changed (60) hide show
  1. package/dist/AUTO-GENERATED-version.d.mts +1 -1
  2. package/dist/AUTO-GENERATED-version.mjs +1 -1
  3. package/dist/helpers.d.mts.map +1 -1
  4. package/dist/helpers.mjs +1 -0
  5. package/dist/helpers.mjs.map +1 -1
  6. package/dist/identity/device-delegate-helper.d.mts +43 -0
  7. package/dist/identity/device-delegate-helper.d.mts.map +1 -0
  8. package/dist/identity/device-delegate-helper.mjs +106 -0
  9. package/dist/identity/device-delegate-helper.mjs.map +1 -0
  10. package/dist/identity/device-delegate.respec.d.mts +2 -0
  11. package/dist/identity/device-delegate.respec.d.mts.map +1 -0
  12. package/dist/identity/device-delegate.respec.mjs +106 -0
  13. package/dist/identity/device-delegate.respec.mjs.map +1 -0
  14. package/dist/identity/keystone-sync-service.d.mts +18 -0
  15. package/dist/identity/keystone-sync-service.d.mts.map +1 -1
  16. package/dist/identity/keystone-sync-service.mjs +77 -1
  17. package/dist/identity/keystone-sync-service.mjs.map +1 -1
  18. package/dist/index.d.mts +1 -1
  19. package/dist/index.d.mts.map +1 -1
  20. package/dist/index.mjs +1 -2
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/storage/storage-helpers.web.d.mts +9 -0
  23. package/dist/storage/storage-helpers.web.d.mts.map +1 -1
  24. package/dist/storage/storage-helpers.web.mjs +42 -0
  25. package/dist/storage/storage-helpers.web.mjs.map +1 -1
  26. package/dist/ui/component/identity/add-device/add-device.d.mts.map +1 -1
  27. package/dist/ui/component/identity/add-device/add-device.mjs +30 -43
  28. package/dist/ui/component/identity/add-device/add-device.mjs.map +1 -1
  29. package/dist/ui/component/identity/keystone-creator/keystone-creator.d.mts.map +1 -1
  30. package/dist/ui/component/identity/keystone-creator/keystone-creator.mjs +41 -57
  31. package/dist/ui/component/identity/keystone-creator/keystone-creator.mjs.map +1 -1
  32. package/dist/ui/component/identity/keystone-details/keystone-details.d.mts +3 -0
  33. package/dist/ui/component/identity/keystone-details/keystone-details.d.mts.map +1 -1
  34. package/dist/ui/component/identity/keystone-details/keystone-details.mjs +307 -46
  35. package/dist/ui/component/identity/keystone-details/keystone-details.mjs.map +1 -1
  36. package/dist/ui/ui-constants.d.mts +1 -0
  37. package/dist/ui/ui-constants.d.mts.map +1 -1
  38. package/dist/ui/ui-constants.mjs +1 -0
  39. package/dist/ui/ui-constants.mjs.map +1 -1
  40. package/dist/ui/ui-types.d.mts +5 -0
  41. package/dist/ui/ui-types.d.mts.map +1 -1
  42. package/package.json +2 -2
  43. package/src/AUTO-GENERATED-version.mts +1 -1
  44. package/src/helpers.mts +1 -0
  45. package/src/identity/custodian-delegate-helper.mts.bak +7 -0
  46. package/src/identity/device-delegate-helper.mts +135 -0
  47. package/src/identity/device-delegate.respec.mts +125 -0
  48. package/src/identity/keystone-sync-service.mts +95 -2
  49. package/src/index.mts +1 -2
  50. package/src/storage/storage-helpers.web.mts +47 -0
  51. package/src/ui/component/identity/add-device/add-device.mts +36 -48
  52. package/src/ui/component/identity/keystone-creator/keystone-creator.mts +48 -65
  53. package/src/ui/component/identity/keystone-details/keystone-details.mts +317 -49
  54. package/src/ui/ui-constants.mts +1 -0
  55. package/src/ui/ui-types.mts +6 -0
  56. package/dist/identity/custodian-delegate-helper.d.mts +0 -22
  57. package/dist/identity/custodian-delegate-helper.d.mts.map +0 -1
  58. package/dist/identity/custodian-delegate-helper.mjs +0 -67
  59. package/dist/identity/custodian-delegate-helper.mjs.map +0 -1
  60. package/src/identity/custodian-delegate-helper.mts +0 -86
@@ -9,12 +9,15 @@ import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs
9
9
  import { getIbAndGib, getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
10
10
  import { getGibInfo } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
11
11
  import { KeystoneIbGib_V1 } from "@ibgib/core-gib/dist/keystone/keystone-types.mjs";
12
+ import { KeystoneService_V1 } from "@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs";
12
13
  import { getTimelinesGroupedByTjp, getTjpAddr, toDto } from "@ibgib/core-gib/dist/common/other/ibgib-helper.mjs";
13
14
  import { updateSpecialIndex } from "@ibgib/core-gib/dist/timeline/timeline-api.mjs";
15
+ import { isDelegateExpired } from "@ibgib/core-gib/dist/keystone/delegate/delegate-helpers.mjs";
14
16
  import { getApiBridge } from "../api/ibgib-api-bridge.mjs";
15
17
  import { getGlobalMetaspace_waitIfNeeded } from "../helpers.mjs";
16
- import { EVENT_IBGIB_IDENTITY_UPDATE_AVAILABLE } from "../ui/ui-constants.mjs";
17
- import { EventIbGibIdentityUpdateAvailableDetail } from "../ui/ui-types.mjs";
18
+ import { getDeviceDelegateSecret } from "./device-delegate-helper.mjs";
19
+ import { EVENT_IBGIB_IDENTITY_UPDATE_AVAILABLE, EVENT_IBGIB_IDENTITY_RENEWAL_REQUIRED } from "../ui/ui-constants.mjs";
20
+ import { EventIbGibIdentityUpdateAvailableDetail, EventIbGibIdentityRenewalRequiredDetail } from "../ui/ui-types.mjs";
18
21
 
19
22
  export interface KeystoneUpdateCheckResult {
20
23
  hasUpdate: boolean;
@@ -37,6 +40,96 @@ export class KeystoneSyncService {
37
40
  }
38
41
  }
39
42
 
43
+ private dispatchRenewalRequiredEvent(detail: EventIbGibIdentityRenewalRequiredDetail): void {
44
+ if (typeof window !== 'undefined') {
45
+ window.dispatchEvent(new CustomEvent(EVENT_IBGIB_IDENTITY_RENEWAL_REQUIRED, {
46
+ detail,
47
+ bubbles: true,
48
+ composed: true,
49
+ }));
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Retrieves the stored device delegate secret ($S_D$) for an active primary identity from IndexedDB.
55
+ */
56
+ public async getDeviceDelegateSecret({
57
+ primaryTjpAddr
58
+ }: {
59
+ primaryTjpAddr: string;
60
+ }): Promise<string | undefined> {
61
+ return getDeviceDelegateSecret({ primaryTjpAddr });
62
+ }
63
+
64
+ /**
65
+ * Checks if the active identity has a valid, unexpired sync delegate on this device.
66
+ */
67
+ public async checkDelegateStatus({
68
+ activePrimaryAddr,
69
+ metaspace,
70
+ space
71
+ }: {
72
+ activePrimaryAddr: string;
73
+ metaspace?: any;
74
+ space?: any;
75
+ }): Promise<{ isValid: boolean; reason?: 'expired' | 'missing_secret' }> {
76
+ const lc = `${this.lc}[${this.checkDelegateStatus.name}]`;
77
+ try {
78
+ if (!metaspace) metaspace = await getGlobalMetaspace_waitIfNeeded();
79
+ if (!metaspace) {
80
+ throw new Error(`${lc} (UNEXPECTED) metaspace falsy? (E: a1b2c3d4e5f60718293a4b5c6d7e8f90)`);
81
+ }
82
+ if (!space) space = await metaspace.getLocalUserSpace({ lock: false });
83
+ if (!space) {
84
+ throw new Error(`${lc} (UNEXPECTED) space falsy? (E: b2c3d4e5f60718293a4b5c6d7e8f90a1)`);
85
+ }
86
+
87
+ const info = getGibInfo({ ibGibAddr: activePrimaryAddr });
88
+ const { ib } = getIbAndGib({ ibGibAddr: activePrimaryAddr });
89
+ const primaryTjpAddr = info.tjpGib ? `${ib}^${info.tjpGib}` : activePrimaryAddr;
90
+
91
+ // 1. Check if local secret exists in IndexedDB
92
+ const secret = await getDeviceDelegateSecret({ primaryTjpAddr });
93
+ if (!secret) {
94
+ this.dispatchRenewalRequiredEvent({
95
+ activePrimaryAddr,
96
+ primaryTjpAddr,
97
+ reason: 'missing_secret'
98
+ });
99
+ return { isValid: false, reason: 'missing_secret' };
100
+ }
101
+
102
+ // 2. Check if primary keystone has registered delegates and if any are expired
103
+ const keystoneService = new KeystoneService_V1();
104
+ const keystone = await keystoneService.getLatestKeystone({
105
+ addr: activePrimaryAddr,
106
+ metaspace,
107
+ space
108
+ });
109
+ if (!keystone) {
110
+ throw new Error(`${lc} (UNEXPECTED) latest primary keystone not found for addr: ${activePrimaryAddr} (E: c3d4e5f60718293a4b5c6d7e8f90a1b2)`);
111
+ }
112
+
113
+ if (keystone?.data?.delegates) {
114
+ const delegates = Object.values(keystone.data.delegates);
115
+ const isAnyExpired = delegates.some(d => isDelegateExpired({ delegateInfo: d }));
116
+ if (isAnyExpired) {
117
+ this.dispatchRenewalRequiredEvent({
118
+ activePrimaryAddr,
119
+ primaryTjpAddr,
120
+ reason: 'expired'
121
+ });
122
+ return { isValid: false, reason: 'expired' };
123
+ }
124
+ }
125
+
126
+ return { isValid: true };
127
+ } catch (error) {
128
+ console.error(`${lc} ${extractErrorMsg(error)}`);
129
+ return { isValid: false };
130
+ }
131
+ }
132
+
40
133
  /**
41
134
  * Checks if a server update exists for the given active primary keystone address.
42
135
  */
package/src/index.mts CHANGED
@@ -18,8 +18,7 @@ export * from "./api/ibgib-api-bridge.mjs";
18
18
 
19
19
  // Identity & Sync services
20
20
  export * from "./identity/keystone-sync-service.mjs";
21
- export * from "./identity/custodian-delegate-helper.mjs";
22
- // export * from "./identity/sso-callback-helper.mjs";
21
+ export * from "./identity/device-delegate-helper.mjs";
23
22
  export * from "./identity/sso-popup-helper.mjs";
24
23
 
25
24
  // Identity UI components
@@ -726,3 +726,50 @@ export async function storageReaddir({
726
726
  }
727
727
  }
728
728
  }
729
+
730
+ /**
731
+ * Deletes a single key from indexeddb storage.
732
+ */
733
+ export async function storageDelete({
734
+ dbName,
735
+ storeName,
736
+ key,
737
+ logalot = false,
738
+ }: {
739
+ dbName: string;
740
+ storeName: string;
741
+ key: string;
742
+ logalot?: boolean;
743
+ }): Promise<void> {
744
+ const lc = `[${storageDelete.name}]`;
745
+ let db: IDBDatabase | undefined = undefined;
746
+ try {
747
+ if (logalot) { console.log(`${lc} starting... (I: 8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d)`); }
748
+ await new Promise<void>((resolve, reject) => {
749
+ const openDBRequest = indexedDB.open(dbName);
750
+ openDBRequest.onerror = () => {
751
+ reject(openDBRequest.error);
752
+ };
753
+ openDBRequest.onsuccess = () => {
754
+ db = openDBRequest.result;
755
+ const transaction = db.transaction(storeName, "readwrite");
756
+ const objectStore = transaction.objectStore(storeName);
757
+ const deleteRequest = objectStore.delete(key);
758
+ deleteRequest.onerror = () => {
759
+ reject(deleteRequest.error);
760
+ };
761
+ deleteRequest.onsuccess = () => {
762
+ resolve();
763
+ };
764
+ };
765
+ });
766
+ } catch (error) {
767
+ console.error(`${lc} ${extractErrorMsg(error)}`);
768
+ throw error;
769
+ } finally {
770
+ if (db) {
771
+ (db as any).close();
772
+ }
773
+ if (logalot) { console.log(`${lc} complete.`); }
774
+ }
775
+ }
@@ -9,8 +9,8 @@ import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
9
9
  import { KeystoneService_V1 } from "@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs";
10
10
  import { KeystoneProfileBuilder } from "@ibgib/core-gib/dist/keystone/policy/keystone-profile-builder.mjs";
11
11
  import { KeystoneIbGib_V1 } from "@ibgib/core-gib/dist/keystone/keystone-types.mjs";
12
- import { KEYSTONE_VERB_SYNC, KEYSTONE_VERB_CONNECT, KEYSTONE_USERNAME_REGEXP } from "@ibgib/core-gib/dist/keystone/keystone-constants.mjs";
13
- import { deriveDelegateSecret } from "@ibgib/core-gib/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mjs";
12
+ import { KEYSTONE_USERNAME_REGEXP, KEYSTONE_VERB_SYNC, KEYSTONE_VERB_CONNECT } from "@ibgib/core-gib/dist/keystone/keystone-constants.mjs";
13
+ import { deriveDelegateSecret, createSyncDelegateKeystone } from "@ibgib/core-gib/dist/keystone/delegate/delegate-helpers.mjs";
14
14
  import { getTimelinesGroupedByTjp, getTjpAddr, toDto } from "@ibgib/core-gib/dist/common/other/ibgib-helper.mjs";
15
15
  import { updateSpecialIndex } from "@ibgib/core-gib/dist/timeline/timeline-api.mjs";
16
16
  import { validateEmail } from "@ibgib/core-gib/dist/keystone/keystone-helpers.mjs";
@@ -29,7 +29,7 @@ import {
29
29
  } from "../../../ui-constants.mjs";
30
30
  import { generateDefaultDeviceTag } from "../../../../util/device-helper.mjs";
31
31
  import { executeSsoOAuthPopup } from "../../../../identity/sso-popup-helper.mjs";
32
- import { deriveLocalCustodianDelegateSecret } from "../../../../identity/custodian-delegate-helper.mjs";
32
+ import { getOrCreateDeviceDelegateSecret, setDeviceDelegateSecret } from "../../../../identity/device-delegate-helper.mjs";
33
33
 
34
34
  export const ADD_DEVICE_COMPONENT_NAME = 'ibgib-add-device';
35
35
 
@@ -472,25 +472,6 @@ export class AddDeviceComponentInstance
472
472
  animationEmoji: '🔑'
473
473
  });
474
474
 
475
- const delegateSecret = await deriveLocalCustodianDelegateSecret({ primaryTjpAddr });
476
- const userAlias = username || (email ? email.split('@')[0] : 'user');
477
- const custodianSyncProfileName = process.env.KEYSTONE_PROFILE_CUSTODIAN_SYNC;
478
- if (!custodianSyncProfileName || !custodianSyncProfileName.trim()) {
479
- throw new Error('KEYSTONE_PROFILE_CUSTODIAN_SYNC environment variable is missing. Expected valid profile name like "sync-profile.dev" or "sync-profile.prod". (E: 4d5e6f7890123456789abcdef4)');
480
- }
481
-
482
- const delegateBuilder = KeystoneProfileBuilder.buildKeystone(custodianSyncProfileName.trim() as any)
483
- .withUsername(`${userAlias}-sync-${deviceTag}`)
484
- .withDescription(`Sync Delegate for ${userAlias} on ${deviceTag}`)
485
- .withDetails({
486
- client: 'space-gib-web',
487
- role: 'sync-delegate',
488
- deviceTag,
489
- primaryTjpAddr,
490
- custodianReqs,
491
- });
492
-
493
- const configs = await delegateBuilder.compileConfigs();
494
475
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
495
476
  const space = await metaspace.getLocalUserSpace({ lock: false });
496
477
  if (!space) {
@@ -498,14 +479,23 @@ export class AddDeviceComponentInstance
498
479
  return;
499
480
  }
500
481
 
501
- const keystoneService = new KeystoneService_V1();
502
- const delegateKeystone = await keystoneService.genesis({
503
- masterSecret: delegateSecret,
504
- configs,
482
+ const delegateSecret = await getOrCreateDeviceDelegateSecret({ primaryTjpAddr, deviceTag });
483
+ const userAlias = username || (email ? email.split('@')[0] : 'user');
484
+ const custodianSyncProfileName = process.env.KEYSTONE_PROFILE_CUSTODIAN_SYNC;
485
+ if (!custodianSyncProfileName || !custodianSyncProfileName.trim()) {
486
+ throw new Error('KEYSTONE_PROFILE_CUSTODIAN_SYNC environment variable is missing. Expected valid profile name like "sync-profile.dev" or "sync-profile.prod". (E: 4d5e6f7890123456789abcdef4)');
487
+ }
488
+
489
+ const delegateKeystone = await createSyncDelegateKeystone({
490
+ profileName: custodianSyncProfileName.trim() as any,
491
+ username: userAlias,
492
+ deviceTag,
493
+ primaryTjpAddr,
494
+ delegateSecret,
495
+ custodianReqs,
496
+ additionalFrameDetails: { client: 'space-gib-web' },
505
497
  metaspace,
506
498
  space,
507
- frameDetails: delegateBuilder.getFrameDetails(),
508
- isPrimary: false
509
499
  });
510
500
 
511
501
  this.setStatus('Registering device delegate with custodian server...', 'info');
@@ -590,34 +580,27 @@ export class AddDeviceComponentInstance
590
580
  animationEmoji: '🔑'
591
581
  });
592
582
 
583
+ const metaspace = await getGlobalMetaspace_waitIfNeeded();
584
+ const space = await metaspace.getLocalUserSpace({});
585
+ if (!space) { throw new Error('No default space found in metaspace.'); }
586
+
593
587
  const delegateSecret = await deriveDelegateSecret({ masterSecret });
588
+ await setDeviceDelegateSecret({ primaryTjpAddr, delegateSecret });
589
+
594
590
  const sovereignSyncProfileName = process.env.KEYSTONE_PROFILE_SOVEREIGN_SYNC;
595
591
  if (!sovereignSyncProfileName || !sovereignSyncProfileName.trim()) {
596
592
  throw new Error('KEYSTONE_PROFILE_SOVEREIGN_SYNC environment variable is missing. Expected valid profile name like "sync-profile.dev" or "sync-profile.prod". (E: 8f9e0a1b2c3d4e5f67890123456789ab)');
597
593
  }
598
594
 
599
- const delegateBuilder = KeystoneProfileBuilder.buildKeystone(sovereignSyncProfileName.trim() as any)
600
- .withUsername(`${primaryUsername}-sync-${deviceTag}`)
601
- .withDescription(`Sync Delegate for ${primaryUsername} on ${deviceTag}`)
602
- .withDetails({
603
- client: 'space-gib-web',
604
- role: 'sync-delegate',
605
- deviceTag,
606
- primaryTjpAddr,
607
- });
608
-
609
- const delegateConfigs = await delegateBuilder.compileConfigs();
610
- const metaspace = await getGlobalMetaspace_waitIfNeeded();
611
- const space = await metaspace.getLocalUserSpace({});
612
- if (!space) { throw new Error('No default space found in metaspace.'); }
613
-
614
- const delegateKeystone = await keystoneService.genesis({
615
- masterSecret: delegateSecret,
616
- configs: delegateConfigs,
595
+ const delegateKeystone = await createSyncDelegateKeystone({
596
+ profileName: sovereignSyncProfileName.trim() as any,
597
+ username: primaryUsername,
598
+ deviceTag,
599
+ primaryTjpAddr,
600
+ delegateSecret,
601
+ additionalFrameDetails: { client: 'space-gib-web' },
617
602
  metaspace,
618
603
  space,
619
- frameDetails: delegateBuilder.getFrameDetails(),
620
- isPrimary: false
621
604
  });
622
605
 
623
606
  this.setStatus('Evolving primary identity to register delegate...', 'info');
@@ -765,6 +748,11 @@ export class AddDeviceComponentInstance
765
748
 
766
749
  await delay(humanEyeDelay);
767
750
 
751
+ // 4.5 Sanitize password input fields from DOM
752
+ if (this.elements?.inputPassword) {
753
+ this.elements.inputPassword.value = '';
754
+ }
755
+
768
756
  // 5. Navigate to identity manager
769
757
  window.dispatchEvent(new CustomEvent(EVENT_IBGIB_UI_MESSAGE, {
770
758
  detail: { action: 'show-identity-manager', addr: primaryTjpAddr },
@@ -14,7 +14,7 @@ import { toDto, getTjpAddr, getTimelinesGroupedByTjp } from "@ibgib/core-gib/dis
14
14
  import { FlatIbGibGraph } from "@ibgib/core-gib/dist/common/other/graph-types.mjs";
15
15
  import { validateEmail } from "@ibgib/core-gib/dist/keystone/keystone-helpers.mjs";
16
16
  import { KEYSTONE_USERNAME_REGEXP, KEYSTONE_DESCRIPTION_REGEXP, KEYSTONE_VERB_SYNC, KEYSTONE_VERB_CONNECT } from "@ibgib/core-gib/dist/keystone/keystone-constants.mjs";
17
- import { deriveDelegateSecret } from "@ibgib/core-gib/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mjs";
17
+ import { deriveDelegateSecret, createSyncDelegateKeystone } from "@ibgib/core-gib/dist/keystone/delegate/delegate-helpers.mjs";
18
18
 
19
19
  import { getGlobalMetaspace_waitIfNeeded, } from "../../../../helpers.mjs";
20
20
  import { IbGibDynamicComponentMetaBase, IbGibFormInstanceBase, } from "../../ibgib-dynamic-component-bases.mjs";
@@ -24,8 +24,9 @@ import {
24
24
  } from "../../component-types.mjs";
25
25
  import { getComponentCtorArg } from "../../../../app-bootstrap/init-orchestration.mjs";
26
26
  import { getApiBridge } from "../../../../api/ibgib-api-bridge.mjs";
27
- import { deriveLocalCustodianDelegateSecret } from "../../../../identity/custodian-delegate-helper.mjs";
27
+ import { getOrCreateDeviceDelegateSecret, setDeviceDelegateSecret } from "../../../../identity/device-delegate-helper.mjs";
28
28
  import { executeSsoOAuthPopup } from "../../../../identity/sso-popup-helper.mjs";
29
+ import { generateDefaultDeviceTag } from "../../../../util/device-helper.mjs";
29
30
  import { EVENT_IBGIB_IDENTITY_REQUEST_CHANGE, EVENT_IBGIB_UI_MESSAGE } from "../../../ui-constants.mjs";
30
31
  import { alertUser, shadowRoot_getElementById } from "../../../../helpers.web.mjs";
31
32
 
@@ -307,25 +308,6 @@ export class KeystoneCreatorComponentInstance
307
308
  animationEmoji: '🔑'
308
309
  });
309
310
 
310
- const delegateSecret = await deriveLocalCustodianDelegateSecret({ primaryTjpAddr });
311
- const email = resLogin.userInfo?.email || '';
312
- const username = email ? email.split('@')[0] : 'user';
313
- const custodianSyncProfileName = process.env.KEYSTONE_PROFILE_CUSTODIAN_SYNC;
314
- if (!custodianSyncProfileName || !custodianSyncProfileName.trim()) {
315
- throw new Error('KEYSTONE_PROFILE_CUSTODIAN_SYNC environment variable is missing. Expected valid profile name like "sync-profile.dev" or "sync-profile.prod". (E: 4d5e6f7890123456789abcdef4)');
316
- }
317
-
318
- const delegateBuilder = KeystoneProfileBuilder.buildKeystone(custodianSyncProfileName.trim() as any)
319
- .withUsername(`${username}-sync`)
320
- .withDescription(`Sync Delegate for ${username}`)
321
- .withDetails({
322
- client: 'space-gib-web',
323
- role: 'sync-delegate',
324
- primaryTjpAddr,
325
- custodianReqs,
326
- });
327
-
328
- const configs = await delegateBuilder.compileConfigs();
329
311
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
330
312
  const space = await metaspace.getLocalUserSpace({ lock: false });
331
313
  if (!space) {
@@ -333,14 +315,24 @@ export class KeystoneCreatorComponentInstance
333
315
  return;
334
316
  }
335
317
 
336
- const keystoneService = new KeystoneService_V1();
337
- const delegateKeystone = await keystoneService.genesis({
338
- masterSecret: delegateSecret,
339
- configs,
318
+ const delegateSecret = await getOrCreateDeviceDelegateSecret({ primaryTjpAddr });
319
+ const email = resLogin.userInfo?.email || '';
320
+ const username = email ? email.split('@')[0] : 'user';
321
+ const custodianSyncProfileName = process.env.KEYSTONE_PROFILE_CUSTODIAN_SYNC;
322
+ if (!custodianSyncProfileName || !custodianSyncProfileName.trim()) {
323
+ throw new Error('KEYSTONE_PROFILE_CUSTODIAN_SYNC environment variable is missing. Expected valid profile name like "sync-profile.dev" or "sync-profile.prod". (E: 4d5e6f7890123456789abcdef4)');
324
+ }
325
+
326
+ const delegateKeystone = await createSyncDelegateKeystone({
327
+ profileName: custodianSyncProfileName.trim() as any,
328
+ username,
329
+ deviceTag: generateDefaultDeviceTag(),
330
+ primaryTjpAddr,
331
+ delegateSecret,
332
+ custodianReqs,
333
+ additionalFrameDetails: { client: 'space-gib-web' },
340
334
  metaspace,
341
335
  space,
342
- frameDetails: delegateBuilder.getFrameDetails(),
343
- isPrimary: false
344
336
  });
345
337
 
346
338
  this.setStatus('Registering device delegate with custodian server...', 'info');
@@ -467,24 +459,6 @@ export class KeystoneCreatorComponentInstance
467
459
  animationEmoji: '🔑'
468
460
  });
469
461
 
470
- const delegateSecret = await deriveLocalCustodianDelegateSecret({ primaryTjpAddr });
471
- const username = email ? email.split('@')[0] : 'user';
472
- const custodianSyncProfileName = process.env.KEYSTONE_PROFILE_CUSTODIAN_SYNC;
473
- if (!custodianSyncProfileName || !custodianSyncProfileName.trim()) {
474
- throw new Error('KEYSTONE_PROFILE_CUSTODIAN_SYNC environment variable is missing. Expected valid profile name like "sync-profile.dev" or "sync-profile.prod". (E: 4d5e6f7890123456789abcdef4)');
475
- }
476
-
477
- const delegateBuilder = KeystoneProfileBuilder.buildKeystone(custodianSyncProfileName.trim() as any)
478
- .withUsername(`${username}-sync`)
479
- .withDescription(`Sync Delegate for ${username}`)
480
- .withDetails({
481
- client: 'space-gib-web',
482
- role: 'sync-delegate',
483
- primaryTjpAddr,
484
- custodianReqs,
485
- });
486
-
487
- const configs = await delegateBuilder.compileConfigs();
488
462
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
489
463
  const space = await metaspace.getLocalUserSpace({ lock: false });
490
464
  if (!space) {
@@ -492,14 +466,23 @@ export class KeystoneCreatorComponentInstance
492
466
  return;
493
467
  }
494
468
 
495
- const keystoneService = new KeystoneService_V1();
496
- const delegateKeystone = await keystoneService.genesis({
497
- masterSecret: delegateSecret,
498
- configs,
469
+ const delegateSecret = await getOrCreateDeviceDelegateSecret({ primaryTjpAddr });
470
+ const username = email ? email.split('@')[0] : 'user';
471
+ const custodianSyncProfileName = process.env.KEYSTONE_PROFILE_CUSTODIAN_SYNC;
472
+ if (!custodianSyncProfileName || !custodianSyncProfileName.trim()) {
473
+ throw new Error('KEYSTONE_PROFILE_CUSTODIAN_SYNC environment variable is missing. Expected valid profile name like "sync-profile.dev" or "sync-profile.prod". (E: 4d5e6f7890123456789abcdef4)');
474
+ }
475
+
476
+ const delegateKeystone = await createSyncDelegateKeystone({
477
+ profileName: custodianSyncProfileName.trim() as any,
478
+ username,
479
+ deviceTag: generateDefaultDeviceTag(),
480
+ primaryTjpAddr,
481
+ delegateSecret,
482
+ custodianReqs,
483
+ additionalFrameDetails: { client: 'space-gib-web' },
499
484
  metaspace,
500
485
  space,
501
- frameDetails: delegateBuilder.getFrameDetails(),
502
- isPrimary: false
503
486
  });
504
487
 
505
488
  // Register delegate with server
@@ -684,27 +667,22 @@ export class KeystoneCreatorComponentInstance
684
667
  });
685
668
 
686
669
  const delegateSecret = await deriveDelegateSecret({ masterSecret });
670
+ await setDeviceDelegateSecret({ primaryTjpAddr, delegateSecret });
671
+
687
672
  const sovereignSyncProfileName = process.env.KEYSTONE_PROFILE_SOVEREIGN_SYNC;
688
673
  if (!sovereignSyncProfileName || !sovereignSyncProfileName.trim()) {
689
674
  throw new Error('KEYSTONE_PROFILE_SOVEREIGN_SYNC environment variable is missing. Expected valid profile name like "sync-profile.dev" or "sync-profile.prod". (E: 5e6f7890123456789abcdef5)');
690
675
  }
691
676
 
692
- const delegateBuilder = KeystoneProfileBuilder.buildKeystone(sovereignSyncProfileName.trim() as any)
693
- .withUsername(`${username}-sync`)
694
- .withDescription(`Sync Delegate for ${username}`)
695
- .withDetails({
696
- client: 'space-gib-web',
697
- role: 'sync-delegate',
698
- primaryTjpAddr: primaryTjpAddr,
699
- });
700
- const delegateConfigs = await delegateBuilder.compileConfigs();
701
-
702
- const delegateKeystoneIbGib = await keystoneService.genesis({
703
- masterSecret: delegateSecret,
704
- configs: delegateConfigs,
677
+ const delegateKeystoneIbGib = await createSyncDelegateKeystone({
678
+ profileName: sovereignSyncProfileName.trim() as any,
679
+ username,
680
+ deviceTag: generateDefaultDeviceTag(),
681
+ primaryTjpAddr,
682
+ delegateSecret,
683
+ additionalFrameDetails: { client: 'space-gib-web' },
705
684
  metaspace,
706
685
  space,
707
- frameDetails: delegateBuilder.getFrameDetails()
708
686
  });
709
687
 
710
688
  const delegateAddr = getIbGibAddr({ ibGib: delegateKeystoneIbGib });
@@ -1009,6 +987,11 @@ export class KeystoneCreatorComponentInstance
1009
987
  this.setStatus(successMsg, "success");
1010
988
  console.log(`${lc} ✓ ${successMsg}`);
1011
989
 
990
+ // 3.5 Sanitize secret input fields from DOM
991
+ if (this.elements?.inputSecret) {
992
+ this.elements.inputSecret.value = '';
993
+ }
994
+
1012
995
  // 4. Dispatch UI navigation message to close creator and open identity manager
1013
996
  window.dispatchEvent(new CustomEvent(EVENT_IBGIB_UI_MESSAGE, {
1014
997
  detail: { action: 'show-identity-manager', addr: primaryTjpAddr },