aegis-desktop 1.0.4 → 1.0.6
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/lib/account-key.js +6 -1
- package/main.js +21 -8
- package/package.json +1 -1
- package/renderer/app.js +34 -12
- package/renderer/index.html +4 -0
package/lib/account-key.js
CHANGED
|
@@ -55,4 +55,9 @@ function createAccountKey({ aegis, credentials, persistKey, provision, onChange
|
|
|
55
55
|
return { status, recordStartup, registerAccount };
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
// A key this host saved on purpose outranks one minted for a fresh device at startup.
|
|
59
|
+
function startupKeyOverride({ mintedKey, hostKey }) {
|
|
60
|
+
return mintedKey && hostKey && hostKey !== mintedKey ? hostKey : null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = { createAccountKey, provisionFailureText, startupKeyOverride };
|
package/main.js
CHANGED
|
@@ -152,7 +152,7 @@ try {
|
|
|
152
152
|
// backed by transport-only modules in desktop/lib/. No brain logic enters here.
|
|
153
153
|
const os = require('node:os');
|
|
154
154
|
const { createLocalEngine } = require('./lib/local/engine.js');
|
|
155
|
-
const { createAccountKey } = require('./lib/account-key.js');
|
|
155
|
+
const { createAccountKey, startupKeyOverride } = require('./lib/account-key.js');
|
|
156
156
|
const { createSettingsStore, isReservedNamespace } = require('./lib/settings.js');
|
|
157
157
|
const sessionStore = require('./lib/sync/sessions.js');
|
|
158
158
|
const memoryQueue = require('./lib/sync/memory-queue.js');
|
|
@@ -3333,6 +3333,7 @@ function bootstrap() {
|
|
|
3333
3333
|
provision: autoProvision.autoProvisionApiKey,
|
|
3334
3334
|
onChange: (state) => broadcastAccountStatus(state),
|
|
3335
3335
|
});
|
|
3336
|
+
const keyPresentAtStart = Boolean(aegis.apiKey);
|
|
3336
3337
|
const earlyKeyProvision = autoProvision.autoProvisionApiKey(aegis, credentials).then((result) => {
|
|
3337
3338
|
accountKey.recordStartup(result);
|
|
3338
3339
|
if (!result.key && !aegis.apiKey) {
|
|
@@ -3910,13 +3911,25 @@ function bootstrap() {
|
|
|
3910
3911
|
// registration attempt, and earlyKeyProvision's own .then() already
|
|
3911
3912
|
// warns on failure, so there is nothing further to report if it
|
|
3912
3913
|
// didn't land.
|
|
3913
|
-
await earlyKeyProvision;
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3914
|
+
const early = await earlyKeyProvision;
|
|
3915
|
+
// A key minted just now only means "no key was saved yet" — a key the user
|
|
3916
|
+
// saved in Settings before the shared store mirrored it would otherwise be
|
|
3917
|
+
// overwritten by the device's fresh account on this first start.
|
|
3918
|
+
const override = startupKeyOverride({
|
|
3919
|
+
mintedKey: keyPresentAtStart ? '' : early.key,
|
|
3920
|
+
hostKey: credentials.normalizeApiKey(settings.aegisRawKey()),
|
|
3921
|
+
});
|
|
3922
|
+
if (override) {
|
|
3923
|
+
credentials.saveApiKey(override);
|
|
3924
|
+
aegis.setApiKey(override);
|
|
3925
|
+
} else {
|
|
3926
|
+
const chosen = credentials.preferNewest(settings.aegisRawKey(), settings.aegisKeySavedAt());
|
|
3927
|
+
if (chosen.key) {
|
|
3928
|
+
aegis.setApiKey(chosen.key);
|
|
3929
|
+
// The shared store is the newer write: bring this host's encrypted copy
|
|
3930
|
+
// up to date so a CLI rotation does not have to be redone in Settings.
|
|
3931
|
+
if (chosen.source === 'shared') settings.setAegisKey(chosen.key);
|
|
3932
|
+
}
|
|
3920
3933
|
}
|
|
3921
3934
|
}
|
|
3922
3935
|
// ── presence beacon ───────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aegis-desktop",
|
|
3
3
|
"productName": "AEGIS Desktop",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.6",
|
|
5
5
|
"description": "Thin Electron host for AEGIS — a local chat UI over the shared client/aegis.js transport. Ships transport + UI only; engine logic stays server-side.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "AEGIS Code",
|
package/renderer/app.js
CHANGED
|
@@ -76,6 +76,8 @@ const ELEMENT_IDS = {
|
|
|
76
76
|
accountBanner: 'account-banner',
|
|
77
77
|
accountBannerText: 'account-banner-text',
|
|
78
78
|
accountRetryBtn: 'account-retry-btn',
|
|
79
|
+
keysAccount: 'keys-account',
|
|
80
|
+
keysAccountRetry: 'keys-account-retry',
|
|
79
81
|
connDot: 'conn-dot',
|
|
80
82
|
connText: 'conn-text',
|
|
81
83
|
app: 'st-app',
|
|
@@ -1143,17 +1145,35 @@ function renderUpdateBanner(state) {
|
|
|
1143
1145
|
els.updateBanner.hidden = false;
|
|
1144
1146
|
}
|
|
1145
1147
|
|
|
1148
|
+
/** Why the last account registration failed; null while the account is set up. */
|
|
1149
|
+
let accountFailureReason = null;
|
|
1150
|
+
|
|
1146
1151
|
function renderAccountBanner(state) {
|
|
1152
|
+
accountFailureReason = state && state.status === 'no-key' ? state.reason : null;
|
|
1153
|
+
renderKeysPopup();
|
|
1147
1154
|
if (!els.accountBanner) return;
|
|
1148
|
-
if (!
|
|
1155
|
+
if (!accountFailureReason) {
|
|
1149
1156
|
els.accountBanner.hidden = true;
|
|
1150
1157
|
return;
|
|
1151
1158
|
}
|
|
1152
|
-
els.accountBannerText.textContent =
|
|
1153
|
-
`No AEGIS account key on this machine: ${state.reason}.`;
|
|
1159
|
+
els.accountBannerText.textContent = `No AEGIS account key on this machine: ${accountFailureReason}.`;
|
|
1154
1160
|
els.accountBanner.hidden = false;
|
|
1155
1161
|
}
|
|
1156
1162
|
|
|
1163
|
+
/** Retry registration from either surface; a success re-reads status so the sheet and key rows update. */
|
|
1164
|
+
function retryAccountSetup(button) {
|
|
1165
|
+
button.disabled = true;
|
|
1166
|
+
aegis.registerAccount()
|
|
1167
|
+
.then((state) => {
|
|
1168
|
+
renderAccountBanner(state);
|
|
1169
|
+
if (!state) return refreshAfterKeyChange();
|
|
1170
|
+
})
|
|
1171
|
+
.catch((err) => renderAccountBanner({ status: 'no-key', reason: String((err && err.message) || err) }))
|
|
1172
|
+
.finally(() => {
|
|
1173
|
+
button.disabled = false;
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1157
1177
|
async function loadAccountInfo() {
|
|
1158
1178
|
try {
|
|
1159
1179
|
const verify = await aegis.verifyApiKey();
|
|
@@ -2889,6 +2909,13 @@ function renderKeysPopup() {
|
|
|
2889
2909
|
if (els.keysRowAegis) els.keysRowAegis.classList.toggle('set', aegisSet);
|
|
2890
2910
|
if (els.keysRowByok) els.keysRowByok.classList.toggle('set', byokSet);
|
|
2891
2911
|
if (els.keysCount) els.keysCount.textContent = `${(aegisSet ? 1 : 0) + (byokSet ? 1 : 0)} / 2`;
|
|
2912
|
+
if (els.keysAccount) {
|
|
2913
|
+
els.keysAccount.hidden = !accountFailureReason;
|
|
2914
|
+
els.keysAccount.textContent = accountFailureReason
|
|
2915
|
+
? `The AEGIS account key could not be set up: ${accountFailureReason}.`
|
|
2916
|
+
: '';
|
|
2917
|
+
}
|
|
2918
|
+
if (els.keysAccountRetry) els.keysAccountRetry.hidden = !accountFailureReason;
|
|
2892
2919
|
if (els.keysHint) {
|
|
2893
2920
|
els.keysHint.textContent =
|
|
2894
2921
|
aegisSet && byokSet
|
|
@@ -5720,15 +5747,10 @@ async function init() {
|
|
|
5720
5747
|
if (els.accountBanner && aegis.onAccountStatus) {
|
|
5721
5748
|
aegis.onAccountStatus(renderAccountBanner);
|
|
5722
5749
|
aegis.accountStatus().then(renderAccountBanner).catch((err) => console.warn('account status unavailable', err));
|
|
5723
|
-
els.accountRetryBtn.addEventListener('click', () =>
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
.catch((err) => renderAccountBanner({ status: 'no-key', reason: String((err && err.message) || err) }))
|
|
5728
|
-
.finally(() => {
|
|
5729
|
-
els.accountRetryBtn.disabled = false;
|
|
5730
|
-
});
|
|
5731
|
-
});
|
|
5750
|
+
els.accountRetryBtn.addEventListener('click', () => retryAccountSetup(els.accountRetryBtn));
|
|
5751
|
+
if (els.keysAccountRetry) {
|
|
5752
|
+
els.keysAccountRetry.addEventListener('click', () => retryAccountSetup(els.keysAccountRetry));
|
|
5753
|
+
}
|
|
5732
5754
|
}
|
|
5733
5755
|
|
|
5734
5756
|
if (els.updateBanner && aegis.onUpdateStatus) {
|
package/renderer/index.html
CHANGED
|
@@ -839,9 +839,13 @@
|
|
|
839
839
|
</div>
|
|
840
840
|
</div>
|
|
841
841
|
|
|
842
|
+
<p class="hint" id="keys-account" role="alert" hidden></p>
|
|
842
843
|
<p class="hint" id="keys-hint"></p>
|
|
843
844
|
|
|
844
845
|
<div class="keys-actions">
|
|
846
|
+
<button type="button" id="keys-account-retry" class="ghost-btn" hidden>
|
|
847
|
+
Retry account setup
|
|
848
|
+
</button>
|
|
845
849
|
<a
|
|
846
850
|
class="ghost-btn"
|
|
847
851
|
id="keys-get"
|