@artenx/dshb 0.1.5 → 0.1.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/auth/index.js +9 -2
- package/lib/auth/index.js.map +1 -1
- package/package.json +1 -1
package/lib/auth/index.js
CHANGED
|
@@ -11,13 +11,20 @@ const name = "dshb-auth";
|
|
|
11
11
|
const inject = ["webServer"];
|
|
12
12
|
function registerFrontendBootRaceWorkaround(ctx) {
|
|
13
13
|
try {
|
|
14
|
-
const
|
|
14
|
+
const resolver = createRequire(import.meta.url);
|
|
15
|
+
let manifestPath;
|
|
16
|
+
try {
|
|
17
|
+
const webAppManifest = resolver.resolve("@deepseek-ai/dsh-web-app/package.json");
|
|
18
|
+
manifestPath = createRequire(webAppManifest).resolve("@deepseek-ai/dsh-web-frontend/package.json");
|
|
19
|
+
} catch {
|
|
20
|
+
manifestPath = resolver.resolve("@deepseek-ai/dsh-web-frontend/package.json", { paths: [process.cwd()] });
|
|
21
|
+
}
|
|
15
22
|
const assetDir = join(dirname(manifestPath), "dist", "assets");
|
|
16
23
|
const assetName = readdirSync(assetDir).find((name) => /^index-.*\.js$/.test(name));
|
|
17
24
|
if (!assetName) return;
|
|
18
25
|
const assetPath = join(assetDir, assetName);
|
|
19
26
|
const source = readFileSync(assetPath, "utf8");
|
|
20
|
-
const patched = source.replace(
|
|
27
|
+
const patched = source.replace(/await ([A-Za-z_$][\w$]*)\.await\(\),this\.assertEntriesActive\(([A-Za-z_$][\w$]*)\)/, "await $1.await(),await new Promise(r=>setTimeout(r,8000)),this.assertEntriesActive($2)");
|
|
21
28
|
if (patched === source) return;
|
|
22
29
|
ctx.effect(() => ctx.webServer.register({
|
|
23
30
|
kind: "exact",
|
package/lib/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/auth/index.ts"],"sourcesContent":["import { readFileSync, readdirSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { sharedCredentialStore } from './credentials.js'\nimport { decorateWebServer } from './decorate-webserver.js'\nimport { installLoopbackCompat } from './loopback-compat.js'\nimport { LoginRateLimiter } from './ratelimit.js'\nimport { registerAuthRoutes } from './routes.js'\n\nexport const name = 'dshb-auth'\n\nexport const inject = ['webServer']\n\nfunction registerFrontendBootRaceWorkaround(ctx: Context): void {\n try {\n // Resolve
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/auth/index.ts"],"sourcesContent":["import { readFileSync, readdirSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { sharedCredentialStore } from './credentials.js'\nimport { decorateWebServer } from './decorate-webserver.js'\nimport { installLoopbackCompat } from './loopback-compat.js'\nimport { LoginRateLimiter } from './ratelimit.js'\nimport { registerAuthRoutes } from './routes.js'\n\nexport const name = 'dshb-auth'\n\nexport const inject = ['webServer']\n\nfunction registerFrontendBootRaceWorkaround(ctx: Context): void {\n try {\n // Resolve the frontend through the same `dsh-web-app` bundle the webserver\n // loads, so the patched hashed asset is the one the static fallback serves.\n // `process.cwd()` may hold a different installation whose asset filename\n // the server never requests, leaving the served bundle unpatched.\n const resolver = createRequire(import.meta.url)\n let manifestPath: string\n try {\n const webAppManifest = resolver.resolve('@deepseek-ai/dsh-web-app/package.json')\n manifestPath = createRequire(webAppManifest).resolve('@deepseek-ai/dsh-web-frontend/package.json')\n } catch {\n manifestPath = resolver.resolve('@deepseek-ai/dsh-web-frontend/package.json', {\n paths: [process.cwd()],\n })\n }\n const assetDir = join(dirname(manifestPath), 'dist', 'assets')\n const assetName = readdirSync(assetDir).find((name) => /^index-.*\\.js$/.test(name))\n if (!assetName) return\n\n const assetPath = join(assetDir, assetName)\n const source = readFileSync(assetPath, 'utf8')\n // DSH 0.1.5 asserts before api-remotes' dynamic remote namespace fibers\n // settle. Delay the assertion so mountApp sees the complete client graph;\n // real activation failures still throw after the bounded wait. The loader\n // and context identifiers are minified per build, so match them by shape\n // rather than by the identifier names of any single bundle.\n const patched = source.replace(\n /await ([A-Za-z_$][\\w$]*)\\.await\\(\\),this\\.assertEntriesActive\\(([A-Za-z_$][\\w$]*)\\)/,\n 'await $1.await(),await new Promise(r=>setTimeout(r,8000)),this.assertEntriesActive($2)',\n )\n if (patched === source) return\n\n ctx.effect(() =>\n ctx.webServer.register({\n kind: 'exact',\n path: `/assets/${basename(assetPath)}`,\n handler: (_req, res) => {\n res.writeHead(200, {\n 'cache-control': 'no-store',\n 'content-type': 'application/javascript; charset=utf-8',\n })\n res.end(patched)\n },\n }),\n )\n } catch {\n // Upstream assets are optional from DSHB's perspective. A missing or changed\n // frontend layout simply skips this version-specific workaround.\n }\n}\n\nexport function apply(ctx: Context): void {\n decorateWebServer(ctx.webServer, sharedCredentialStore())\n registerFrontendBootRaceWorkaround(ctx)\n ctx.webServer.tapIndex(installLoopbackCompat)\n registerAuthRoutes(ctx, sharedCredentialStore(), new LoginRateLimiter())\n\n // DSH 0.1.5 introduced a browser-auth fence on the connection package: the SPA\n // fallback calls connection.authorizeIndex() on \"/\" (mints/checks DSH's own\n // launch-token cookie), and /api routes run requestRejection() which 401s when\n // that DSH cookie is absent. DSHB uses its own session cookie and must stay the\n // sole auth gate (DSH 0.1.1 had no such connection fence, so DSHB worked there).\n // Neutralize the connection's browserAuth.isAuthenticated check so DSH's fence\n // never rejects a DSHB-authenticated (or loopback) request; DSHB's gate still\n // rejects unauthenticated access to gated routes. Property is read at request\n // time, so installing it once after connection is ready suffices.\n ctx.inject(['connection'], (connCtx: Context) => {\n const conn = (connCtx as unknown as { connection?: { browserAuth?: { isAuthenticated?: (...a: unknown[]) => unknown; __dshbNeutralized?: true } } }).connection\n const auth = conn?.browserAuth\n if (auth && typeof auth.isAuthenticated === 'function' && !auth.__dshbNeutralized) {\n auth.isAuthenticated = () => true\n auth.__dshbNeutralized = true\n }\n })\n}\n"],"mappings":";;;;;;;;;AAUA,MAAa,OAAO;AAEpB,MAAa,SAAS,CAAC,WAAW;AAElC,SAAS,mCAAmC,KAAoB;CAC9D,IAAI;EAKF,MAAM,WAAW,cAAc,YAAY,GAAG;EAC9C,IAAI;EACJ,IAAI;GACF,MAAM,iBAAiB,SAAS,QAAQ,uCAAuC;GAC/E,eAAe,cAAc,cAAc,CAAC,CAAC,QAAQ,4CAA4C;EACnG,QAAQ;GACN,eAAe,SAAS,QAAQ,8CAA8C,EAC5E,OAAO,CAAC,QAAQ,IAAI,CAAC,EACvB,CAAC;EACH;EACA,MAAM,WAAW,KAAK,QAAQ,YAAY,GAAG,QAAQ,QAAQ;EAC7D,MAAM,YAAY,YAAY,QAAQ,CAAC,CAAC,MAAM,SAAS,iBAAiB,KAAK,IAAI,CAAC;EAClF,IAAI,CAAC,WAAW;EAEhB,MAAM,YAAY,KAAK,UAAU,SAAS;EAC1C,MAAM,SAAS,aAAa,WAAW,MAAM;EAM7C,MAAM,UAAU,OAAO,QACrB,uFACA,wFACF;EACA,IAAI,YAAY,QAAQ;EAExB,IAAI,aACF,IAAI,UAAU,SAAS;GACrB,MAAM;GACN,MAAM,WAAW,SAAS,SAAS;GACnC,UAAU,MAAM,QAAQ;IACtB,IAAI,UAAU,KAAK;KACjB,iBAAiB;KACjB,gBAAgB;IAClB,CAAC;IACD,IAAI,IAAI,OAAO;GACjB;EACF,CAAC,CACH;CACF,QAAQ,CAGR;AACF;AAEA,SAAgB,MAAM,KAAoB;CACxC,kBAAkB,IAAI,WAAW,sBAAsB,CAAC;CACxD,mCAAmC,GAAG;CACtC,IAAI,UAAU,SAAS,qBAAqB;CAC5C,mBAAmB,KAAK,sBAAsB,GAAG,IAAI,iBAAiB,CAAC;CAWvE,IAAI,OAAO,CAAC,YAAY,IAAI,YAAqB;EAE/C,MAAM,OADQ,QAAuI,YAClI;EACnB,IAAI,QAAQ,OAAO,KAAK,oBAAoB,cAAc,CAAC,KAAK,mBAAmB;GACjF,KAAK,wBAAwB;GAC7B,KAAK,oBAAoB;EAC3B;CACF,CAAC;AACH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artenx/dshb",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Routes DSH filesystem, shell, subprocess, and PTY operations to local, SSH, and Docker execution nodes, with a node registry, an authentication gate, a mobile-aware management UI, and per-workspace custom project instructions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|