@volter/browser-toolbelt 0.1.5 → 0.1.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/README.md +15 -0
- package/dist/browser-git-http.d.ts +28 -2
- package/dist/browser-git-http.d.ts.map +1 -1
- package/dist/browser-git-http.js +5 -1
- package/dist/browser-git-http.js.map +1 -1
- package/dist/browser-git-remote-https.d.ts +34 -0
- package/dist/browser-git-remote-https.d.ts.map +1 -0
- package/dist/browser-git-remote-https.js +619 -0
- package/dist/browser-git-remote-https.js.map +1 -0
- package/dist/browser-interactive-shell.d.ts +11 -0
- package/dist/browser-interactive-shell.d.ts.map +1 -0
- package/dist/browser-interactive-shell.js +211 -0
- package/dist/browser-interactive-shell.js.map +1 -0
- package/dist/browser-rm.d.ts +3 -0
- package/dist/browser-rm.d.ts.map +1 -0
- package/dist/browser-rm.js +61 -0
- package/dist/browser-rm.js.map +1 -0
- package/dist/browser-shell-filesystem.d.ts +1 -1
- package/dist/browser-shell-filesystem.d.ts.map +1 -1
- package/dist/browser-shell-filesystem.js +25 -7
- package/dist/browser-shell-filesystem.js.map +1 -1
- package/dist/browser-shell.d.ts +52 -3
- package/dist/browser-shell.d.ts.map +1 -1
- package/dist/browser-shell.js +387 -58
- package/dist/browser-shell.js.map +1 -1
- package/dist/github-device-auth.d.ts +23 -2
- package/dist/github-device-auth.d.ts.map +1 -1
- package/dist/github-device-auth.js +132 -17
- package/dist/github-device-auth.js.map +1 -1
- package/dist/github-web-sign-in.d.ts +24 -0
- package/dist/github-web-sign-in.d.ts.map +1 -0
- package/dist/github-web-sign-in.js +93 -0
- package/dist/github-web-sign-in.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +8 -3
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +37 -5
- package/dist/install.js.map +1 -1
- package/dist/shell-buffer-global.d.ts +2 -0
- package/dist/shell-buffer-global.d.ts.map +1 -0
- package/dist/shell-buffer-global.js +10 -0
- package/dist/shell-buffer-global.js.map +1 -0
- package/dist/volter-sign-in.d.ts +62 -0
- package/dist/volter-sign-in.d.ts.map +1 -0
- package/dist/volter-sign-in.js +255 -0
- package/dist/volter-sign-in.js.map +1 -0
- package/package.json +22 -10
- package/dist/browser-git-filesystem.d.ts +0 -18
- package/dist/browser-git-filesystem.d.ts.map +0 -1
- package/dist/browser-git-filesystem.js +0 -84
- package/dist/browser-git-filesystem.js.map +0 -1
- package/dist/browser-git.d.ts +0 -38
- package/dist/browser-git.d.ts.map +0 -1
- package/dist/browser-git.js +0 -514
- package/dist/browser-git.js.map +0 -1
package/dist/install.js
CHANGED
|
@@ -1,19 +1,51 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BrowserGitRemoteHttps } from "./browser-git-remote-https.js";
|
|
2
|
+
import { BrowserGitHttp } from "./browser-git-http.js";
|
|
2
3
|
import { BrowserShareCommand } from "./browser-share-command.js";
|
|
3
4
|
import { BrowserShell } from "./browser-shell.js";
|
|
5
|
+
import { interactiveShell } from "./browser-interactive-shell.js";
|
|
4
6
|
/** Installs the optional development command set on an existing runtime. */
|
|
5
7
|
export function installBrowserToolbelt(runtime, options = {}) {
|
|
6
8
|
const shell = new BrowserShell(runtime.filesystem);
|
|
9
|
+
shell.setProcessTable(() => runtime.processes());
|
|
7
10
|
runtime.processHost.registerShell(shell);
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
// `git` itself is a pack, the program Git publishes; what belongs to the
|
|
12
|
+
// page is the helper Git invokes to reach a remote. It is registered here
|
|
13
|
+
// and seeded on PATH, because Git's `execvp` searches PATH for it.
|
|
14
|
+
const remote = new BrowserGitRemoteHttps({
|
|
15
|
+
http: options.gitHttp ? { request: (request) => {
|
|
16
|
+
runtime.policy.assertWorldEgress("git", request.url);
|
|
17
|
+
return options.gitHttp.request(request);
|
|
18
|
+
} } : new BrowserGitHttp({ authorize: (url) => runtime.policy.assertWorldEgress("git", url) }).client,
|
|
19
|
+
spawn: runtime.processHost,
|
|
20
|
+
});
|
|
21
|
+
runtime.registerProgram("git-remote-https", remote.run);
|
|
22
|
+
const bin = "/opt/programs/bin";
|
|
23
|
+
const marker = `${bin}/git-remote-https`;
|
|
24
|
+
runtime.filesystem.mkdirSync(bin, { recursive: true });
|
|
25
|
+
if (!runtime.filesystem.existsSync(marker)) {
|
|
26
|
+
runtime.filesystem.writeFileSync(marker, "#!/bin/sh\n# git-remote-https: runtime-registered program\n");
|
|
27
|
+
runtime.filesystem.chmodSync?.(marker, 0o755);
|
|
28
|
+
}
|
|
11
29
|
const share = options.share === false ? undefined : new BrowserShareCommand(runtime);
|
|
12
30
|
if (share)
|
|
13
31
|
runtime.registerProgram("share", share.run);
|
|
32
|
+
// `sh` and `bash` as programs: an exec of either with a TTY is the
|
|
33
|
+
// interactive shell a terminal attaches to (ADR-0026 §2); each line runs
|
|
34
|
+
// the way the process host runs any command.
|
|
35
|
+
const shellProgram = interactiveShell((command, runOptions) => runtime.spawn(command, runOptions), (path) => runtime.filesystem.readFile(path, "utf8").catch(() => undefined));
|
|
36
|
+
runtime.filesystem.mkdirSync("/bin", { recursive: true });
|
|
37
|
+
for (const name of ["sh", "bash"]) {
|
|
38
|
+
runtime.registerProgram(name, shellProgram);
|
|
39
|
+
// Registered executables must also be discoverable by stat/access,
|
|
40
|
+
// before a caller chooses to spawn them. Dispatch remains the host's.
|
|
41
|
+
const executable = `/bin/${name}`;
|
|
42
|
+
if (!runtime.filesystem.existsSync(executable)) {
|
|
43
|
+
runtime.filesystem.writeFileSync(executable, `#!/bin/sh\n# ${name}: runtime-registered program\n`);
|
|
44
|
+
runtime.filesystem.chmodSync?.(executable, 0o755);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
14
47
|
return {
|
|
15
48
|
shell,
|
|
16
|
-
...(git ? { git } : {}),
|
|
17
49
|
...(share ? { share } : {}),
|
|
18
50
|
dispose: () => share?.close(),
|
|
19
51
|
};
|
package/dist/install.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-buffer-global.d.ts","sourceRoot":"","sources":["../src/shell-buffer-global.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// just-bash, the page's shell, writes `Buffer` as a Node program would in a
|
|
2
|
+
// few commands: gzip's read of a gzipped file and curl's basic auth take it
|
|
3
|
+
// unguarded. A page whose engine runs in a worker has no such global
|
|
4
|
+
// (ADR-0042), so the shell's host gives the realm the `buffer` package's,
|
|
5
|
+
// Node's API without Node's library, where it has none.
|
|
6
|
+
import { Buffer } from "buffer";
|
|
7
|
+
if (!Object.getOwnPropertyDescriptor(globalThis, "Buffer")) {
|
|
8
|
+
Object.defineProperty(globalThis, "Buffer", { configurable: true, enumerable: false, writable: true, value: Buffer });
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=shell-buffer-global.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-buffer-global.js","sourceRoot":"","sources":["../src/shell-buffer-global.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,4EAA4E;AAC5E,qEAAqE;AACrE,0EAA0E;AAC1E,wDAAwD;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;IAC3D,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;AACxH,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { BrowserByteVault } from "@volter/browser-runtime/browser-byte-vault.js";
|
|
2
|
+
/** What a gateway's `/api/ready` says about identity: absent, this deployment signs no one in. */
|
|
3
|
+
export interface VolterIdentityCapability {
|
|
4
|
+
issuer: string;
|
|
5
|
+
clientId: string;
|
|
6
|
+
}
|
|
7
|
+
/** A signed-in person, as this tab holds them. */
|
|
8
|
+
export interface VolterSession {
|
|
9
|
+
accessToken: string;
|
|
10
|
+
refreshToken?: string;
|
|
11
|
+
/** Epoch milliseconds. */
|
|
12
|
+
expiresAt: number;
|
|
13
|
+
subject: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
email?: string;
|
|
16
|
+
/** The login of the GitHub account linked to this identity, when one is. */
|
|
17
|
+
githubLogin?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Whether the gateway at `gateway` signs people in, and with which issuer. */
|
|
20
|
+
export declare function volterIdentityOf(gateway?: string): Promise<VolterIdentityCapability | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* Opens Volter's sign-in and resolves with the session it grants. Asking
|
|
23
|
+
* again while a request is open re-shows the same window instead of racing it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function signInWithVolter(identity: VolterIdentityCapability, options?: {
|
|
26
|
+
gateway?: string;
|
|
27
|
+
}): Promise<VolterSession>;
|
|
28
|
+
/** Shows the sign-in window again when one is waiting for an answer; false when nothing is. */
|
|
29
|
+
export declare function reopenVolterSignIn(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The window the gateway sent back to this loopback page with the answer in
|
|
32
|
+
* its fragment: it tells this origin's waiting tab and closes. A page calls it
|
|
33
|
+
* first thing and stops when it answers true.
|
|
34
|
+
*/
|
|
35
|
+
export declare function completeVolterSignIn(): boolean;
|
|
36
|
+
/** Trades a refresh token at the gateway for a new session; the old refresh token is spent. */
|
|
37
|
+
export declare function refreshVolterSession(session: VolterSession, options?: {
|
|
38
|
+
gateway?: string;
|
|
39
|
+
}): Promise<VolterSession>;
|
|
40
|
+
/**
|
|
41
|
+
* Keeps the session outside the workspace and serializes refresh: a refresh
|
|
42
|
+
* token is single-use, so the vault marks a rotation before the old token
|
|
43
|
+
* leaves the tab, and a rotation that never finished is a sign-in to do again,
|
|
44
|
+
* never a refresh token to retry.
|
|
45
|
+
*/
|
|
46
|
+
export declare class VolterSessionVault {
|
|
47
|
+
private readonly vault;
|
|
48
|
+
private readonly options;
|
|
49
|
+
constructor(vault: BrowserByteVault, options?: {
|
|
50
|
+
gateway?: string;
|
|
51
|
+
lock?: <T>(operation: () => Promise<T>) => Promise<T>;
|
|
52
|
+
});
|
|
53
|
+
load(): Promise<VolterSession | undefined>;
|
|
54
|
+
/** The session to send now, renewed first when it is about to expire; undefined when there is none or it cannot be renewed. */
|
|
55
|
+
current(): Promise<VolterSession | undefined>;
|
|
56
|
+
save(session: VolterSession): Promise<void>;
|
|
57
|
+
clear(): Promise<void>;
|
|
58
|
+
private read;
|
|
59
|
+
private write;
|
|
60
|
+
private lock;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=volter-sign-in.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"volter-sign-in.d.ts","sourceRoot":"","sources":["../src/volter-sign-in.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AAoBtF,kGAAkG;AAClG,MAAM,WAAW,wBAAwB;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AAE9E,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD,+EAA+E;AAC/E,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,MAAwB,GAAG,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAKvH;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,wBAAwB,EAAE,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAqC/H;AAED,+FAA+F;AAC/F,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAa9C;AAED,+FAA+F;AAC/F,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAGvH;AAoDD;;;;;GAKG;AACH,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAoB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAjD,KAAK,EAAE,gBAAgB,EAAmB,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;KAAO;IAEhK,IAAI,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAQ1C,+HAA+H;IAC/H,OAAO,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAiB7C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAIR,IAAI;YAUJ,KAAK;YAOL,IAAI;CAKnB"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
// Signing in with Volter (ADR-0041): the identity service's sign-in page in a
|
|
2
|
+
// popup, code flow with PKCE, opened through the gateway so the page never
|
|
3
|
+
// reaches the issuer itself. The gateway is the registered client: its
|
|
4
|
+
// callback hands the code back to this tab over a BroadcastChannel of the
|
|
5
|
+
// gateway's origin (or in the fragment to a loopback page), and the tab trades
|
|
6
|
+
// code and verifier at the gateway, which adds the client secret. The tokens
|
|
7
|
+
// stay in this origin's vault; the access token's audience is the gateway.
|
|
8
|
+
const CHANNEL = "browser-substrate-volter-sign-in";
|
|
9
|
+
const AUTHORIZE = "/api/auth/volter/authorize";
|
|
10
|
+
const CALLBACK = "/api/auth/volter/callback";
|
|
11
|
+
const TOKEN = "/api/auth/volter/token";
|
|
12
|
+
const REFRESH = "/api/auth/volter/refresh";
|
|
13
|
+
const SCOPE = "openid profile email offline_access";
|
|
14
|
+
/** Refresh a little before the hour is up, so a request never carries a token that expires in flight. */
|
|
15
|
+
const REFRESH_MARGIN_MS = 5 * 60 * 1000;
|
|
16
|
+
const MAXIMUM_SESSION_BYTES = 16 * 1024;
|
|
17
|
+
let pending;
|
|
18
|
+
/** Whether the gateway at `gateway` signs people in, and with which issuer. */
|
|
19
|
+
export async function volterIdentityOf(gateway = location.origin) {
|
|
20
|
+
const response = await fetch(new URL("/api/ready", gateway), { credentials: "omit" });
|
|
21
|
+
const ready = await response.json().catch(() => ({}));
|
|
22
|
+
const identity = ready.capabilities?.identity;
|
|
23
|
+
return typeof identity?.issuer === "string" && typeof identity.clientId === "string" ? { issuer: identity.issuer, clientId: identity.clientId } : undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Opens Volter's sign-in and resolves with the session it grants. Asking
|
|
27
|
+
* again while a request is open re-shows the same window instead of racing it.
|
|
28
|
+
*/
|
|
29
|
+
export function signInWithVolter(identity, options = {}) {
|
|
30
|
+
if (pending) {
|
|
31
|
+
openWindow(pending.url);
|
|
32
|
+
return pending.done;
|
|
33
|
+
}
|
|
34
|
+
const gateway = new URL(options.gateway ?? location.origin).origin;
|
|
35
|
+
const here = `${location.origin}${location.pathname}`;
|
|
36
|
+
const state = gateway === location.origin ? crypto.randomUUID() : `${crypto.randomUUID()}.${base64url(new TextEncoder().encode(here))}`;
|
|
37
|
+
const verifier = base64url(crypto.getRandomValues(new Uint8Array(48)));
|
|
38
|
+
// The window opens now, while the click that asked still counts; it is sent on once the address is known.
|
|
39
|
+
const popup = openWindow("about:blank");
|
|
40
|
+
const channel = new BroadcastChannel(CHANNEL);
|
|
41
|
+
const done = (async () => {
|
|
42
|
+
// The gateway sends the window on to the issuer: this page reads nothing from it.
|
|
43
|
+
const challenge = await sha256(verifier);
|
|
44
|
+
const authorize = new URL(AUTHORIZE, gateway);
|
|
45
|
+
authorize.search = new URLSearchParams({
|
|
46
|
+
client_id: identity.clientId,
|
|
47
|
+
response_type: "code",
|
|
48
|
+
redirect_uri: new URL(CALLBACK, gateway).href,
|
|
49
|
+
scope: SCOPE,
|
|
50
|
+
state,
|
|
51
|
+
code_challenge: challenge,
|
|
52
|
+
code_challenge_method: "S256",
|
|
53
|
+
}).toString();
|
|
54
|
+
const answered = new Promise((resolve) => {
|
|
55
|
+
channel.onmessage = (event) => {
|
|
56
|
+
if (event.data?.state === state)
|
|
57
|
+
resolve(event.data);
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
pending.url = authorize.href;
|
|
61
|
+
popup.location.href = authorize.href;
|
|
62
|
+
const answer = await answered;
|
|
63
|
+
if (!answer.code)
|
|
64
|
+
throw new Error(answer.error ?? "Volter returned no code");
|
|
65
|
+
return trade(gateway, TOKEN, { code: answer.code, code_verifier: verifier });
|
|
66
|
+
})().finally(() => { channel.close(); pending = undefined; });
|
|
67
|
+
// A sign-in that failed before the window left this page closes it; one at Volter is the person's to close.
|
|
68
|
+
done.catch(() => { try {
|
|
69
|
+
if (popup.location.href === "about:blank")
|
|
70
|
+
popup.close();
|
|
71
|
+
}
|
|
72
|
+
catch { /* at Volter now */ } });
|
|
73
|
+
pending = { state, url: "", done };
|
|
74
|
+
return done;
|
|
75
|
+
}
|
|
76
|
+
/** Shows the sign-in window again when one is waiting for an answer; false when nothing is. */
|
|
77
|
+
export function reopenVolterSignIn() {
|
|
78
|
+
if (!pending?.url)
|
|
79
|
+
return false;
|
|
80
|
+
openWindow(pending.url);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The window the gateway sent back to this loopback page with the answer in
|
|
85
|
+
* its fragment: it tells this origin's waiting tab and closes. A page calls it
|
|
86
|
+
* first thing and stops when it answers true.
|
|
87
|
+
*/
|
|
88
|
+
export function completeVolterSignIn() {
|
|
89
|
+
const prefix = "#volter-sign-in=";
|
|
90
|
+
if (!location.hash.startsWith(prefix))
|
|
91
|
+
return false;
|
|
92
|
+
let outcome;
|
|
93
|
+
try {
|
|
94
|
+
outcome = JSON.parse(decodeURIComponent(location.hash.slice(prefix.length)));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
history.replaceState(null, "", `${location.pathname}${location.search}`);
|
|
100
|
+
const channel = new BroadcastChannel(CHANNEL);
|
|
101
|
+
channel.postMessage(outcome);
|
|
102
|
+
channel.close();
|
|
103
|
+
document.body.textContent = outcome.error ? `Sign-in did not complete: ${outcome.error}` : "Signed in. You can close this window.";
|
|
104
|
+
if (!outcome.error)
|
|
105
|
+
setTimeout(() => window.close(), 300);
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
/** Trades a refresh token at the gateway for a new session; the old refresh token is spent. */
|
|
109
|
+
export function refreshVolterSession(session, options = {}) {
|
|
110
|
+
if (!session.refreshToken)
|
|
111
|
+
return Promise.reject(new Error("The sign-in cannot be renewed; sign in again."));
|
|
112
|
+
return trade(new URL(options.gateway ?? location.origin).origin, REFRESH, { refresh_token: session.refreshToken });
|
|
113
|
+
}
|
|
114
|
+
async function trade(gateway, route, body) {
|
|
115
|
+
const response = await fetch(new URL(route, gateway), {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: { "Content-Type": "application/json" },
|
|
118
|
+
body: JSON.stringify(body),
|
|
119
|
+
credentials: "omit",
|
|
120
|
+
signal: AbortSignal.timeout(30_000),
|
|
121
|
+
});
|
|
122
|
+
const answer = await response.json().catch(() => ({}));
|
|
123
|
+
if (!response.ok || !answer.access_token)
|
|
124
|
+
throw new Error(answer.error?.message ?? `The gateway answered ${response.status}.`);
|
|
125
|
+
// Who the person is, for this tab's display; the gateway verifies the access token itself.
|
|
126
|
+
const claims = readClaims(answer.id_token ?? answer.access_token);
|
|
127
|
+
if (typeof claims.sub !== "string")
|
|
128
|
+
throw new Error("The sign-in named no one.");
|
|
129
|
+
const access = readClaims(answer.access_token);
|
|
130
|
+
const text = (name) => typeof claims[name] === "string" ? claims[name]
|
|
131
|
+
: typeof access[name] === "string" ? access[name] : undefined;
|
|
132
|
+
return {
|
|
133
|
+
accessToken: answer.access_token,
|
|
134
|
+
...(answer.refresh_token ? { refreshToken: answer.refresh_token } : {}),
|
|
135
|
+
expiresAt: Date.now() + (answer.expires_in ?? 3600) * 1000,
|
|
136
|
+
subject: claims.sub,
|
|
137
|
+
...(text("name") ? { name: text("name") } : {}),
|
|
138
|
+
...(text("email") ? { email: text("email") } : {}),
|
|
139
|
+
...(text("https://volter.ai/github_login") ? { githubLogin: text("https://volter.ai/github_login") } : {}),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function readClaims(jwt) {
|
|
143
|
+
try {
|
|
144
|
+
const part = jwt.split(".")[1] ?? "";
|
|
145
|
+
return JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(part.replace(/-/gu, "+").replace(/_/gu, "/")), (character) => character.charCodeAt(0))));
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return {};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async function sha256(text) {
|
|
152
|
+
return base64url(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(text))));
|
|
153
|
+
}
|
|
154
|
+
function base64url(bytes) {
|
|
155
|
+
return btoa(String.fromCharCode(...bytes)).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/u, "");
|
|
156
|
+
}
|
|
157
|
+
function openWindow(url) {
|
|
158
|
+
const opened = window.open(url, "browser-substrate-volter-sign-in", "popup,width=520,height=720");
|
|
159
|
+
if (!opened)
|
|
160
|
+
throw new Error("the browser blocked the sign-in window; allow pop-ups for this page and press Sign in again");
|
|
161
|
+
return opened;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Keeps the session outside the workspace and serializes refresh: a refresh
|
|
165
|
+
* token is single-use, so the vault marks a rotation before the old token
|
|
166
|
+
* leaves the tab, and a rotation that never finished is a sign-in to do again,
|
|
167
|
+
* never a refresh token to retry.
|
|
168
|
+
*/
|
|
169
|
+
export class VolterSessionVault {
|
|
170
|
+
vault;
|
|
171
|
+
options;
|
|
172
|
+
constructor(vault, options = {}) {
|
|
173
|
+
this.vault = vault;
|
|
174
|
+
this.options = options;
|
|
175
|
+
}
|
|
176
|
+
load() {
|
|
177
|
+
return this.lock(async () => {
|
|
178
|
+
const stored = await this.read();
|
|
179
|
+
if (stored?.rotationId) {
|
|
180
|
+
await this.vault.clear();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
return stored && publicSession(stored);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
/** The session to send now, renewed first when it is about to expire; undefined when there is none or it cannot be renewed. */
|
|
187
|
+
current() {
|
|
188
|
+
return this.lock(async () => {
|
|
189
|
+
const stored = await this.read();
|
|
190
|
+
if (!stored)
|
|
191
|
+
return;
|
|
192
|
+
if (stored.rotationId) {
|
|
193
|
+
await this.vault.clear();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const session = publicSession(stored);
|
|
197
|
+
if (session.expiresAt - REFRESH_MARGIN_MS > Date.now())
|
|
198
|
+
return session;
|
|
199
|
+
if (!session.refreshToken) {
|
|
200
|
+
await this.vault.clear();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
await this.write(session, crypto.randomUUID());
|
|
204
|
+
let next;
|
|
205
|
+
try {
|
|
206
|
+
next = await refreshVolterSession(session, this.options.gateway ? { gateway: this.options.gateway } : {});
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
await this.vault.clear();
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
await this.write(next);
|
|
213
|
+
return next;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
save(session) {
|
|
217
|
+
return this.lock(() => this.write(session));
|
|
218
|
+
}
|
|
219
|
+
clear() {
|
|
220
|
+
return this.lock(() => this.vault.clear());
|
|
221
|
+
}
|
|
222
|
+
async read() {
|
|
223
|
+
const bytes = await this.vault.load();
|
|
224
|
+
if (!bytes)
|
|
225
|
+
return;
|
|
226
|
+
try {
|
|
227
|
+
const stored = JSON.parse(new TextDecoder().decode(bytes));
|
|
228
|
+
if (stored.version !== 1 || typeof stored.accessToken !== "string" || typeof stored.subject !== "string" || typeof stored.expiresAt !== "number")
|
|
229
|
+
return;
|
|
230
|
+
return stored;
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async write(session, rotationId) {
|
|
237
|
+
const stored = { ...session, version: 1, savedAt: Date.now(), ...(rotationId ? { rotationId } : {}) };
|
|
238
|
+
const bytes = new TextEncoder().encode(JSON.stringify(stored));
|
|
239
|
+
if (bytes.byteLength > MAXIMUM_SESSION_BYTES)
|
|
240
|
+
throw new Error("The Volter session record is unexpectedly large.");
|
|
241
|
+
await this.vault.save(bytes, { backup: "current" });
|
|
242
|
+
}
|
|
243
|
+
async lock(operation) {
|
|
244
|
+
if (this.options.lock)
|
|
245
|
+
return this.options.lock(operation);
|
|
246
|
+
if (!globalThis.navigator?.locks)
|
|
247
|
+
throw new Error("Volter session storage requires browser Web Locks.");
|
|
248
|
+
return await navigator.locks.request("browser-substrate-volter-session", operation);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function publicSession(stored) {
|
|
252
|
+
const { version: _version, savedAt: _savedAt, rotationId: _rotationId, ...session } = stored;
|
|
253
|
+
return session;
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=volter-sign-in.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"volter-sign-in.js","sourceRoot":"","sources":["../src/volter-sign-in.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,27 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/browser-toolbelt",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Shell, Git, and standard development commands for the Volter browser runtime",
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"description": "Shell, Git's remote helper, and standard development commands for the Volter browser runtime",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/volter-ai/browser-substrate.git",
|
|
9
9
|
"directory": "packages/toolbelt"
|
|
10
10
|
},
|
|
11
|
-
"publishConfig": {
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
12
14
|
"type": "module",
|
|
13
|
-
"files": [
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
14
20
|
"types": "./dist/index.d.ts",
|
|
15
21
|
"exports": {
|
|
16
|
-
".": {
|
|
17
|
-
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./*.js": {
|
|
27
|
+
"types": "./dist/*.d.ts",
|
|
28
|
+
"import": "./dist/*.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc -p tsconfig.build.json"
|
|
18
33
|
},
|
|
19
|
-
"scripts": { "build": "tsc -p tsconfig.build.json" },
|
|
20
34
|
"dependencies": {
|
|
21
35
|
"@volter/browser-runtime": "^0.1.5",
|
|
22
|
-
"buffer": "
|
|
23
|
-
"diff": "^8.0.4",
|
|
24
|
-
"isomorphic-git": "^1.41.9",
|
|
36
|
+
"buffer": "6.0.3",
|
|
25
37
|
"just-bash": "^2.14.5"
|
|
26
38
|
}
|
|
27
39
|
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { BrowserFileSystem } from "@volter/browser-runtime/browser-filesystem.js";
|
|
2
|
-
import type { FsClient } from "isomorphic-git";
|
|
3
|
-
/** Promise-style Node fs subset backed directly by the shared browser VFS. */
|
|
4
|
-
export declare class BrowserGitFileSystem {
|
|
5
|
-
private readonly filesystem;
|
|
6
|
-
readonly client: FsClient;
|
|
7
|
-
constructor(filesystem: BrowserFileSystem);
|
|
8
|
-
private readFile;
|
|
9
|
-
private writeFile;
|
|
10
|
-
private unlink;
|
|
11
|
-
private readdir;
|
|
12
|
-
private mkdir;
|
|
13
|
-
private rmdir;
|
|
14
|
-
private stat;
|
|
15
|
-
private chmod;
|
|
16
|
-
private unsupportedLink;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=browser-git-filesystem.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-git-filesystem.d.ts","sourceRoot":"","sources":["../src/browser-git-filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK/C,8EAA8E;AAC9E,qBAAa,oBAAoB;IAGnB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAFvC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;gBAEG,UAAU,EAAE,iBAAiB;YAkB5C,QAAQ;YAcR,SAAS;YAUT,MAAM;YACN,OAAO;YACP,KAAK;YACL,KAAK;YAEL,IAAI;YAIJ,KAAK;YAKL,eAAe;CAG9B"}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/** Promise-style Node fs subset backed directly by the shared browser VFS. */
|
|
2
|
-
export class BrowserGitFileSystem {
|
|
3
|
-
filesystem;
|
|
4
|
-
client;
|
|
5
|
-
constructor(filesystem) {
|
|
6
|
-
this.filesystem = filesystem;
|
|
7
|
-
this.client = {
|
|
8
|
-
promises: {
|
|
9
|
-
readFile: (path, options) => this.readFile(path, options),
|
|
10
|
-
writeFile: (path, data) => this.writeFile(path, data),
|
|
11
|
-
unlink: (path) => this.unlink(path),
|
|
12
|
-
readdir: (path) => this.readdir(path),
|
|
13
|
-
mkdir: (path) => this.mkdir(path),
|
|
14
|
-
rmdir: (path) => this.rmdir(path),
|
|
15
|
-
stat: (path) => this.stat(path),
|
|
16
|
-
lstat: (path) => this.stat(path),
|
|
17
|
-
readlink: (path) => this.unsupportedLink("readlink", path),
|
|
18
|
-
symlink: (_target, path) => this.unsupportedLink("symlink", path),
|
|
19
|
-
chmod: (path, mode) => this.chmod(path, mode),
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
async readFile(path, options) {
|
|
24
|
-
const bytes = this.filesystem.readFileSync(path);
|
|
25
|
-
const encoding = typeof options === "string" ? options : options?.encoding;
|
|
26
|
-
if (!encoding || encoding === "buffer")
|
|
27
|
-
return bytes;
|
|
28
|
-
if (encoding === "latin1" || encoding === "binary") {
|
|
29
|
-
let value = "";
|
|
30
|
-
for (let offset = 0; offset < bytes.byteLength; offset += 0x8000) {
|
|
31
|
-
value += String.fromCharCode(...bytes.subarray(offset, offset + 0x8000));
|
|
32
|
-
}
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
return new TextDecoder().decode(bytes);
|
|
36
|
-
}
|
|
37
|
-
async writeFile(path, data) {
|
|
38
|
-
const parent = dirname(path);
|
|
39
|
-
this.filesystem.mkdirSync(parent, { recursive: true });
|
|
40
|
-
if (typeof data === "string" || data instanceof Uint8Array) {
|
|
41
|
-
this.filesystem.writeFileSync(path, data);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
this.filesystem.writeFileSync(path, new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
|
|
45
|
-
}
|
|
46
|
-
async unlink(path) { this.filesystem.unlinkSync(path); }
|
|
47
|
-
async readdir(path) { return this.filesystem.readdirSync(path); }
|
|
48
|
-
async mkdir(path) { this.filesystem.mkdirSync(path, { recursive: true }); }
|
|
49
|
-
async rmdir(path) { this.filesystem.rmdirSync(path); }
|
|
50
|
-
async stat(path) {
|
|
51
|
-
return gitStat(this.filesystem.statSync(path));
|
|
52
|
-
}
|
|
53
|
-
async chmod(path, mode) {
|
|
54
|
-
this.filesystem.statSync(path);
|
|
55
|
-
this.filesystem.chmodSync(path, mode);
|
|
56
|
-
}
|
|
57
|
-
async unsupportedLink(operation, path) {
|
|
58
|
-
throw Object.assign(new Error(`ENOSYS: ${operation} '${path}'`), { code: "ENOSYS", path });
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
function dirname(path) {
|
|
62
|
-
const normalized = path.replace(/\/+$/u, "");
|
|
63
|
-
const index = normalized.lastIndexOf("/");
|
|
64
|
-
return index <= 0 ? "/" : normalized.slice(0, index);
|
|
65
|
-
}
|
|
66
|
-
function gitStat(value) {
|
|
67
|
-
const mtimeMs = value.mtimeMs ?? Date.now();
|
|
68
|
-
return {
|
|
69
|
-
isFile: () => value.isFile(),
|
|
70
|
-
isDirectory: () => value.isDirectory(),
|
|
71
|
-
isSymbolicLink: () => false,
|
|
72
|
-
mode: value.mode ?? (value.isDirectory() ? 0o755 : 0o644),
|
|
73
|
-
size: value.size,
|
|
74
|
-
mtime: new Date(mtimeMs),
|
|
75
|
-
mtimeMs,
|
|
76
|
-
ctime: new Date(mtimeMs),
|
|
77
|
-
ctimeMs: mtimeMs,
|
|
78
|
-
uid: 1000,
|
|
79
|
-
gid: 1000,
|
|
80
|
-
ino: 0,
|
|
81
|
-
dev: 0,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=browser-git-filesystem.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-git-filesystem.js","sourceRoot":"","sources":["../src/browser-git-filesystem.ts"],"names":[],"mappings":"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"}
|
package/dist/browser-git.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { BrowserFileSystem } from "@volter/browser-runtime/browser-filesystem.js";
|
|
2
|
-
import type { HttpClient } from "isomorphic-git";
|
|
3
|
-
import type { BrowserShellProgramRunner } from "./browser-shell.js";
|
|
4
|
-
export interface BrowserGitOptions {
|
|
5
|
-
/** Supply an embedding-owned smart-HTTP transport instead of the default edge client. */
|
|
6
|
-
http?: HttpClient;
|
|
7
|
-
}
|
|
8
|
-
/** Local Git CLI surface operating entirely on the shared browser VFS. */
|
|
9
|
-
export declare class BrowserGit {
|
|
10
|
-
private readonly filesystem;
|
|
11
|
-
readonly run: BrowserShellProgramRunner;
|
|
12
|
-
private readonly fs;
|
|
13
|
-
private readonly http;
|
|
14
|
-
constructor(filesystem: BrowserFileSystem, options?: BrowserGitOptions);
|
|
15
|
-
private execute;
|
|
16
|
-
private initialize;
|
|
17
|
-
private clone;
|
|
18
|
-
private status;
|
|
19
|
-
private add;
|
|
20
|
-
private remove;
|
|
21
|
-
private commit;
|
|
22
|
-
private config;
|
|
23
|
-
private log;
|
|
24
|
-
private branch;
|
|
25
|
-
private checkout;
|
|
26
|
-
private diff;
|
|
27
|
-
private entryContent;
|
|
28
|
-
private revParse;
|
|
29
|
-
private lsFiles;
|
|
30
|
-
private remote;
|
|
31
|
-
private fetch;
|
|
32
|
-
private pull;
|
|
33
|
-
private push;
|
|
34
|
-
private remoteUrl;
|
|
35
|
-
private repositoryRoot;
|
|
36
|
-
private removeTree;
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=browser-git.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-git.d.ts","sourceRoot":"","sources":["../src/browser-git.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,gBAAgB,CAAC;AAG9D,OAAO,KAAK,EACV,yBAAyB,EAG1B,MAAM,oBAAoB,CAAC;AAW5B,MAAM,WAAW,iBAAiB;IAChC,yFAAyF;IACzF,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,0EAA0E;AAC1E,qBAAa,UAAU;IAKT,OAAO,CAAC,QAAQ,CAAC,UAAU;IAJvC,QAAQ,CAAC,GAAG,EAAE,yBAAyB,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEL,UAAU,EAAE,iBAAiB,EAAE,OAAO,GAAE,iBAAsB;YAM7E,OAAO;YAsCP,UAAU;YAeV,KAAK;YA0BL,MAAM;YAaN,GAAG;YAeH,MAAM;YAYN,MAAM;YAwBN,MAAM;YAYN,GAAG;YAeH,MAAM;YAeN,QAAQ;YASR,IAAI;YA8CJ,YAAY;YAQZ,QAAQ;YASR,OAAO;YAKP,MAAM;YA8BN,KAAK;YAkBL,IAAI;YAkBJ,IAAI;YA2BJ,SAAS;IAIvB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,UAAU;CAMnB"}
|