@jeffusion/bungee 5.10.0 → 5.12.0
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/dist/index.js +100 -2
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -3397,7 +3397,7 @@ import { createInterface } from "node:readline";
|
|
|
3397
3397
|
// package.json
|
|
3398
3398
|
var package_default = {
|
|
3399
3399
|
name: "@jeffusion/bungee",
|
|
3400
|
-
version: "5.
|
|
3400
|
+
version: "5.12.0",
|
|
3401
3401
|
description: "High-performance reverse proxy server CLI",
|
|
3402
3402
|
type: "module",
|
|
3403
3403
|
bin: {
|
|
@@ -5357,7 +5357,7 @@ class DaemonManager {
|
|
|
5357
5357
|
try {
|
|
5358
5358
|
logFd = fs2.openSync(this.logFile, "a");
|
|
5359
5359
|
errorLogFd = fs2.openSync(this.errorLogFile, "a");
|
|
5360
|
-
const args = descriptor.entrypoint === null ? [`--bungee-daemon-boot=${bootNonce}`] : [descriptor.entrypoint, `--bungee-daemon-boot=${bootNonce}`];
|
|
5360
|
+
const args = descriptor.entrypoint === null ? [`--bungee-daemon-boot=${bootNonce}`, `--bungee-process-identity=${bootNonce}`] : [descriptor.entrypoint, `--bungee-daemon-boot=${bootNonce}`, `--bungee-process-identity=${bootNonce}`];
|
|
5361
5361
|
child = this.spawnDaemon(descriptor.executable, args, {
|
|
5362
5362
|
detached: true,
|
|
5363
5363
|
stdio: ["ignore", logFd, errorLogFd],
|
|
@@ -6049,9 +6049,107 @@ async function importCommand(options) {
|
|
|
6049
6049
|
}
|
|
6050
6050
|
}
|
|
6051
6051
|
|
|
6052
|
+
// ../core/src/oauth-callback.ts
|
|
6053
|
+
import { createServer } from "node:http";
|
|
6054
|
+
var CALLBACK_PATH = "/auth/callback";
|
|
6055
|
+
async function captureOAuthCallback(options = {}) {
|
|
6056
|
+
const port = options.port ?? 1455;
|
|
6057
|
+
const timeoutMs = options.timeoutMs ?? 5 * 60000;
|
|
6058
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535 || !Number.isFinite(timeoutMs) || timeoutMs <= 0)
|
|
6059
|
+
throw new Error("Invalid callback listener options");
|
|
6060
|
+
let settle;
|
|
6061
|
+
let fail;
|
|
6062
|
+
let completed = false;
|
|
6063
|
+
const result = new Promise((resolve, reject) => {
|
|
6064
|
+
settle = resolve;
|
|
6065
|
+
fail = reject;
|
|
6066
|
+
});
|
|
6067
|
+
const reject = (message) => {
|
|
6068
|
+
if (completed)
|
|
6069
|
+
return;
|
|
6070
|
+
completed = true;
|
|
6071
|
+
fail(new Error(message));
|
|
6072
|
+
};
|
|
6073
|
+
const server = createServer({ maxHeaderSize: 8192 }, (request, response) => {
|
|
6074
|
+
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
|
6075
|
+
response.setHeader("Cache-Control", "no-store");
|
|
6076
|
+
response.setHeader("Referrer-Policy", "no-referrer");
|
|
6077
|
+
const address = server.address();
|
|
6078
|
+
const actualPort = address && typeof address === "object" ? address.port : port;
|
|
6079
|
+
const raw = request.url ?? "";
|
|
6080
|
+
let url;
|
|
6081
|
+
try {
|
|
6082
|
+
url = new URL(raw, `http://127.0.0.1:${actualPort}`);
|
|
6083
|
+
} catch {
|
|
6084
|
+
response.writeHead(400).end("Invalid callback.");
|
|
6085
|
+
return;
|
|
6086
|
+
}
|
|
6087
|
+
const code = url.searchParams.get("code");
|
|
6088
|
+
const state = url.searchParams.get("state");
|
|
6089
|
+
const clientId = url.searchParams.get("client_id");
|
|
6090
|
+
const valid = request.method === "GET" && raw.split("?")[0] === CALLBACK_PATH && raw.length <= 4096 && !url.hash && !url.searchParams.has("error") && !url.searchParams.has("error_description") && [...url.searchParams.keys()].every((key) => url.searchParams.getAll(key).length === 1) && [code, state].every((value) => typeof value === "string" && value.length > 0 && value.trim() === value && !/[\u0000-\u001f\u007f]/.test(value)) && typeof clientId === "string" && /^oaiapp_[A-Za-z0-9_-]{1,200}$/.test(clientId);
|
|
6091
|
+
if (!valid) {
|
|
6092
|
+
response.writeHead(400).end("Invalid callback. Continue with the Bungee authorization page.");
|
|
6093
|
+
return;
|
|
6094
|
+
}
|
|
6095
|
+
if (completed) {
|
|
6096
|
+
response.writeHead(409).end("Callback already captured.");
|
|
6097
|
+
return;
|
|
6098
|
+
}
|
|
6099
|
+
completed = true;
|
|
6100
|
+
response.writeHead(200).end("Callback captured. Paste the complete URL shown in your terminal into Bungee to finish signing in.");
|
|
6101
|
+
settle(url.toString());
|
|
6102
|
+
});
|
|
6103
|
+
server.on("error", () => reject("Cannot listen on 127.0.0.1. Check whether the callback port is occupied."));
|
|
6104
|
+
const abort = () => reject("Callback capture cancelled.");
|
|
6105
|
+
const timer = setTimeout(() => reject("Callback capture timed out. Start a new Bungee login."), timeoutMs);
|
|
6106
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
6107
|
+
try {
|
|
6108
|
+
if (options.signal?.aborted)
|
|
6109
|
+
abort();
|
|
6110
|
+
else
|
|
6111
|
+
server.listen(port, "127.0.0.1", () => {
|
|
6112
|
+
const address = server.address();
|
|
6113
|
+
if (address && typeof address === "object")
|
|
6114
|
+
options.onListening?.(address.port);
|
|
6115
|
+
});
|
|
6116
|
+
return await result;
|
|
6117
|
+
} finally {
|
|
6118
|
+
clearTimeout(timer);
|
|
6119
|
+
options.signal?.removeEventListener("abort", abort);
|
|
6120
|
+
server.closeIdleConnections();
|
|
6121
|
+
server.close();
|
|
6122
|
+
server.closeAllConnections();
|
|
6123
|
+
}
|
|
6124
|
+
}
|
|
6125
|
+
async function oauthCallbackCommand() {
|
|
6126
|
+
const controller = new AbortController;
|
|
6127
|
+
const cancel = () => controller.abort();
|
|
6128
|
+
process.once("SIGINT", cancel);
|
|
6129
|
+
process.once("SIGTERM", cancel);
|
|
6130
|
+
try {
|
|
6131
|
+
const url = await captureOAuthCallback({ signal: controller.signal, onListening: () => {
|
|
6132
|
+
console.error("Listening on 127.0.0.1:1455. Open the SIWC authorization URL from Bungee.");
|
|
6133
|
+
console.error("The printed callback contains a one-time login code. Paste it only into your Bungee login window.");
|
|
6134
|
+
} });
|
|
6135
|
+
console.log(url);
|
|
6136
|
+
} finally {
|
|
6137
|
+
process.removeListener("SIGINT", cancel);
|
|
6138
|
+
process.removeListener("SIGTERM", cancel);
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6141
|
+
|
|
6052
6142
|
// src/index.ts
|
|
6053
6143
|
function createProgram() {
|
|
6054
6144
|
const program = new Command2().name("bungee").description("High-performance reverse proxy server built with Bun and TypeScript").version(package_default.version);
|
|
6145
|
+
program.command("oauth-callback").description("Capture one SIWC browser callback on 127.0.0.1:1455 for manual submission to Bungee").action(async () => {
|
|
6146
|
+
try {
|
|
6147
|
+
await oauthCallbackCommand();
|
|
6148
|
+
} catch {
|
|
6149
|
+
console.error("OAuth callback capture failed or was cancelled. Check the local port and restart the login.");
|
|
6150
|
+
process.exitCode = 1;
|
|
6151
|
+
}
|
|
6152
|
+
});
|
|
6055
6153
|
program.command("init").description("Initialize the Bungee SQLite data directory").action(initCommand);
|
|
6056
6154
|
program.command("recover").description("Recover a stopped instance using bounded JSON from stdin or a 0600 file").option("--file <path>", "Owner-only 0600 recovery JSON input file").addHelpText("after", `
|
|
6057
6155
|
Stop the instance first. Supply one JSON object via stdin or bungee recover --file recovery.json (chmod 600).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jeffusion/bungee",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.12.0",
|
|
4
4
|
"description": "High-performance reverse proxy server CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"test": "bun test"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@jeffusion/bungee-core": "^5.
|
|
17
|
-
"@jeffusion/bungee-types": "^5.
|
|
16
|
+
"@jeffusion/bungee-core": "^5.12.0",
|
|
17
|
+
"@jeffusion/bungee-types": "^5.12.0",
|
|
18
18
|
"cli-progress": "^3.12.0",
|
|
19
19
|
"commander": "^14.0.1"
|
|
20
20
|
},
|