sleev 0.0.11 → 0.0.13
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/README.md +19 -39
- package/dist/auth/browser.d.ts +12 -0
- package/dist/auth/browser.js +33 -24
- package/dist/auth/browser.js.map +1 -0
- package/dist/auth/firebase-tokens.d.ts +39 -0
- package/dist/auth/firebase-tokens.js +173 -0
- package/dist/auth/firebase-tokens.js.map +1 -0
- package/dist/auth/firebase.d.ts +17 -0
- package/dist/auth/firebase.js +55 -0
- package/dist/auth/firebase.js.map +1 -0
- package/dist/auth/login.d.ts +22 -0
- package/dist/auth/login.js +31 -28
- package/dist/auth/login.js.map +1 -0
- package/dist/auth/loopback.d.ts +19 -0
- package/dist/auth/loopback.js +114 -44
- package/dist/auth/loopback.js.map +1 -0
- package/dist/auth/schema.d.ts +26 -0
- package/dist/auth/schema.js +59 -17
- package/dist/auth/schema.js.map +1 -0
- package/dist/auth/token.d.ts +19 -0
- package/dist/auth/token.js +53 -0
- package/dist/auth/token.js.map +1 -0
- package/dist/auth/verify.d.ts +6 -0
- package/dist/auth/verify.js +22 -0
- package/dist/auth/verify.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +245 -59
- package/dist/cli.js.map +1 -0
- package/dist/config/paths.d.ts +12 -0
- package/dist/config/paths.js +34 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/store.d.ts +63 -0
- package/dist/config/store.js +270 -0
- package/dist/config/store.js.map +1 -0
- package/dist/control/local-installations.d.ts +13 -0
- package/dist/control/local-installations.js +37 -0
- package/dist/control/local-installations.js.map +1 -0
- package/dist/daemon/config.d.ts +10 -0
- package/dist/daemon/config.js +52 -0
- package/dist/daemon/config.js.map +1 -0
- package/dist/daemon/controller.d.ts +29 -0
- package/dist/daemon/controller.js +34 -0
- package/dist/daemon/controller.js.map +1 -0
- package/dist/daemon/health.d.ts +8 -0
- package/dist/daemon/health.js +47 -0
- package/dist/daemon/health.js.map +1 -0
- package/dist/daemon/start.d.ts +5 -0
- package/dist/daemon/start.js +24 -0
- package/dist/daemon/start.js.map +1 -0
- package/dist/daemon/systemd.d.ts +35 -0
- package/dist/daemon/systemd.js +181 -0
- package/dist/daemon/systemd.js.map +1 -0
- package/dist/gateway/acquire.d.ts +14 -0
- package/dist/gateway/acquire.js +112 -0
- package/dist/gateway/acquire.js.map +1 -0
- package/dist/gateway/manifest.d.ts +26 -0
- package/dist/gateway/manifest.js +98 -0
- package/dist/gateway/manifest.js.map +1 -0
- package/dist/gateway/platform.d.ts +5 -0
- package/dist/gateway/platform.js +27 -0
- package/dist/gateway/platform.js.map +1 -0
- package/dist/harness/claude.d.ts +8 -0
- package/dist/{apps → harness}/claude.js +28 -28
- package/dist/harness/claude.js.map +1 -0
- package/dist/harness/codex.d.ts +10 -0
- package/dist/harness/codex.js +213 -0
- package/dist/harness/codex.js.map +1 -0
- package/dist/harness/index.d.ts +13 -0
- package/dist/harness/index.js +63 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/opencode-config.d.ts +8 -0
- package/dist/{apps → harness}/opencode-config.js +116 -83
- package/dist/harness/opencode-config.js.map +1 -0
- package/dist/harness/opencode.d.ts +14 -0
- package/dist/harness/opencode.js +50 -0
- package/dist/harness/opencode.js.map +1 -0
- package/dist/harness/providers.d.ts +8 -0
- package/dist/harness/providers.js +30 -0
- package/dist/harness/providers.js.map +1 -0
- package/dist/harness/types.d.ts +14 -0
- package/dist/harness/types.js +2 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/product.d.ts +12 -0
- package/dist/product.js +53 -10
- package/dist/product.js.map +1 -0
- package/dist/tui/clipboard.d.ts +1 -0
- package/dist/tui/clipboard.js +48 -0
- package/dist/tui/clipboard.js.map +1 -0
- package/dist/tui/openTuiApp.d.ts +1 -0
- package/dist/tui/openTuiApp.js +1436 -0
- package/dist/tui/openTuiApp.js.map +1 -0
- package/dist/tui/pages/flow-screen.d.ts +50 -0
- package/dist/tui/pages/flow-screen.js +435 -0
- package/dist/tui/pages/flow-screen.js.map +1 -0
- package/dist/tui/pages/footer.d.ts +7 -0
- package/dist/tui/pages/footer.js +14 -0
- package/dist/tui/pages/footer.js.map +1 -0
- package/dist/tui/pages/home-screen.d.ts +19 -0
- package/dist/tui/pages/home-screen.js +89 -0
- package/dist/tui/pages/home-screen.js.map +1 -0
- package/dist/tui/pages/index.d.ts +17 -0
- package/dist/tui/pages/index.js +11 -0
- package/dist/tui/pages/index.js.map +1 -0
- package/dist/tui/pages/local-setup-screen.d.ts +23 -0
- package/dist/tui/pages/local-setup-screen.js +134 -0
- package/dist/tui/pages/local-setup-screen.js.map +1 -0
- package/dist/tui/pages/location-card.d.ts +19 -0
- package/dist/tui/pages/location-card.js +116 -0
- package/dist/tui/pages/location-card.js.map +1 -0
- package/dist/tui/pages/menu-screen.d.ts +24 -0
- package/dist/tui/pages/menu-screen.js +117 -0
- package/dist/tui/pages/menu-screen.js.map +1 -0
- package/dist/tui/pages/session-grid.d.ts +23 -0
- package/dist/tui/pages/session-grid.js +552 -0
- package/dist/tui/pages/session-grid.js.map +1 -0
- package/dist/tui/pages/setup-screen.d.ts +15 -0
- package/dist/tui/pages/setup-screen.js +80 -0
- package/dist/tui/pages/setup-screen.js.map +1 -0
- package/dist/tui/pages/terminal-log.d.ts +14 -0
- package/dist/tui/pages/terminal-log.js +104 -0
- package/dist/tui/pages/terminal-log.js.map +1 -0
- package/dist/tui/pages/welcome-screen.d.ts +16 -0
- package/dist/tui/pages/welcome-screen.js +80 -0
- package/dist/tui/pages/welcome-screen.js.map +1 -0
- package/dist/tui/saved-tokens.d.ts +10 -0
- package/dist/tui/saved-tokens.js +104 -0
- package/dist/tui/saved-tokens.js.map +1 -0
- package/dist/tui/theme.d.ts +25 -0
- package/dist/tui/theme.js +27 -0
- package/dist/tui/theme.js.map +1 -0
- package/package.json +55 -38
- package/dist/apps/codex.js +0 -184
- package/dist/apps/opencode.js +0 -158
- package/dist/apps.js +0 -148
- package/dist/auth/command.js +0 -109
- package/dist/auth/index.js +0 -2
- package/dist/auth/validation.js +0 -27
- package/dist/credentials/index.js +0 -3
- package/dist/credentials/schema.js +0 -63
- package/dist/credentials/store.js +0 -52
- package/dist/harnesses.js +0 -66
- package/dist/index.js +0 -3
- package/dist/providers.js +0 -30
- package/dist/terminal.js +0 -55
package/dist/auth/loopback.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { parseHandoff } from './schema.js';
|
|
1
|
+
import { createServer, } from "node:http";
|
|
2
|
+
import { parseFirebaseHandoff, parseHandoff, parseTokenHandoff, } from "./schema.js";
|
|
4
3
|
const MAX_BODY_BYTES = 16 * 1024;
|
|
5
4
|
export async function startLoopback(options) {
|
|
5
|
+
return start(options, {
|
|
6
|
+
parse: parseHandoff,
|
|
7
|
+
verify: (payload) => accountMismatch(options.expectedAccount, payload),
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export async function startTokenLoopback(options) {
|
|
11
|
+
return start(options, { parse: parseTokenHandoff });
|
|
12
|
+
}
|
|
13
|
+
export async function startFirebaseLoopback(options) {
|
|
14
|
+
return start(options, { parse: parseFirebaseHandoff });
|
|
15
|
+
}
|
|
16
|
+
async function start(options, runtime) {
|
|
6
17
|
let settled = false;
|
|
7
18
|
let finish = () => undefined;
|
|
8
19
|
let fail = () => undefined;
|
|
@@ -10,69 +21,125 @@ export async function startLoopback(options) {
|
|
|
10
21
|
finish = resolve;
|
|
11
22
|
fail = reject;
|
|
12
23
|
});
|
|
13
|
-
const server = createServer(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
const server = createServer((req, res) => {
|
|
25
|
+
void (async () => {
|
|
26
|
+
try {
|
|
27
|
+
await handleRequest(req, res, options, runtime, (payload) => {
|
|
28
|
+
if (settled)
|
|
29
|
+
return;
|
|
30
|
+
settled = true;
|
|
31
|
+
finish(payload);
|
|
32
|
+
}, (err) => {
|
|
33
|
+
if (settled)
|
|
34
|
+
return;
|
|
35
|
+
settled = true;
|
|
36
|
+
fail(err);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
sendJson(res, 400, {
|
|
41
|
+
error: err instanceof Error
|
|
42
|
+
? err.message
|
|
43
|
+
: "Invalid request.",
|
|
44
|
+
}, options.webOrigin);
|
|
45
|
+
}
|
|
46
|
+
})();
|
|
30
47
|
});
|
|
31
48
|
await listen(server);
|
|
32
49
|
const address = server.address();
|
|
33
|
-
if (!address || typeof address ===
|
|
50
|
+
if (!address || typeof address === "string") {
|
|
34
51
|
await closeServer(server);
|
|
35
|
-
throw new Error(
|
|
52
|
+
throw new Error("Could not bind local login callback server.");
|
|
36
53
|
}
|
|
37
54
|
const timeout = setTimeout(() => {
|
|
38
55
|
if (settled)
|
|
39
56
|
return;
|
|
40
57
|
settled = true;
|
|
41
|
-
fail(new Error(
|
|
58
|
+
fail(new Error("Timed out waiting for browser login."));
|
|
42
59
|
void closeServer(server);
|
|
43
60
|
}, options.timeoutMs);
|
|
44
|
-
|
|
61
|
+
const abort = () => {
|
|
62
|
+
if (settled)
|
|
63
|
+
return;
|
|
64
|
+
settled = true;
|
|
65
|
+
fail(new Error("Sign in cancelled."));
|
|
66
|
+
void closeServer(server);
|
|
67
|
+
};
|
|
68
|
+
if (options.signal?.aborted) {
|
|
69
|
+
abort();
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
73
|
+
}
|
|
74
|
+
wait.finally(() => {
|
|
75
|
+
clearTimeout(timeout);
|
|
76
|
+
options.signal?.removeEventListener("abort", abort);
|
|
77
|
+
}).catch(() => undefined);
|
|
45
78
|
return {
|
|
46
79
|
callback: `http://127.0.0.1:${address.port}/callback`,
|
|
47
80
|
wait,
|
|
48
81
|
close: () => closeServer(server),
|
|
49
82
|
};
|
|
50
83
|
}
|
|
51
|
-
async function handleRequest(req, res, options, accept, reject) {
|
|
52
|
-
if (req.method ===
|
|
84
|
+
async function handleRequest(req, res, options, runtime, accept, reject) {
|
|
85
|
+
if (req.method === "OPTIONS") {
|
|
53
86
|
handleOptions(req, res, options.webOrigin);
|
|
54
87
|
return;
|
|
55
88
|
}
|
|
56
|
-
if (req.method !==
|
|
57
|
-
sendJson(res, 404, { error:
|
|
89
|
+
if (req.method !== "POST" || req.url !== "/callback") {
|
|
90
|
+
sendJson(res, 404, { error: "Not found." }, options.webOrigin);
|
|
58
91
|
return;
|
|
59
92
|
}
|
|
60
93
|
if (!hasAllowedOrigin(req, options.webOrigin)) {
|
|
61
|
-
sendJson(res, 403, { error:
|
|
94
|
+
sendJson(res, 403, { error: "Origin is not allowed." }, options.webOrigin);
|
|
62
95
|
return;
|
|
63
96
|
}
|
|
64
97
|
const body = await readBody(req);
|
|
65
|
-
const payload =
|
|
66
|
-
if (payload
|
|
67
|
-
sendJson(res, 403, { error:
|
|
98
|
+
const payload = runtime.parse(JSON.parse(body));
|
|
99
|
+
if (stateOf(payload) !== options.state) {
|
|
100
|
+
sendJson(res, 403, { error: "Login state did not match." }, options.webOrigin);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const mismatch = runtime.verify?.(payload) ?? null;
|
|
104
|
+
if (mismatch) {
|
|
105
|
+
reject(new Error(mismatch));
|
|
106
|
+
sendJson(res, 403, { error: mismatch }, options.webOrigin);
|
|
68
107
|
return;
|
|
69
108
|
}
|
|
70
109
|
accept(payload);
|
|
71
110
|
sendJson(res, 200, { ok: true }, options.webOrigin);
|
|
72
111
|
}
|
|
112
|
+
function stateOf(payload) {
|
|
113
|
+
if (typeof payload !== "object" || payload === null)
|
|
114
|
+
return undefined;
|
|
115
|
+
const state = payload.state;
|
|
116
|
+
if (typeof state !== "string")
|
|
117
|
+
return undefined;
|
|
118
|
+
return state;
|
|
119
|
+
}
|
|
120
|
+
function accountMismatch(expected, payload) {
|
|
121
|
+
if (!expected)
|
|
122
|
+
return null;
|
|
123
|
+
if (expected.accountId) {
|
|
124
|
+
if (!payload.accountId)
|
|
125
|
+
return "Could not verify browser account. Run `sleeved auth login` again.";
|
|
126
|
+
if (expected.accountId !== payload.accountId) {
|
|
127
|
+
return "Browser is signed into a different Sleev account. Run `sleeved auth login` to switch accounts.";
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
if (expected.email) {
|
|
132
|
+
if (!payload.email)
|
|
133
|
+
return "Could not verify browser email. Run `sleeved auth login` again.";
|
|
134
|
+
if (expected.email !== payload.email) {
|
|
135
|
+
return "Browser is signed into a different Sleev email. Run `sleeved auth login` to switch accounts.";
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
73
140
|
function handleOptions(req, res, origin) {
|
|
74
141
|
if (!hasAllowedOrigin(req, origin)) {
|
|
75
|
-
sendJson(res, 403, { error:
|
|
142
|
+
sendJson(res, 403, { error: "Origin is not allowed." }, origin);
|
|
76
143
|
return;
|
|
77
144
|
}
|
|
78
145
|
writeCors(res, origin);
|
|
@@ -87,36 +154,38 @@ function readBody(req) {
|
|
|
87
154
|
return new Promise((resolve, reject) => {
|
|
88
155
|
const chunks = [];
|
|
89
156
|
let size = 0;
|
|
90
|
-
req.on(
|
|
157
|
+
req.on("data", (chunk) => {
|
|
91
158
|
size += chunk.length;
|
|
92
159
|
if (size > MAX_BODY_BYTES) {
|
|
93
|
-
reject(new Error(
|
|
160
|
+
reject(new Error("Login callback body is too large."));
|
|
94
161
|
req.destroy();
|
|
95
162
|
return;
|
|
96
163
|
}
|
|
97
164
|
chunks.push(chunk);
|
|
98
165
|
});
|
|
99
|
-
req.once(
|
|
100
|
-
req.once(
|
|
166
|
+
req.once("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
167
|
+
req.once("error", () => reject(new Error("Could not read login callback.")));
|
|
101
168
|
});
|
|
102
169
|
}
|
|
103
170
|
function sendJson(res, status, body, origin) {
|
|
104
171
|
if (res.writableEnded)
|
|
105
172
|
return;
|
|
106
173
|
writeCors(res, origin);
|
|
107
|
-
res.writeHead(status, {
|
|
174
|
+
res.writeHead(status, {
|
|
175
|
+
"content-type": "application/json; charset=utf-8",
|
|
176
|
+
});
|
|
108
177
|
res.end(JSON.stringify(body));
|
|
109
178
|
}
|
|
110
179
|
function writeCors(res, origin) {
|
|
111
|
-
res.setHeader(
|
|
112
|
-
res.setHeader(
|
|
113
|
-
res.setHeader(
|
|
180
|
+
res.setHeader("access-control-allow-origin", origin);
|
|
181
|
+
res.setHeader("access-control-allow-methods", "POST, OPTIONS");
|
|
182
|
+
res.setHeader("access-control-allow-headers", "content-type");
|
|
114
183
|
}
|
|
115
184
|
function listen(server) {
|
|
116
185
|
return new Promise((resolve, reject) => {
|
|
117
|
-
server.once(
|
|
118
|
-
server.listen(0,
|
|
119
|
-
server.removeListener(
|
|
186
|
+
server.once("error", reject);
|
|
187
|
+
server.listen(0, "127.0.0.1", () => {
|
|
188
|
+
server.removeListener("error", reject);
|
|
120
189
|
resolve();
|
|
121
190
|
});
|
|
122
191
|
});
|
|
@@ -132,3 +201,4 @@ function closeServer(server) {
|
|
|
132
201
|
});
|
|
133
202
|
});
|
|
134
203
|
}
|
|
204
|
+
//# sourceMappingURL=loopback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopback.js","sourceRoot":"","sources":["../../src/auth/loopback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type LoginHandoff = {
|
|
2
|
+
state: string;
|
|
3
|
+
label: string | null;
|
|
4
|
+
accountId: string;
|
|
5
|
+
email: string | null;
|
|
6
|
+
};
|
|
7
|
+
export type TokenHandoff = {
|
|
8
|
+
state: string;
|
|
9
|
+
token: string;
|
|
10
|
+
label: string | null;
|
|
11
|
+
proxyUrl: string;
|
|
12
|
+
};
|
|
13
|
+
export type FirebaseHandoff = {
|
|
14
|
+
state: string;
|
|
15
|
+
refreshToken: string;
|
|
16
|
+
accountId: string;
|
|
17
|
+
email: string | null;
|
|
18
|
+
label: string | null;
|
|
19
|
+
};
|
|
20
|
+
export type AccountIdentity = {
|
|
21
|
+
accountId: string | null;
|
|
22
|
+
email: string | null;
|
|
23
|
+
};
|
|
24
|
+
export declare function parseHandoff(input: unknown): LoginHandoff;
|
|
25
|
+
export declare function parseTokenHandoff(input: unknown): TokenHandoff;
|
|
26
|
+
export declare function parseFirebaseHandoff(input: unknown): FirebaseHandoff;
|
package/dist/auth/schema.js
CHANGED
|
@@ -1,35 +1,76 @@
|
|
|
1
|
-
// Validation for the browser-to-CLI auth handoff payload.
|
|
2
1
|
export function parseHandoff(input) {
|
|
3
|
-
if (!isRecord(input))
|
|
4
|
-
throw new Error(
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const label = nullableStringField(input,
|
|
8
|
-
const
|
|
2
|
+
if (!isRecord(input)) {
|
|
3
|
+
throw new Error("Login callback payload must be an object.");
|
|
4
|
+
}
|
|
5
|
+
const state = stringField(input, "state");
|
|
6
|
+
const label = nullableStringField(input, "label");
|
|
7
|
+
const accountId = stringField(input, "accountId");
|
|
8
|
+
const email = nullableStringField(input, "email");
|
|
9
|
+
if (!state)
|
|
10
|
+
throw new Error("Login callback state is missing.");
|
|
11
|
+
if (!accountId)
|
|
12
|
+
throw new Error("Login callback account ID is missing.");
|
|
13
|
+
return {
|
|
14
|
+
state,
|
|
15
|
+
label,
|
|
16
|
+
accountId,
|
|
17
|
+
email,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function parseTokenHandoff(input) {
|
|
21
|
+
if (!isRecord(input)) {
|
|
22
|
+
throw new Error("Token callback payload must be an object.");
|
|
23
|
+
}
|
|
24
|
+
const state = stringField(input, "state");
|
|
25
|
+
const token = stringField(input, "token");
|
|
26
|
+
const label = nullableStringField(input, "label");
|
|
27
|
+
const proxyUrl = stringField(input, "proxyUrl");
|
|
28
|
+
if (!state)
|
|
29
|
+
throw new Error("Token callback state is missing.");
|
|
30
|
+
if (!token.startsWith("slv_live_"))
|
|
31
|
+
throw new Error("Token callback token is invalid.");
|
|
32
|
+
validateUrl(proxyUrl, "Token callback proxy URL");
|
|
33
|
+
return {
|
|
34
|
+
state,
|
|
35
|
+
token,
|
|
36
|
+
label,
|
|
37
|
+
proxyUrl,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function parseFirebaseHandoff(input) {
|
|
41
|
+
if (!isRecord(input)) {
|
|
42
|
+
throw new Error("Firebase callback payload must be an object.");
|
|
43
|
+
}
|
|
44
|
+
const state = stringField(input, "state");
|
|
45
|
+
const refreshToken = stringField(input, "refreshToken");
|
|
46
|
+
const accountId = stringField(input, "accountId");
|
|
47
|
+
const email = nullableStringField(input, "email");
|
|
48
|
+
const label = nullableStringField(input, "label");
|
|
9
49
|
if (!state)
|
|
10
|
-
throw new Error(
|
|
11
|
-
if (!
|
|
12
|
-
throw new Error(
|
|
13
|
-
|
|
14
|
-
|
|
50
|
+
throw new Error("Firebase callback state is missing.");
|
|
51
|
+
if (!refreshToken)
|
|
52
|
+
throw new Error("Firebase callback refresh token is missing.");
|
|
53
|
+
if (!accountId)
|
|
54
|
+
throw new Error("Firebase callback account ID is missing.");
|
|
55
|
+
return { state, refreshToken, accountId, email, label };
|
|
15
56
|
}
|
|
16
57
|
function stringField(input, key) {
|
|
17
58
|
const value = input[key];
|
|
18
|
-
if (typeof value !==
|
|
59
|
+
if (typeof value !== "string")
|
|
19
60
|
throw new Error(`${key} must be a string.`);
|
|
20
61
|
return value;
|
|
21
62
|
}
|
|
22
63
|
function nullableStringField(input, key) {
|
|
23
64
|
const value = input[key];
|
|
24
|
-
if (value === null || typeof value ===
|
|
65
|
+
if (value === null || typeof value === "undefined")
|
|
25
66
|
return null;
|
|
26
|
-
if (typeof value !==
|
|
67
|
+
if (typeof value !== "string")
|
|
27
68
|
throw new Error(`${key} must be a string or null.`);
|
|
28
69
|
return value;
|
|
29
70
|
}
|
|
30
71
|
function validateUrl(raw, name) {
|
|
31
72
|
const url = parseUrl(raw, name);
|
|
32
|
-
if (url.protocol !==
|
|
73
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
33
74
|
throw new Error(`${name} must use http or https.`);
|
|
34
75
|
}
|
|
35
76
|
}
|
|
@@ -42,5 +83,6 @@ function parseUrl(raw, name) {
|
|
|
42
83
|
}
|
|
43
84
|
}
|
|
44
85
|
function isRecord(input) {
|
|
45
|
-
return typeof input ===
|
|
86
|
+
return typeof input === "object" && input !== null && !Array.isArray(input);
|
|
46
87
|
}
|
|
88
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/auth/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Writable } from "node:stream";
|
|
2
|
+
export type TokenResult = {
|
|
3
|
+
id: string;
|
|
4
|
+
token: string;
|
|
5
|
+
label: string | null;
|
|
6
|
+
proxyUrl: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
};
|
|
9
|
+
export type TokenOptions = {
|
|
10
|
+
webOrigin?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
output?: Writable;
|
|
13
|
+
opener?: (url: string) => Promise<boolean>;
|
|
14
|
+
onUrl?: (url: string) => void;
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
now?: () => Date;
|
|
18
|
+
};
|
|
19
|
+
export declare function createToken(options?: TokenOptions): Promise<TokenResult>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Creates live Sleev tokens through the browser callback used by the legacy CLI.
|
|
2
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
|
+
import { hostname } from "node:os";
|
|
4
|
+
import { webOrigin as defaultWebOrigin } from "../product.js";
|
|
5
|
+
import { openBrowser } from "./browser.js";
|
|
6
|
+
import { startTokenLoopback } from "./loopback.js";
|
|
7
|
+
const TOKEN_TIMEOUT_MS = 10 * 60 * 1000;
|
|
8
|
+
export async function createToken(options = {}) {
|
|
9
|
+
const output = options.output ?? process.stdout;
|
|
10
|
+
const origin = options.webOrigin ?? defaultWebOrigin();
|
|
11
|
+
const opener = options.opener ?? openBrowser;
|
|
12
|
+
const state = randomBytes(32).toString("base64url");
|
|
13
|
+
const loopback = await startTokenLoopback({
|
|
14
|
+
state,
|
|
15
|
+
webOrigin: origin,
|
|
16
|
+
timeoutMs: options.timeoutMs ?? TOKEN_TIMEOUT_MS,
|
|
17
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
18
|
+
});
|
|
19
|
+
const url = tokenUrl(origin, state, loopback.callback, options.label);
|
|
20
|
+
options.onUrl?.(url);
|
|
21
|
+
output.write(`Opening ${origin} to create a Sleev token.\n`);
|
|
22
|
+
try {
|
|
23
|
+
const opened = await opener(url);
|
|
24
|
+
if (!opened) {
|
|
25
|
+
output.write("Could not open a browser automatically. Open this URL instead:\n");
|
|
26
|
+
output.write(`${url}\n`);
|
|
27
|
+
}
|
|
28
|
+
output.write("Waiting for browser token confirmation...\n");
|
|
29
|
+
const payload = await loopback.wait;
|
|
30
|
+
output.write("Browser token confirmed.\n");
|
|
31
|
+
return {
|
|
32
|
+
id: randomUUID(),
|
|
33
|
+
token: payload.token,
|
|
34
|
+
label: payload.label,
|
|
35
|
+
proxyUrl: payload.proxyUrl,
|
|
36
|
+
createdAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
await loopback.close();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function tokenUrl(origin, state, callback, label) {
|
|
44
|
+
const url = new URL("/cli/login", origin);
|
|
45
|
+
url.searchParams.set("mode", "signup");
|
|
46
|
+
url.searchParams.set("state", state);
|
|
47
|
+
url.searchParams.set("callback", callback);
|
|
48
|
+
url.searchParams.set("device", hostname().slice(0, 80));
|
|
49
|
+
if (label)
|
|
50
|
+
url.searchParams.set("label", label);
|
|
51
|
+
return url.toString();
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Proves the Firebase chain end to end: stored refresh token -> minted ID
|
|
2
|
+
// token -> authenticated control-server call.
|
|
3
|
+
import { apiOrigin } from "../product.js";
|
|
4
|
+
import { FirebaseTokenManager } from "./firebase-tokens.js";
|
|
5
|
+
export async function verifyFirebaseAuth(manager = new FirebaseTokenManager(), fetchImpl = fetch) {
|
|
6
|
+
const idToken = await manager.getIdToken();
|
|
7
|
+
const response = await fetchImpl(`${apiOrigin()}/api/users/me`, {
|
|
8
|
+
headers: { authorization: `Bearer ${idToken}` },
|
|
9
|
+
});
|
|
10
|
+
if (!response.ok) {
|
|
11
|
+
throw new Error(`Control rejected the Firebase token (HTTP ${response.status}).`);
|
|
12
|
+
}
|
|
13
|
+
const body = (await response.json().catch(() => null));
|
|
14
|
+
if (!body || typeof body.id !== "string") {
|
|
15
|
+
throw new Error("Control returned an unexpected /api/users/me body.");
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
accountId: body.id,
|
|
19
|
+
email: typeof body.email === "string" ? body.email : null,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/auth/verify.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,8CAA8C;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAO5D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,OAAO,GAAG,IAAI,oBAAoB,EAAE,EACpC,YAA0B,KAAK;IAE/B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,SAAS,EAAE,eAAe,EAAE;QAC5D,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,OAAO,EAAE,EAAE;KAClD,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACX,6CAA6C,QAAQ,CAAC,MAAM,IAAI,CACnE,CAAC;IACN,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAG7C,CAAC;IAET,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO;QACH,SAAS,EAAE,IAAI,CAAC,EAAE;QAClB,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;KAC5D,CAAC;AACN,CAAC"}
|