@artenx/dshb 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/lib/auth/index.js CHANGED
@@ -17,7 +17,7 @@ function registerFrontendBootRaceWorkaround(ctx) {
17
17
  if (!assetName) return;
18
18
  const assetPath = join(assetDir, assetName);
19
19
  const source = readFileSync(assetPath, "utf8");
20
- const patched = source.replace("await i.await(),this.assertEntriesActive(t)", "await i.await(),await new Promise(r=>setTimeout(r,8000)),this.assertEntriesActive(t)");
20
+ 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
21
  if (patched === source) return;
22
22
  ctx.effect(() => ctx.webServer.register({
23
23
  kind: "exact",
@@ -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 from the active profile so the route patches the same hashed asset\n // that dsh-web-app's static fallback serves.\n const resolver = createRequire(import.meta.url)\n const manifestPath = resolver.resolve('@deepseek-ai/dsh-web-frontend/package.json', {\n paths: [process.cwd()],\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.\n const patched = source.replace(\n 'await i.await(),this.assertEntriesActive(t)',\n 'await i.await(),await new Promise(r=>setTimeout(r,8000)),this.assertEntriesActive(t)',\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;EAIF,MAAM,eADW,cAAc,YAAY,GACf,CAAC,CAAC,QAAQ,8CAA8C,EAClF,OAAO,CAAC,QAAQ,IAAI,CAAC,EACvB,CAAC;EACD,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;EAI7C,MAAM,UAAU,OAAO,QACrB,+CACA,sFACF;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"}
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 from the active profile so the route patches the same hashed asset\n // that dsh-web-app's static fallback serves.\n const resolver = createRequire(import.meta.url)\n const manifestPath = resolver.resolve('@deepseek-ai/dsh-web-frontend/package.json', {\n paths: [process.cwd()],\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;EAIF,MAAM,eADW,cAAc,YAAY,GACf,CAAC,CAAC,QAAQ,8CAA8C,EAClF,OAAO,CAAC,QAAQ,IAAI,CAAC,EACvB,CAAC;EACD,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.5",
3
+ "version": "0.1.6",
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",