@polderlabs/bizar 5.3.0 → 5.3.1
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/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/bizar-dash/src/server/auth.mjs +14 -1
- package/bizar-dash/src/server/routes/users.mjs +18 -0
- package/cli/commands/dash.mjs +5 -0
- package/cli/commands/tailscale.mjs +8 -1
- package/package.json +1 -1
package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"4.1.9","results":[[":tests/lib/utils.test.ts",{"duration":
|
|
1
|
+
{"version":"4.1.9","results":[[":tests/lib/utils.test.ts",{"duration":15.788036999999974,"failed":false}],[":tests/components/Button.test.tsx",{"duration":84.90294800000004,"failed":false}],[":tests/components/Card.test.tsx",{"duration":18.837508999999955,"failed":false}],[":tests/hooks/useModal.test.tsx",{"duration":120.20212400000003,"failed":false}],[":tests/components/Toast.test.tsx",{"duration":161.860364,"failed":false}],[":tests/components/Modal.test.tsx",{"duration":169.36771700000008,"failed":false}],[":tests/lib/i18n.test.ts",{"duration":2.9599100000000362,"failed":false}],[":tests/components/StatusBadge.test.tsx",{"duration":22.451562999999965,"failed":false}],[":tests/hooks/useToast.test.tsx",{"duration":113.03238799999997,"failed":false}],[":tests/components/Spinner.test.tsx",{"duration":56.80167199999994,"failed":false}],[":tests/backup-restore.test.tsx",{"duration":209.892064,"failed":false}],[":tests/a11y.test.tsx",{"duration":679.8717469999999,"failed":false}],[":tests/lib/search-fuzzy.test.ts",{"duration":5.03047799999996,"failed":false}],[":tests/components/settings-search.test.tsx",{"duration":718.4375819999999,"failed":false}],[":tests/memory-graph-view.test.tsx",{"duration":29.26699000000002,"failed":false}],[":tests/components/workspace-selector.test.tsx",{"duration":120.47785299999998,"failed":false}],[":tests/components/screenshot-ocr.test.tsx",{"duration":27.81256400000001,"failed":false}],[":tests/voice-recorder.test.tsx",{"duration":114.61372900000003,"failed":false}],[":tests/autosave.test.tsx",{"duration":254.917053,"failed":false}],[":tests/settings-layout.test.tsx",{"duration":217.68918099999996,"failed":false}],[":tests/settings-nav.test.tsx",{"duration":290.68972699999995,"failed":false}],[":tests/components/doctor-panel.test.tsx",{"duration":70.02781100000004,"failed":false}],[":tests/chat-composer.test.tsx",{"duration":232.71696299999996,"failed":false}],[":tests/settings-mode-wiring.test.tsx",{"duration":276.79545799999994,"failed":false}],[":tests/minimax-bar.test.ts",{"duration":0,"failed":true}],[":tests/minimax-bar.test.tsx",{"duration":22.24368499999997,"failed":false}],[":tests/components/plugin-permissions.test.tsx",{"duration":92.75674500000002,"failed":false}],[":tests/eval-web-ui.test.tsx",{"duration":117.119639,"failed":false}],[":tests/components/marketplace-plugin-card.test.tsx",{"duration":188.3587500000001,"failed":false}],[":tests/a11y/components.test.tsx",{"duration":127.70726300000001,"failed":false}],[":tests/a11y/forms.test.tsx",{"duration":103.14186000000007,"failed":true}],[":tests/a11y/navigation.test.tsx",{"duration":120.83297300000004,"failed":true}]]}
|
|
@@ -484,7 +484,20 @@ function extractToken(req) {
|
|
|
484
484
|
*/
|
|
485
485
|
export function getCurrentUserId(req) {
|
|
486
486
|
const token = extractToken(req);
|
|
487
|
-
if (!token)
|
|
487
|
+
if (!token) {
|
|
488
|
+
// v5.3.1 — Tailscale trust: when the dashboard is reached via
|
|
489
|
+
// tailscale serve and the operator has opted in to trust tailnet
|
|
490
|
+
// clients, derive a deterministic userId from the tailnet hostname
|
|
491
|
+
// so the rest of the v5.0 multi-user code paths (workspaces, etc.)
|
|
492
|
+
// work without requiring an explicit token.
|
|
493
|
+
if (process.env.BIZAR_DASHBOARD_TRUST_TAILSCALE === '1' && isLoopback(req)) {
|
|
494
|
+
const hostname = String(req?.headers?.host || '').split(':')[0];
|
|
495
|
+
if (hostname && hostname.endsWith('.ts.net')) {
|
|
496
|
+
return 'usr_ts_' + createHash('sha256').update(hostname).digest('hex').slice(0, 12);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return null;
|
|
500
|
+
}
|
|
488
501
|
|
|
489
502
|
const secret = getOrCreateSecret();
|
|
490
503
|
|
|
@@ -26,7 +26,25 @@ export function createUsersRouter() {
|
|
|
26
26
|
return res.status(401).json({ error: 'unauthorized', message: 'Not authenticated' });
|
|
27
27
|
}
|
|
28
28
|
const user = await getUser(userId);
|
|
29
|
+
// v5.3.1 — Tailscale-trust: when getCurrentUserId returns a derived
|
|
30
|
+
// userId (usr_ts_*) that doesn't exist in the store, synthesize a
|
|
31
|
+
// minimal user record from the request Host header so the dashboard
|
|
32
|
+
// can render a profile without needing a full signup.
|
|
29
33
|
if (!user) {
|
|
34
|
+
if (userId.startsWith('usr_ts_')) {
|
|
35
|
+
const host = String(req.headers?.host || '').split(':')[0] || 'tailnet';
|
|
36
|
+
const tailnetName = host.split('.')[0] || 'tailnet';
|
|
37
|
+
const workspaces = await listWorkspacesWithRoles(userId);
|
|
38
|
+
return res.json({
|
|
39
|
+
user: {
|
|
40
|
+
id: userId,
|
|
41
|
+
email: `${tailnetName}@tailscale.local`,
|
|
42
|
+
name: `Tailnet user (${tailnetName})`,
|
|
43
|
+
tailnet: true
|
|
44
|
+
},
|
|
45
|
+
workspaces
|
|
46
|
+
});
|
|
47
|
+
}
|
|
30
48
|
return res.status(404).json({ error: 'not_found', message: 'User not found' });
|
|
31
49
|
}
|
|
32
50
|
const workspaces = await listWorkspacesWithRoles(userId);
|
package/cli/commands/dash.mjs
CHANGED
|
@@ -138,6 +138,11 @@ export async function runDash(dashArgs) {
|
|
|
138
138
|
const serveResult = await setupTailscaleServe({ dashboardPort: usePort });
|
|
139
139
|
if (serveResult.ok) {
|
|
140
140
|
console.log(chalk.green(` ✓ Tailscale serve: ${serveResult.url}`));
|
|
141
|
+
// v5.3.1 — Auto-trust Tailscale clients so they don't need
|
|
142
|
+
// a bearer token. Tailscale users are already authenticated
|
|
143
|
+
// on the tailnet before they reach the dashboard.
|
|
144
|
+
process.env.BIZAR_DASHBOARD_TRUST_TAILSCALE = '1';
|
|
145
|
+
console.log(chalk.dim(' ✓ Tailscale clients auto-trusted (BIZAR_DASHBOARD_TRUST_TAILSCALE=1)'));
|
|
141
146
|
}
|
|
142
147
|
}
|
|
143
148
|
} catch (err) {
|
|
@@ -83,9 +83,16 @@ export async function setupTailscaleServe({ dashboardPort = 4097, path = '/', ht
|
|
|
83
83
|
} catch { /* ignore — might not have existing config */ }
|
|
84
84
|
|
|
85
85
|
// Set up new serve config
|
|
86
|
+
// v5.3.1 — Use --set-x-forwarded-for=trailing so the dashboard sees
|
|
87
|
+
// the original client IP (a 100.x Tailscale address) in X-Forwarded-For.
|
|
88
|
+
// Without this, the dashboard can't tell that the request came from
|
|
89
|
+
// a trusted tailnet client and demands a bearer token.
|
|
86
90
|
try {
|
|
87
91
|
execFileSync('tailscale', [
|
|
88
|
-
'serve', '--bg',
|
|
92
|
+
'serve', '--bg',
|
|
93
|
+
`--https=${https}`,
|
|
94
|
+
`--set-path=${path}`,
|
|
95
|
+
'--set-x-forwarded-for=trailing',
|
|
89
96
|
`http://localhost:${dashboardPort}`,
|
|
90
97
|
], { encoding: 'utf8', timeout: 30000 });
|
|
91
98
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polderlabs/bizar",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.1",
|
|
4
4
|
"description": "Norse-pantheon multi-agent system for opencode — 13 agents across 4 cost tiers with cost-aware routing, plans, and a configurable agent harness. v4 ships as a single npm package bundling the dashboard server, opencode plugin, and typed SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|