aegis-desktop 1.0.6 → 1.0.7
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 +4 -12
- package/main.js +3 -2
- package/package.json +1 -1
- package/vendor/aegis.js +3 -2
- package/vendor/auto-provision.js +24 -7
- package/vendor/device-fingerprint.js +1 -8
package/lib/account-key.js
CHANGED
|
@@ -8,15 +8,7 @@
|
|
|
8
8
|
* Pure: Electron, the store and the provisioner are injected.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
function
|
|
12
|
-
const err = result && result.error;
|
|
13
|
-
if (!err) return 'the server returned no account key';
|
|
14
|
-
if (err.status === 429) return 'too many sign-ups from this network — try again later';
|
|
15
|
-
if (!err.status || err.status === 408 || err.status >= 500) return 'could not reach aegiscloud.org';
|
|
16
|
-
return `the server refused the request (HTTP ${err.status})`;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function createAccountKey({ aegis, credentials, persistKey, provision, onChange }) {
|
|
11
|
+
function createAccountKey({ aegis, credentials, persistKey, provision, describeFailure, onChange }) {
|
|
20
12
|
let failure = null;
|
|
21
13
|
let inFlight = null;
|
|
22
14
|
|
|
@@ -26,7 +18,7 @@ function createAccountKey({ aegis, credentials, persistKey, provision, onChange
|
|
|
26
18
|
}
|
|
27
19
|
|
|
28
20
|
function recordStartup(result) {
|
|
29
|
-
failure = (result.key || aegis.apiKey) ? null :
|
|
21
|
+
failure = (result.key || aegis.apiKey) ? null : describeFailure(result);
|
|
30
22
|
onChange(status());
|
|
31
23
|
}
|
|
32
24
|
|
|
@@ -39,7 +31,7 @@ function createAccountKey({ aegis, credentials, persistKey, provision, onChange
|
|
|
39
31
|
persistKey(result.key);
|
|
40
32
|
failure = null;
|
|
41
33
|
} else {
|
|
42
|
-
failure =
|
|
34
|
+
failure = describeFailure(result);
|
|
43
35
|
}
|
|
44
36
|
const state = status();
|
|
45
37
|
onChange(state);
|
|
@@ -60,4 +52,4 @@ function startupKeyOverride({ mintedKey, hostKey }) {
|
|
|
60
52
|
return mintedKey && hostKey && hostKey !== mintedKey ? hostKey : null;
|
|
61
53
|
}
|
|
62
54
|
|
|
63
|
-
module.exports = { createAccountKey,
|
|
55
|
+
module.exports = { createAccountKey, startupKeyOverride };
|
package/main.js
CHANGED
|
@@ -3330,11 +3330,12 @@ function bootstrap() {
|
|
|
3330
3330
|
aegis,
|
|
3331
3331
|
credentials,
|
|
3332
3332
|
persistKey: (key) => settings.setAegisKey(key),
|
|
3333
|
-
provision: autoProvision.autoProvisionApiKey,
|
|
3333
|
+
provision: (client, creds) => autoProvision.autoProvisionApiKey(client, creds, { app: 'desktop' }),
|
|
3334
|
+
describeFailure: autoProvision.provisionFailureText,
|
|
3334
3335
|
onChange: (state) => broadcastAccountStatus(state),
|
|
3335
3336
|
});
|
|
3336
3337
|
const keyPresentAtStart = Boolean(aegis.apiKey);
|
|
3337
|
-
const earlyKeyProvision = autoProvision.autoProvisionApiKey(aegis, credentials).then((result) => {
|
|
3338
|
+
const earlyKeyProvision = autoProvision.autoProvisionApiKey(aegis, credentials, { app: 'desktop' }).then((result) => {
|
|
3338
3339
|
accountKey.recordStartup(result);
|
|
3339
3340
|
if (!result.key && !aegis.apiKey) {
|
|
3340
3341
|
const reason =
|
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.7",
|
|
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/vendor/aegis.js
CHANGED
|
@@ -855,10 +855,11 @@ function createClient(opts = {}) {
|
|
|
855
855
|
* zero balance. Re-registering an already-known fingerprint does NOT
|
|
856
856
|
* re-grant it; the pool balance gate still applies once the allowance is
|
|
857
857
|
* spent or the 30 days lapse. Sends no API key of its own — there isn't
|
|
858
|
-
* one yet.
|
|
858
|
+
* one yet. `opts.app` names the host ('cli' | 'desktop' | 'mcp') so the
|
|
859
|
+
* server files this machine under its real name, not 'other'.
|
|
859
860
|
*/
|
|
860
861
|
async function registerDevice(fingerprint, opts) {
|
|
861
|
-
return apiPost('/api/v1/auth/register-device', { fingerprint }, undefined, opts);
|
|
862
|
+
return apiPost('/api/v1/auth/register-device', { fingerprint, app: opts && opts.app }, undefined, opts);
|
|
862
863
|
}
|
|
863
864
|
|
|
864
865
|
/** Build the OpenAI-style messages array from either a full history or the
|
package/vendor/auto-provision.js
CHANGED
|
@@ -43,30 +43,47 @@ function isTransientRegisterError(err) {
|
|
|
43
43
|
return !status || status === 408 || status >= 500;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// Why automatic registration gave up, in words a host can show the user.
|
|
47
|
+
function provisionFailureText(result) {
|
|
48
|
+
const err = result && result.error;
|
|
49
|
+
if (!err) return 'the server returned no account key';
|
|
50
|
+
if (err.status === 429) return 'too many sign-ups from this network — try again later';
|
|
51
|
+
if (err.status >= 500) return `aegiscloud.org failed to register this device: ${err.message}`;
|
|
52
|
+
if (isTransientRegisterError(err)) return 'could not reach aegiscloud.org';
|
|
53
|
+
return `the server refused the request (HTTP ${err.status})`;
|
|
54
|
+
}
|
|
55
|
+
|
|
46
56
|
/**
|
|
47
57
|
* @param {object} aegisClient A client from client/aegis.js (createClient()).
|
|
48
58
|
* @param {object} credentials client/credentials.js (or a compatible double).
|
|
49
|
-
* @param {number[]} [
|
|
50
|
-
*
|
|
59
|
+
* @param {{app?: string, retryDelaysMs?: number[]}} [options] `app` names the host
|
|
60
|
+
* for the server's presence panel; `retryDelaysMs` waits before each retry of a
|
|
61
|
+
* transient failure.
|
|
62
|
+
* @returns {Promise<{ok: boolean, key: string, trialGranted?: boolean, error?: Error}>}
|
|
51
63
|
* `ok` is true only when a usable key was obtained AND persisted to the
|
|
52
64
|
* shared store; `aegisClient.setApiKey()` has already been called on
|
|
53
65
|
* success, so the caller's client is immediately usable either way it
|
|
54
|
-
* inspects `ok`.
|
|
66
|
+
* inspects `ok`. `trialGranted` is false when the server withheld the
|
|
67
|
+
* welcome trial (the account and key are still valid).
|
|
55
68
|
*/
|
|
56
|
-
async function autoProvisionApiKey(aegisClient, credentials,
|
|
69
|
+
async function autoProvisionApiKey(aegisClient, credentials, options = {}) {
|
|
70
|
+
if (Array.isArray(options)) {
|
|
71
|
+
throw new TypeError('autoProvisionApiKey takes { app, retryDelaysMs }; a bare retry array is no longer accepted');
|
|
72
|
+
}
|
|
57
73
|
if (aegisClient.apiKey) return { ok: true, key: aegisClient.apiKey };
|
|
74
|
+
const { app, retryDelaysMs = DEVICE_REGISTER_RETRY_DELAYS_MS } = options;
|
|
58
75
|
let lastError = null;
|
|
59
76
|
for (let attempt = 0; attempt <= retryDelaysMs.length; attempt++) {
|
|
60
77
|
if (attempt > 0) await new Promise((resolve) => setTimeout(resolve, retryDelaysMs[attempt - 1]));
|
|
61
78
|
const controller = new AbortController();
|
|
62
79
|
const timer = setTimeout(() => controller.abort(), DEVICE_REGISTER_TIMEOUT_MS);
|
|
63
80
|
try {
|
|
64
|
-
const data = await aegisClient.registerDevice(machineFingerprint(), { signal: controller.signal });
|
|
81
|
+
const data = await aegisClient.registerDevice(machineFingerprint(), { app, signal: controller.signal });
|
|
65
82
|
const key = data && typeof data.api_key === 'string' ? data.api_key.trim() : '';
|
|
66
83
|
if (!key) return { ok: false, key: '' };
|
|
67
84
|
const saved = credentials.saveApiKey(key);
|
|
68
85
|
aegisClient.setApiKey(key);
|
|
69
|
-
return { ok: !!saved.ok, key };
|
|
86
|
+
return { ok: !!saved.ok, key, trialGranted: data.trial_granted };
|
|
70
87
|
} catch (err) {
|
|
71
88
|
lastError = err;
|
|
72
89
|
if (!isTransientRegisterError(err)) break;
|
|
@@ -77,4 +94,4 @@ async function autoProvisionApiKey(aegisClient, credentials, retryDelaysMs = DEV
|
|
|
77
94
|
return { ok: false, key: '', error: lastError };
|
|
78
95
|
}
|
|
79
96
|
|
|
80
|
-
module.exports = { autoProvisionApiKey, DEVICE_REGISTER_TIMEOUT_MS, DEVICE_REGISTER_RETRY_DELAYS_MS };
|
|
97
|
+
module.exports = { autoProvisionApiKey, provisionFailureText, DEVICE_REGISTER_TIMEOUT_MS, DEVICE_REGISTER_RETRY_DELAYS_MS };
|
|
@@ -111,8 +111,7 @@ function persistedInstallId() {
|
|
|
111
111
|
* 4. `hostname:platform:arch` — last resort, kept only so this never throws.
|
|
112
112
|
*
|
|
113
113
|
* Only step 4 is guessable by a third party; steps 2 and 3 are both per-host
|
|
114
|
-
* unique.
|
|
115
|
-
* abuse review can tell a genuine re-registration from a forged one.
|
|
114
|
+
* unique.
|
|
116
115
|
*
|
|
117
116
|
* @param {string} [overrideId] - test-only override for the raw machine identity.
|
|
118
117
|
*/
|
|
@@ -136,15 +135,9 @@ function machineIdentity(overrideId) {
|
|
|
136
135
|
};
|
|
137
136
|
}
|
|
138
137
|
|
|
139
|
-
/** Which identity class the fingerprint on THIS host is derived from. */
|
|
140
|
-
function machineIdentityKind() {
|
|
141
|
-
return machineIdentity().kind;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
138
|
module.exports = {
|
|
145
139
|
machineFingerprint,
|
|
146
140
|
machineIdentity,
|
|
147
|
-
machineIdentityKind,
|
|
148
141
|
readMachineId,
|
|
149
142
|
persistedInstallId,
|
|
150
143
|
};
|