@ibgib/space-gib 0.0.3 → 0.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.
- package/CHANGELOG.md +4 -0
- package/IMPLEMENTATION.md +9 -13
- package/README.md +7 -0
- package/dist/client/bootstrap.mjs +1 -1
- package/dist/client/bootstrap.mjs.map +1 -1
- package/dist/client/chunk-ANGVYAEK.mjs +42 -0
- package/dist/client/chunk-ANGVYAEK.mjs.map +7 -0
- package/dist/client/chunk-IRGFDQRD.mjs +1920 -0
- package/dist/client/chunk-IRGFDQRD.mjs.map +7 -0
- package/dist/client/index.html +103 -5
- package/dist/client/index.mjs +1 -1
- package/dist/client/script.mjs +1 -1
- package/dist/client/style.css +466 -61
- package/dist/respec-gib.node.mjs +5 -0
- package/dist/server/server.mjs +533 -233
- package/dist/server/server.mjs.map +2 -2
- package/package.json +6 -6
- package/src/client/AUTO-GENERATED-version.mts +1 -1
- package/src/client/components/identity-header/IMPLEMENTATION.md +45 -0
- package/src/client/components/identity-header/identity-header.css +74 -0
- package/src/client/components/identity-header/identity-header.html +10 -0
- package/src/client/components/identity-header/identity-header.mts +361 -0
- package/src/client/components/identity-manager/IMPLEMENTATION.md +100 -0
- package/src/client/components/identity-manager/identity-manager.css +467 -0
- package/src/client/components/identity-manager/identity-manager.html +113 -0
- package/src/client/components/identity-manager/identity-manager.mts +767 -0
- package/src/client/components/keystone-creator/keystone-creator.css +2 -76
- package/src/client/components/keystone-creator/keystone-creator.html +41 -26
- package/src/client/components/keystone-creator/keystone-creator.mts +178 -41
- package/src/client/dev-tools/base-tools.mts +252 -0
- package/src/client/dev-tools/common.mts +217 -0
- package/src/client/dev-tools/phase-1.mts +156 -0
- package/src/client/dev-tools/phase-2.mts +143 -0
- package/src/client/dev-tools/phase-3.mts +189 -0
- package/src/client/dev-tools/phase-4-1.mts +197 -0
- package/src/client/dev-tools/phase-4-10.mts +884 -0
- package/src/client/dev-tools/phase-4-2.mts +388 -0
- package/src/client/dev-tools/phase-4-3.mts +391 -0
- package/src/client/dev-tools/phase-4-4.mts +374 -0
- package/src/client/dev-tools/phase-4-5.mts +376 -0
- package/src/client/dev-tools/phase-4-6.mts +273 -0
- package/src/client/dev-tools/phase-4-7.mts +399 -0
- package/src/client/dev-tools/phase-4-8.mts +430 -0
- package/src/client/dev-tools/phase-4-9.mts +398 -0
- package/src/client/dev-tools/phase-4.mts +1302 -0
- package/src/client/dev-tools.mts +52 -1194
- package/src/client/index.html +103 -5
- package/src/client/style.css +466 -61
- package/src/client/ui/shell/space-gib-shell-constants.mts +0 -2
- package/src/client/ui/shell/space-gib-shell-service.mts +82 -10
- package/src/common/common-constants.mts +0 -0
- package/src/common/keystone-policies.json +40 -43
- package/src/common/keystone-policies.mts +3 -5
- package/src/server/path-helper.respec.mts +99 -94
- package/src/server/serve-gib/README.md +9 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +1 -1
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.respec.mts +1 -1
- package/src/server/serve-gib/handlers/ws/sync-upgrade-handler-base.mts +31 -3
- package/src/server/serve-gib/handlers/ws/ws-helper.mts +73 -45
- package/dist/client/chunk-2KJC5XKE.mjs +0 -31
- package/dist/client/chunk-2KJC5XKE.mjs.map +0 -7
- package/dist/client/chunk-QNIXTRFO.mjs +0 -235
- package/dist/client/chunk-QNIXTRFO.mjs.map +0 -7
|
@@ -5,16 +5,6 @@
|
|
|
5
5
|
margin: 2rem auto;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
.component-container {
|
|
9
|
-
padding: 2rem;
|
|
10
|
-
background: var(--clr-bg-glass);
|
|
11
|
-
backdrop-filter: blur(16px);
|
|
12
|
-
border-radius: var(--radius-lg);
|
|
13
|
-
border: 1px solid var(--clr-border);
|
|
14
|
-
color: var(--clr-text-primary);
|
|
15
|
-
box-shadow: var(--shadow-card);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
8
|
h2 {
|
|
19
9
|
margin-top: 0;
|
|
20
10
|
font-size: 1.5rem;
|
|
@@ -28,28 +18,6 @@ h2 {
|
|
|
28
18
|
gap: 1.5rem;
|
|
29
19
|
}
|
|
30
20
|
|
|
31
|
-
.action-row {
|
|
32
|
-
display: flex;
|
|
33
|
-
justify-content: center;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.action-btn {
|
|
37
|
-
padding: 0.75rem 1.5rem;
|
|
38
|
-
background: var(--clr-accent);
|
|
39
|
-
color: var(--clr-bg-deep);
|
|
40
|
-
border: none;
|
|
41
|
-
border-radius: var(--radius-md);
|
|
42
|
-
font-weight: 600;
|
|
43
|
-
cursor: pointer;
|
|
44
|
-
transition: all var(--t-fast);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.action-btn:hover {
|
|
48
|
-
background: #9fffa5;
|
|
49
|
-
transform: translateY(-1px);
|
|
50
|
-
box-shadow: 0 0 16px var(--clr-accent-glow);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
21
|
.input-group {
|
|
54
22
|
display: flex;
|
|
55
23
|
flex-direction: column;
|
|
@@ -61,45 +29,14 @@ h2 {
|
|
|
61
29
|
color: var(--clr-text-secondary);
|
|
62
30
|
}
|
|
63
31
|
|
|
64
|
-
.secret-input {
|
|
65
|
-
padding: 0.75rem;
|
|
66
|
-
background: rgba(0, 0, 0, 0.2);
|
|
67
|
-
border: 1px solid var(--clr-border);
|
|
68
|
-
border-radius: var(--radius-sm);
|
|
69
|
-
color: var(--clr-text-primary);
|
|
70
|
-
font-family: var(--font-mono);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.secret-input:focus {
|
|
74
|
-
outline: none;
|
|
75
|
-
border-color: var(--clr-accent);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
32
|
.status-area {
|
|
79
|
-
|
|
80
|
-
border-radius: var(--radius-md);
|
|
81
|
-
background: rgba(255, 255, 255, 0.03);
|
|
33
|
+
margin-top: 0.5rem;
|
|
82
34
|
}
|
|
83
35
|
|
|
84
36
|
.status-area.hidden {
|
|
85
37
|
display: none;
|
|
86
38
|
}
|
|
87
39
|
|
|
88
|
-
.status-msg {
|
|
89
|
-
margin: 0;
|
|
90
|
-
font-size: 0.9rem;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.status-msg.info { color: var(--clr-text-secondary); }
|
|
94
|
-
.status-msg.success { color: var(--clr-accent); }
|
|
95
|
-
.status-msg.error { color: var(--clr-warn); }
|
|
96
|
-
|
|
97
|
-
.action-btn:disabled {
|
|
98
|
-
opacity: 0.5;
|
|
99
|
-
cursor: not-allowed;
|
|
100
|
-
background: var(--clr-border);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
40
|
.result-area {
|
|
104
41
|
padding: 1.5rem;
|
|
105
42
|
background: rgba(255, 255, 255, 0.03);
|
|
@@ -121,19 +58,8 @@ h2 {
|
|
|
121
58
|
margin: 0;
|
|
122
59
|
}
|
|
123
60
|
|
|
124
|
-
.keystone-addr {
|
|
125
|
-
display: block;
|
|
126
|
-
padding: 0.75rem;
|
|
127
|
-
background: rgba(0, 0, 0, 0.3);
|
|
128
|
-
border-radius: var(--radius-sm);
|
|
129
|
-
font-family: var(--font-mono);
|
|
130
|
-
font-size: 0.85rem;
|
|
131
|
-
word-break: break-all;
|
|
132
|
-
color: var(--clr-accent);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
61
|
.warning {
|
|
136
62
|
font-size: 0.8rem;
|
|
137
63
|
color: var(--clr-warn);
|
|
138
64
|
margin: 0.5rem 0 0;
|
|
139
|
-
}
|
|
65
|
+
}
|
|
@@ -1,26 +1,41 @@
|
|
|
1
|
-
<div id="container" class="component-container">
|
|
2
|
-
<h2 id="title">Keystone Creator</h2>
|
|
3
|
-
<div class="content">
|
|
4
|
-
<p>This will generate a new root keystone (identity) for your space.</p>
|
|
5
|
-
|
|
6
|
-
<div class="input-group">
|
|
7
|
-
<label for="input-
|
|
8
|
-
<input type="
|
|
9
|
-
</div>
|
|
10
|
-
|
|
11
|
-
<div class="
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
<div id="container" class="component-container">
|
|
2
|
+
<h2 id="title">Keystone Creator</h2>
|
|
3
|
+
<div class="content">
|
|
4
|
+
<p>This will generate a new root keystone (identity) for your space.</p>
|
|
5
|
+
|
|
6
|
+
<div class="input-group">
|
|
7
|
+
<label for="input-username">Username</label>
|
|
8
|
+
<input type="text" id="input-username" placeholder="Enter your username..." class="text-input">
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="input-group">
|
|
12
|
+
<label for="input-description">Description (Optional)</label>
|
|
13
|
+
<input type="text" id="input-description" placeholder="Enter an optional description..." class="text-input">
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="input-group">
|
|
17
|
+
<label for="input-secret">Master Secret (Keep this private!)</label>
|
|
18
|
+
<input type="password" id="input-secret" placeholder="Enter your master secret..." class="secret-input">
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div class="checkbox-group" style="margin-bottom: 1.5rem; display: flex; align-items: center; gap: 0.5rem;">
|
|
22
|
+
<input type="checkbox" id="checkbox-make-active" checked style="cursor: pointer; width: 1rem; height: 1rem;">
|
|
23
|
+
<label for="checkbox-make-active" style="cursor: pointer; font-size: 0.9rem; user-select: none;">Make this the active identity</label>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div class="action-row">
|
|
27
|
+
<button id="btn-generate" class="action-btn">Generate Identity Keystone</button>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div id="status-area" class="status-area hidden">
|
|
31
|
+
<p id="status-text" class="status-msg"></p>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div id="result-area" class="result-area collapsed">
|
|
35
|
+
<h3>New Keystone Generated!</h3>
|
|
36
|
+
<p class="address-label">Address:</p>
|
|
37
|
+
<code id="keystone-addr" class="keystone-addr"></code>
|
|
38
|
+
<p class="warning">⚠️ Store this address safely. It is your root identity for this space.</p>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import thisCss from "./keystone-creator.css";
|
|
2
2
|
import thisHtml from "./keystone-creator.html";
|
|
3
|
+
import styleCss from "../../style.css";
|
|
3
4
|
|
|
4
|
-
import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
5
|
+
import { delay, extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
5
6
|
import { HashAlgorithm } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
6
7
|
import { IbGibAddr } from "@ibgib/ts-gib/dist/types.mjs";
|
|
7
8
|
import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
@@ -10,9 +11,10 @@ import { KeystoneService_V1 } from "@ibgib/core-gib/dist/keystone/keystone-servi
|
|
|
10
11
|
import {
|
|
11
12
|
KeystonePoolConfig, KeystoneChallengeType, KeystoneReplenishStrategy
|
|
12
13
|
} from "@ibgib/core-gib/dist/keystone/keystone-types.mjs";
|
|
13
|
-
import {
|
|
14
|
+
import { KeystoneProfileBuilder } from "@ibgib/core-gib/dist/keystone/policy/keystone-profile-builder.mjs";
|
|
15
|
+
import { getGlobalMetaspace_waitIfNeeded, getLocalCoupledIbGibForDomainIbGib } from "@ibgib/web-gib/dist/helpers.mjs";
|
|
14
16
|
import {
|
|
15
|
-
IbGibDynamicComponentMetaBase,
|
|
17
|
+
IbGibDynamicComponentMetaBase, IbGibFormInstanceBase,
|
|
16
18
|
} from "@ibgib/web-gib/dist/ui/component/ibgib-dynamic-component-bases.mjs";
|
|
17
19
|
import {
|
|
18
20
|
ElementsBase, IbGibDynamicComponentInstance,
|
|
@@ -23,7 +25,17 @@ import { getComponentCtorArg } from "../../helpers.web.mjs";
|
|
|
23
25
|
import { spaceGibApiBridge } from "../../api/space-gib-api-bridge.mjs";
|
|
24
26
|
import { devLog } from "../../dev-tools.mjs";
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
import {
|
|
29
|
+
createSettings, getSectionName, getSettingsScope
|
|
30
|
+
} from "@ibgib/web-gib/dist/common/settings/settings-helpers.mjs";
|
|
31
|
+
import { SettingsType } from "@ibgib/web-gib/dist/common/settings/settings-constants.mjs";
|
|
32
|
+
import { SettingsIbGib_V1 } from "@ibgib/web-gib/dist/common/settings/settings-types.mjs";
|
|
33
|
+
import { updateSpecialIndex, mut8Timeline } from "@ibgib/core-gib/dist/timeline/timeline-api.mjs";
|
|
34
|
+
import { toDto } from "@ibgib/core-gib/dist/common/other/ibgib-helper.mjs";
|
|
35
|
+
import { KEYSTONE_USERNAME_REGEXP, KEYSTONE_DESCRIPTION_REGEXP } from "@ibgib/core-gib/dist/keystone/keystone-constants.mjs";
|
|
36
|
+
import { EVENT_IBGIB_IDENTITY_REQUEST_CHANGE } from "@ibgib/web-gib/dist/ui/ui-constants.mjs";
|
|
37
|
+
|
|
38
|
+
export const KEYSTONE_CREATOR_COMPONENT_NAME = 'ibgib-keystone-creator';
|
|
27
39
|
|
|
28
40
|
/**
|
|
29
41
|
* Metadata for the Keystone Creator component.
|
|
@@ -54,7 +66,7 @@ export class KeystoneCreatorComponentMeta extends IbGibDynamicComponentMetaBase
|
|
|
54
66
|
ibGibAddr,
|
|
55
67
|
meta: this,
|
|
56
68
|
html: thisHtml,
|
|
57
|
-
css: [thisCss],
|
|
69
|
+
css: [styleCss, thisCss],
|
|
58
70
|
});
|
|
59
71
|
return component;
|
|
60
72
|
}
|
|
@@ -69,7 +81,10 @@ interface KeystoneCreatorElements extends ElementsBase {
|
|
|
69
81
|
btnGenerateEl: HTMLButtonElement;
|
|
70
82
|
resultAreaEl: HTMLDivElement;
|
|
71
83
|
keystoneAddrEl: HTMLElement;
|
|
84
|
+
inputUsername: HTMLInputElement;
|
|
85
|
+
inputDescription: HTMLInputElement;
|
|
72
86
|
inputSecret: HTMLInputElement;
|
|
87
|
+
checkboxMakeActive: HTMLInputElement;
|
|
73
88
|
statusArea: HTMLDivElement;
|
|
74
89
|
statusText: HTMLParagraphElement;
|
|
75
90
|
}
|
|
@@ -78,10 +93,11 @@ interface KeystoneCreatorElements extends ElementsBase {
|
|
|
78
93
|
* Concrete implementation of the Keystone Creator component.
|
|
79
94
|
*/
|
|
80
95
|
export class KeystoneCreatorComponentInstance
|
|
81
|
-
extends
|
|
96
|
+
extends IbGibFormInstanceBase<IbGib_V1, KeystoneCreatorElements>
|
|
82
97
|
implements IbGibDynamicComponentInstance<IbGib_V1, KeystoneCreatorElements> {
|
|
83
98
|
|
|
84
99
|
protected lc: string = `[KeystoneCreatorComponentInstance]`;
|
|
100
|
+
private hasExistingIdentities = false;
|
|
85
101
|
|
|
86
102
|
constructor() {
|
|
87
103
|
super();
|
|
@@ -99,7 +115,10 @@ export class KeystoneCreatorComponentInstance
|
|
|
99
115
|
this.elements.btnGenerateEl = this.shadowRoot!.getElementById('btn-generate') as HTMLButtonElement;
|
|
100
116
|
this.elements.resultAreaEl = this.shadowRoot!.getElementById('result-area') as HTMLDivElement;
|
|
101
117
|
this.elements.keystoneAddrEl = this.shadowRoot!.getElementById('keystone-addr') as HTMLElement;
|
|
118
|
+
this.elements.inputUsername = this.shadowRoot!.getElementById('input-username') as HTMLInputElement;
|
|
119
|
+
this.elements.inputDescription = this.shadowRoot!.getElementById('input-description') as HTMLInputElement;
|
|
102
120
|
this.elements.inputSecret = this.shadowRoot!.getElementById('input-secret') as HTMLInputElement;
|
|
121
|
+
this.elements.checkboxMakeActive = this.shadowRoot!.getElementById('checkbox-make-active') as HTMLInputElement;
|
|
103
122
|
this.elements.statusArea = this.shadowRoot!.getElementById('status-area') as HTMLDivElement;
|
|
104
123
|
this.elements.statusText = this.shadowRoot!.getElementById('status-text') as HTMLParagraphElement;
|
|
105
124
|
|
|
@@ -111,15 +130,59 @@ export class KeystoneCreatorComponentInstance
|
|
|
111
130
|
if (this.ibGibAddr && !this.ibGib) {
|
|
112
131
|
await this.loadIbGib();
|
|
113
132
|
}
|
|
133
|
+
await this.checkExistingIdentities();
|
|
114
134
|
await this.renderUI();
|
|
115
135
|
}
|
|
116
136
|
|
|
137
|
+
private async checkExistingIdentities() {
|
|
138
|
+
const lc = `${this.lc}[checkExistingIdentities]`;
|
|
139
|
+
try {
|
|
140
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
141
|
+
const space = await metaspace.getLocalUserSpace({});
|
|
142
|
+
if (space) {
|
|
143
|
+
const keystonesIndex = await metaspace.getSpecialIbGib({
|
|
144
|
+
type: "keystones",
|
|
145
|
+
space,
|
|
146
|
+
initialize: true,
|
|
147
|
+
});
|
|
148
|
+
const registeredKeystones = keystonesIndex?.rel8ns?.keystone ?? [];
|
|
149
|
+
this.hasExistingIdentities = registeredKeystones.length > 0;
|
|
150
|
+
}
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.warn(`${lc} Error checking existing identities: ${extractErrorMsg(error)}`);
|
|
153
|
+
this.hasExistingIdentities = false;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const checkbox = this.elements!.checkboxMakeActive;
|
|
157
|
+
if (checkbox) {
|
|
158
|
+
if (!this.hasExistingIdentities) {
|
|
159
|
+
checkbox.checked = true;
|
|
160
|
+
checkbox.disabled = true;
|
|
161
|
+
checkbox.title = "At least one active identity is required.";
|
|
162
|
+
} else {
|
|
163
|
+
checkbox.disabled = false;
|
|
164
|
+
checkbox.title = "";
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
117
169
|
override async disconnected(): Promise<void> {
|
|
118
170
|
// cleanup if needed
|
|
119
171
|
}
|
|
120
172
|
|
|
121
173
|
private initHandlers() {
|
|
122
174
|
this.elements!.btnGenerateEl.addEventListener('click', () => this.handleGenerate());
|
|
175
|
+
|
|
176
|
+
// Clear invalid styling when user inputs text
|
|
177
|
+
this.elements!.inputUsername.addEventListener('input', () => {
|
|
178
|
+
this.elements!.inputUsername.classList.remove('invalid');
|
|
179
|
+
});
|
|
180
|
+
this.elements!.inputDescription.addEventListener('input', () => {
|
|
181
|
+
this.elements!.inputDescription.classList.remove('invalid');
|
|
182
|
+
});
|
|
183
|
+
this.elements!.inputSecret.addEventListener('input', () => {
|
|
184
|
+
this.elements!.inputSecret.classList.remove('invalid');
|
|
185
|
+
});
|
|
123
186
|
}
|
|
124
187
|
|
|
125
188
|
/**
|
|
@@ -130,35 +193,68 @@ export class KeystoneCreatorComponentInstance
|
|
|
130
193
|
const lc = `${this.lc}[${this.handleGenerate.name}]`;
|
|
131
194
|
try {
|
|
132
195
|
console.log(`${lc} [NAG][ibgib-paradigm] starting genesis orchestration...`);
|
|
133
|
-
|
|
196
|
+
/**
|
|
197
|
+
* Delay update messages so the human eye has a chance to comprehend
|
|
198
|
+
* progress.
|
|
199
|
+
*/
|
|
200
|
+
const humanEyeDelay = 500;
|
|
134
201
|
this.setStatus("Initializing genesis...", "info");
|
|
135
202
|
|
|
136
203
|
devLog('Starting local genesis orchestration...');
|
|
204
|
+
|
|
205
|
+
// Validate Username using base class validation plumbing
|
|
206
|
+
if (!this.validateInputPattern({
|
|
207
|
+
input: this.elements!.inputUsername,
|
|
208
|
+
pattern: KEYSTONE_USERNAME_REGEXP,
|
|
209
|
+
errorMessage: "Username must be 1-63 characters (alphanumeric, underscores, hyphens, dots).",
|
|
210
|
+
required: true
|
|
211
|
+
})) {
|
|
212
|
+
this.setStatus("Invalid username. Must be 1-63 characters (alphanumeric, _, -, .).", "error");
|
|
213
|
+
devLog('✗ Invalid username.');
|
|
214
|
+
return; /* <<<< returns early */
|
|
215
|
+
}
|
|
216
|
+
const username = this.elements!.inputUsername.value.trim();
|
|
217
|
+
|
|
218
|
+
// Validate Description using base class validation plumbing
|
|
219
|
+
if (!this.validateInputPattern({
|
|
220
|
+
input: this.elements!.inputDescription,
|
|
221
|
+
pattern: KEYSTONE_DESCRIPTION_REGEXP,
|
|
222
|
+
errorMessage: "Description must be 0-128 characters and consist of English characters and common punctuation.",
|
|
223
|
+
required: false
|
|
224
|
+
})) {
|
|
225
|
+
this.setStatus("Invalid description. Alphanumeric + common punctuation, max 128 chars.", "error");
|
|
226
|
+
devLog('✗ Invalid description.');
|
|
227
|
+
return; /* <<<< returns early */
|
|
228
|
+
}
|
|
229
|
+
const description = this.elements!.inputDescription.value.trim();
|
|
230
|
+
|
|
137
231
|
const masterSecret = this.elements!.inputSecret.value;
|
|
138
232
|
if (!masterSecret) {
|
|
233
|
+
this.elements!.inputSecret.classList.add('invalid');
|
|
139
234
|
this.setStatus("Please enter a master secret.", "error");
|
|
140
235
|
devLog('✗ Please enter a master secret.');
|
|
141
|
-
return;
|
|
236
|
+
return; /* <<<< returns early */
|
|
237
|
+
} else {
|
|
238
|
+
this.elements!.inputSecret.classList.remove('invalid');
|
|
142
239
|
}
|
|
143
240
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
];
|
|
241
|
+
this.showBusy({
|
|
242
|
+
isBusy: true,
|
|
243
|
+
title: 'Generating Identity...',
|
|
244
|
+
msg: 'Preparing configuration and policy options...',
|
|
245
|
+
animationEmoji: '⚙️',
|
|
246
|
+
submitBtnSelector: '#btn-generate',
|
|
247
|
+
loadingText: 'Generating...'
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// 1. Prepare Keystone Configs using the test behavior profile (with username and description)
|
|
251
|
+
const builder = KeystoneProfileBuilder.buildKeystone('test')
|
|
252
|
+
.withUsername(username)
|
|
253
|
+
.withDescription(description)
|
|
254
|
+
.withDetails({
|
|
255
|
+
client: 'space-gib-web',
|
|
256
|
+
});
|
|
257
|
+
const configs = await builder.compileConfigs();
|
|
162
258
|
|
|
163
259
|
// 2. Get local services
|
|
164
260
|
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
@@ -166,37 +262,85 @@ export class KeystoneCreatorComponentInstance
|
|
|
166
262
|
if (!space) { throw new Error("No default space found in metaspace."); }
|
|
167
263
|
|
|
168
264
|
// 3. Perform Genesis (Local)
|
|
265
|
+
this.showBusy({
|
|
266
|
+
isBusy: true,
|
|
267
|
+
title: 'Generating Identity...',
|
|
268
|
+
msg: 'Performing cryptographic local genesis...\n(This runs compute-heavy Key Derivation Functions)',
|
|
269
|
+
animationEmoji: '🗝️'
|
|
270
|
+
});
|
|
169
271
|
const keystoneService = new KeystoneService_V1();
|
|
170
272
|
const keystoneIbGib = await keystoneService.genesis({
|
|
171
273
|
masterSecret,
|
|
172
274
|
configs,
|
|
173
275
|
metaspace,
|
|
174
276
|
space,
|
|
175
|
-
frameDetails:
|
|
277
|
+
frameDetails: builder.getFrameDetails()
|
|
176
278
|
});
|
|
177
279
|
|
|
178
280
|
const addr = getIbGibAddr({ ibGib: keystoneIbGib });
|
|
179
281
|
console.log(`${lc} [NAG][ibgib-paradigm] local genesis complete: ${addr}`);
|
|
282
|
+
await delay(humanEyeDelay); // for human eyes, not needed for functionality
|
|
180
283
|
this.setStatus("Local genesis complete. Syncing to server...", "info");
|
|
181
284
|
devLog(`✓ Local genesis complete: ${addr}`);
|
|
182
|
-
|
|
285
|
+
|
|
183
286
|
// Expose for dev tools
|
|
184
287
|
(window as any).dev_domainI = keystoneIbGib;
|
|
185
288
|
(window as any).dev_domainIMasterSecret = masterSecret;
|
|
186
289
|
|
|
187
290
|
// 4. Post to Server
|
|
188
291
|
devLog(`Posting genesis keystone to server...`);
|
|
292
|
+
this.showBusy({
|
|
293
|
+
isBusy: true,
|
|
294
|
+
title: 'Syncing to Server...',
|
|
295
|
+
msg: [
|
|
296
|
+
'Local genesis complete!',
|
|
297
|
+
'Posting genesis keystone to server sync node...',
|
|
298
|
+
'(may take awhile, depending on strength of keystone...)',
|
|
299
|
+
].join('\n'),
|
|
300
|
+
animationEmoji: '🔄'
|
|
301
|
+
});
|
|
189
302
|
const resSync = await spaceGibApiBridge.postGenesisKeystone(keystoneIbGib);
|
|
190
303
|
if (!resSync.success) {
|
|
191
304
|
this.setStatus(`Sync failed: ${resSync.message}`, "error");
|
|
192
305
|
devLog(`✗ Server rejected genesis keystone: ${resSync.message}`);
|
|
193
|
-
return;
|
|
306
|
+
return; /* <<<< returns early */
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// 5. Register with the keystones special index
|
|
310
|
+
this.showBusy({
|
|
311
|
+
isBusy: true,
|
|
312
|
+
title: 'Registering Identity...',
|
|
313
|
+
msg: 'Server sync succeeded!\nUpdating local identity indexes and scope settings...',
|
|
314
|
+
animationEmoji: '💾'
|
|
315
|
+
});
|
|
316
|
+
await delay(humanEyeDelay); // for human eyes, not needed for functionality
|
|
317
|
+
await updateSpecialIndex({
|
|
318
|
+
type: "keystones",
|
|
319
|
+
rel8nInfos: [
|
|
320
|
+
{
|
|
321
|
+
rel8nName: "keystone",
|
|
322
|
+
ibGibs: [toDto({ ibGib: keystoneIbGib })],
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
metaspace,
|
|
326
|
+
space,
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// 6. Request to make the new identity active if the checkbox is checked
|
|
330
|
+
const makeActive = this.elements!.checkboxMakeActive?.checked;
|
|
331
|
+
if (makeActive) {
|
|
332
|
+
window.dispatchEvent(new CustomEvent(EVENT_IBGIB_IDENTITY_REQUEST_CHANGE, {
|
|
333
|
+
detail: { activeIdentityAddr: addr },
|
|
334
|
+
bubbles: true,
|
|
335
|
+
composed: true
|
|
336
|
+
}));
|
|
194
337
|
}
|
|
195
338
|
|
|
196
|
-
//
|
|
339
|
+
// 7. Success
|
|
197
340
|
this.elements!.keystoneAddrEl.textContent = addr;
|
|
198
341
|
this.elements!.statusArea.classList.remove('hidden');
|
|
199
342
|
this.setStatus("Keystone successfully created and synced!", "success");
|
|
343
|
+
await delay(humanEyeDelay); // for human eyes, not needed for functionality
|
|
200
344
|
devLog(`✓ Keystone successfully created and synced!`);
|
|
201
345
|
|
|
202
346
|
} catch (error) {
|
|
@@ -205,20 +349,13 @@ export class KeystoneCreatorComponentInstance
|
|
|
205
349
|
this.setStatus(`Error: ${emsg}`, "error");
|
|
206
350
|
devLog(`✗ Error: ${emsg}`);
|
|
207
351
|
} finally {
|
|
208
|
-
this.
|
|
352
|
+
this.showBusy({
|
|
353
|
+
isBusy: false,
|
|
354
|
+
submitBtnSelector: '#btn-generate'
|
|
355
|
+
});
|
|
209
356
|
}
|
|
210
357
|
}
|
|
211
358
|
|
|
212
|
-
private setLoading(loading: boolean) {
|
|
213
|
-
this.elements!.btnGenerateEl.disabled = loading;
|
|
214
|
-
this.elements!.btnGenerateEl.textContent = loading ? "Generating..." : "Generate Identity Keystone";
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
private setStatus(msg: string, type: 'info' | 'success' | 'error') {
|
|
218
|
-
this.elements!.statusText.textContent = msg;
|
|
219
|
-
this.elements!.statusText.className = `status-msg ${type}`;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
359
|
protected override async renderUI(): Promise<void> {
|
|
223
360
|
// No complex rendering needed for this simple creator component yet
|
|
224
361
|
}
|