@ibgib/web-gib 0.0.60 → 0.0.62

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 (89) 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/helpers.web.d.mts +3 -1
  7. package/dist/helpers.web.d.mts.map +1 -1
  8. package/dist/helpers.web.mjs +17 -1
  9. package/dist/helpers.web.mjs.map +1 -1
  10. package/dist/identity/device-delegate-helper.d.mts +91 -0
  11. package/dist/identity/device-delegate-helper.d.mts.map +1 -0
  12. package/dist/identity/device-delegate-helper.mjs +190 -0
  13. package/dist/identity/device-delegate-helper.mjs.map +1 -0
  14. package/dist/identity/device-delegate.respec.d.mts +2 -0
  15. package/dist/identity/device-delegate.respec.d.mts.map +1 -0
  16. package/dist/identity/device-delegate.respec.mjs +106 -0
  17. package/dist/identity/device-delegate.respec.mjs.map +1 -0
  18. package/dist/identity/keystone-sync-service.d.mts +18 -0
  19. package/dist/identity/keystone-sync-service.d.mts.map +1 -1
  20. package/dist/identity/keystone-sync-service.mjs +77 -1
  21. package/dist/identity/keystone-sync-service.mjs.map +1 -1
  22. package/dist/identity/passkey-helper.d.mts +72 -0
  23. package/dist/identity/passkey-helper.d.mts.map +1 -0
  24. package/dist/identity/passkey-helper.mjs +237 -0
  25. package/dist/identity/passkey-helper.mjs.map +1 -0
  26. package/dist/identity/passkey.respec.d.mts +2 -0
  27. package/dist/identity/passkey.respec.d.mts.map +1 -0
  28. package/dist/identity/passkey.respec.mjs +169 -0
  29. package/dist/identity/passkey.respec.mjs.map +1 -0
  30. package/dist/index.d.mts +2 -1
  31. package/dist/index.d.mts.map +1 -1
  32. package/dist/index.mjs +2 -2
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/storage/storage-helpers.web.d.mts +9 -0
  35. package/dist/storage/storage-helpers.web.d.mts.map +1 -1
  36. package/dist/storage/storage-helpers.web.mjs +42 -0
  37. package/dist/storage/storage-helpers.web.mjs.map +1 -1
  38. package/dist/ui/component/identity/add-device/add-device.d.mts.map +1 -1
  39. package/dist/ui/component/identity/add-device/add-device.mjs +31 -43
  40. package/dist/ui/component/identity/add-device/add-device.mjs.map +1 -1
  41. package/dist/ui/component/identity/keystone-creator/keystone-creator.d.mts +18 -1
  42. package/dist/ui/component/identity/keystone-creator/keystone-creator.d.mts.map +1 -1
  43. package/dist/ui/component/identity/keystone-creator/keystone-creator.html +42 -3
  44. package/dist/ui/component/identity/keystone-creator/keystone-creator.mjs +524 -104
  45. package/dist/ui/component/identity/keystone-creator/keystone-creator.mjs.map +1 -1
  46. package/dist/ui/component/identity/keystone-details/keystone-details.d.mts +19 -1
  47. package/dist/ui/component/identity/keystone-details/keystone-details.d.mts.map +1 -1
  48. package/dist/ui/component/identity/keystone-details/keystone-details.html +38 -0
  49. package/dist/ui/component/identity/keystone-details/keystone-details.mjs +1217 -132
  50. package/dist/ui/component/identity/keystone-details/keystone-details.mjs.map +1 -1
  51. package/dist/ui/component/identity/remove-device/remove-device.d.mts.map +1 -1
  52. package/dist/ui/component/identity/remove-device/remove-device.mjs +1 -0
  53. package/dist/ui/component/identity/remove-device/remove-device.mjs.map +1 -1
  54. package/dist/ui/ui-constants.d.mts +1 -0
  55. package/dist/ui/ui-constants.d.mts.map +1 -1
  56. package/dist/ui/ui-constants.mjs +1 -0
  57. package/dist/ui/ui-constants.mjs.map +1 -1
  58. package/dist/ui/ui-helpers.d.mts +3 -0
  59. package/dist/ui/ui-helpers.d.mts.map +1 -1
  60. package/dist/ui/ui-helpers.mjs +110 -6
  61. package/dist/ui/ui-helpers.mjs.map +1 -1
  62. package/dist/ui/ui-types.d.mts +5 -0
  63. package/dist/ui/ui-types.d.mts.map +1 -1
  64. package/package.json +2 -2
  65. package/src/AUTO-GENERATED-version.mts +1 -1
  66. package/src/helpers.mts +1 -0
  67. package/src/helpers.web.mts +22 -2
  68. package/src/identity/custodian-delegate-helper.mts.bak +7 -0
  69. package/src/identity/device-delegate-helper.mts +268 -0
  70. package/src/identity/device-delegate.respec.mts +125 -0
  71. package/src/identity/keystone-sync-service.mts +95 -2
  72. package/src/identity/passkey-helper.mts +304 -0
  73. package/src/identity/passkey.respec.mts +194 -0
  74. package/src/index.mts +2 -2
  75. package/src/storage/storage-helpers.web.mts +47 -0
  76. package/src/ui/component/identity/add-device/add-device.mts +37 -48
  77. package/src/ui/component/identity/keystone-creator/keystone-creator.html +42 -3
  78. package/src/ui/component/identity/keystone-creator/keystone-creator.mts +568 -111
  79. package/src/ui/component/identity/keystone-details/keystone-details.html +38 -0
  80. package/src/ui/component/identity/keystone-details/keystone-details.mts +1290 -142
  81. package/src/ui/component/identity/remove-device/remove-device.mts +1 -0
  82. package/src/ui/ui-constants.mts +1 -0
  83. package/src/ui/ui-helpers.mts +118 -5
  84. package/src/ui/ui-types.mts +6 -0
  85. package/dist/identity/custodian-delegate-helper.d.mts +0 -22
  86. package/dist/identity/custodian-delegate-helper.d.mts.map +0 -1
  87. package/dist/identity/custodian-delegate-helper.mjs +0 -67
  88. package/dist/identity/custodian-delegate-helper.mjs.map +0 -1
  89. package/src/identity/custodian-delegate-helper.mts +0 -86
@@ -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');
@@ -632,6 +615,7 @@ export class AddDeviceComponentInstance
632
615
  parentKeystone: primaryKeystone,
633
616
  delegateKeystone,
634
617
  masterSecret,
618
+ signingPoolId: 'manage',
635
619
  allowedVerbs: [KEYSTONE_VERB_SYNC, KEYSTONE_VERB_CONNECT],
636
620
  metaspace,
637
621
  space,
@@ -765,6 +749,11 @@ export class AddDeviceComponentInstance
765
749
 
766
750
  await delay(humanEyeDelay);
767
751
 
752
+ // 4.5 Sanitize password input fields from DOM
753
+ if (this.elements?.inputPassword) {
754
+ this.elements.inputPassword.value = '';
755
+ }
756
+
768
757
  // 5. Navigate to identity manager
769
758
  window.dispatchEvent(new CustomEvent(EVENT_IBGIB_UI_MESSAGE, {
770
759
  detail: { action: 'show-identity-manager', addr: primaryTjpAddr },
@@ -4,11 +4,13 @@
4
4
  <!-- Mode Selector Tabs -->
5
5
  <div class="mode-tabs">
6
6
  <button id="tab-quick" class="mode-tab active">⚡ Quick (Passwordless)</button>
7
+ <button id="tab-passkey" class="mode-tab">🛡️ Passkey / Hardware</button>
7
8
  <button id="tab-password" class="mode-tab">🔑 Password-based</button>
8
9
  </div>
9
10
 
10
11
  <!-- Mode Subtitles -->
11
12
  <p id="subtitle-quick" class="subtitle">⚡ Skip passwords — sign in with Google, GitHub, or an Email code. You can always set up a password later.</p>
13
+ <p id="subtitle-passkey" class="subtitle hidden">🛡️ Sovereign & Passwordless — secure your identity with Touch ID, Windows Hello, or a YubiKey.</p>
12
14
  <p id="subtitle-password" class="subtitle hidden">🔑 Full local ownership — your password never leaves your device. You can link Google or GitHub later.</p>
13
15
 
14
16
  <div class="content">
@@ -49,12 +51,49 @@
49
51
  <div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;">
50
52
  <input type="text" id="input-quick-otp" maxlength="6" placeholder="123456" class="text-input" style="font-family: monospace; font-size: 1.2rem; letter-spacing: 4px; text-align: center; max-width: 160px;">
51
53
  <button id="btn-quick-verify-code" class="action-btn" style="white-space: nowrap; width: auto;">Verify Code</button>
54
+ <button id="btn-quick-resend-code" class="action-btn secondary" type="button" style="white-space: nowrap; width: auto; font-size: 0.85rem; padding: 0.4rem 0.8rem; background: #45475a; color: #cdd6f4;">Resend Code</button>
52
55
  </div>
53
56
  </div>
54
57
  </div>
55
58
 
56
59
  <!-- ----------------------------------------------------------------- -->
57
- <!-- Tab 2: Password-based Content -->
60
+ <!-- Tab 2: Passkey / Hardware Biometrics Content -->
61
+ <!-- ----------------------------------------------------------------- -->
62
+ <div id="panel-passkey" class="tab-panel hidden">
63
+ <div class="input-group">
64
+ <label for="input-passkey-username">Username</label>
65
+ <input type="text" id="input-passkey-username" placeholder="Enter your username..." class="text-input">
66
+ </div>
67
+
68
+ <div class="input-group">
69
+ <label for="input-passkey-description">Description (Optional)</label>
70
+ <input type="text" id="input-passkey-description" placeholder="Enter an optional description..." class="text-input">
71
+ </div>
72
+
73
+ <div class="input-group">
74
+ <label for="input-passkey-email">Primary Email (Optional)</label>
75
+ <input type="email" id="input-passkey-email" placeholder="Enter your primary email address..." class="text-input">
76
+ </div>
77
+
78
+ <div class="input-group">
79
+ <label for="input-passkey-name">Passkey / Device Label</label>
80
+ <input type="text" id="input-passkey-name" placeholder="e.g. MacBook Touch ID, YubiKey 5Ci, Android Phone..." class="text-input">
81
+ </div>
82
+
83
+ <div class="checkbox-group" style="margin-top: 0.5rem; margin-bottom: 1rem; display: flex; align-items: center; gap: 0.5rem;">
84
+ <input type="checkbox" id="checkbox-passkey-make-active" checked style="cursor: pointer; width: 1rem; height: 1rem;">
85
+ <label for="checkbox-passkey-make-active" style="cursor: pointer; font-size: 0.9rem; user-select: none;">Make this the active identity</label>
86
+ </div>
87
+
88
+ <div class="action-row">
89
+ <button id="btn-generate-passkey" class="action-btn">
90
+ 🛡️ Create Identity with Passkey / Biometrics
91
+ </button>
92
+ </div>
93
+ </div>
94
+
95
+ <!-- ----------------------------------------------------------------- -->
96
+ <!-- Tab 3: Password-based Content -->
58
97
  <!-- ----------------------------------------------------------------- -->
59
98
  <div id="panel-password" class="tab-panel hidden">
60
99
  <div class="input-group">
@@ -99,8 +138,8 @@
99
138
  <p style="font-size: 0.82rem; color: #a6adc8; margin-top: 0.25rem; margin-bottom: 0.75rem;">A 6-digit verification code was sent to your email. Enter it below to activate your identity:</p>
100
139
  <div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;">
101
140
  <input type="text" id="input-verify-code" maxlength="6" placeholder="123456" class="text-input" style="font-family: monospace; font-size: 1.2rem; letter-spacing: 4px; text-align: center; max-width: 160px;">
102
- <button id="btn-submit-code" class="action-btn" style="white-space: nowrap;">Verify Code</button>
103
- <button id="btn-resend-code" class="action-btn" style="white-space: nowrap; background: #45475a; color: #cdd6f4;">Resend Code</button>
141
+ <button id="btn-submit-code" class="action-btn" style="white-space: nowrap; width: auto;">Verify Code</button>
142
+ <button id="btn-resend-code" class="action-btn secondary" type="button" style="white-space: nowrap; width: auto; font-size: 0.85rem; padding: 0.4rem 0.8rem; background: #45475a; color: #cdd6f4;">Resend Code</button>
104
143
  </div>
105
144
  </div>
106
145