fluxy-bot 0.12.0 → 0.12.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/supervisor/index.ts +19 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxy-bot",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "releaseNotes": [
5
5
  "Adding a way for users to claim their fluxies on the fluxy.bot dashboard",
6
6
  "2. ",
@@ -18,6 +18,7 @@ import { ensureFileDirs, saveAttachment, type SavedFile } from './file-saver.js'
18
18
  import { startViteDevServers, stopViteDevServers } from './vite-dev.js';
19
19
  import { startScheduler, stopScheduler } from './scheduler.js';
20
20
  import { execSync, spawn as cpSpawn } from 'child_process';
21
+ import crypto from 'crypto';
21
22
 
22
23
  const DIST_FLUXY = path.join(PKG_DIR, 'dist-fluxy');
23
24
 
@@ -197,6 +198,7 @@ const RECOVERING_HTML = `<!DOCTYPE html><html style="background:#222122"><head><
197
198
  export async function startSupervisor() {
198
199
  const config = loadConfig();
199
200
  const backendPort = getBackendPort(config.port);
201
+ const internalSecret = crypto.randomBytes(16).toString('hex');
200
202
 
201
203
  // Create HTTP server first (Vite needs it for HMR WebSocket)
202
204
  // The request handler is set up later via server.on('request')
@@ -232,7 +234,7 @@ export async function startSupervisor() {
232
234
 
233
235
  /** Call worker API endpoints (in-process via supervisor's own HTTP server) */
234
236
  async function workerApi(apiPath: string, method = 'GET', body?: any) {
235
- const opts: RequestInit = { method, headers: { 'Content-Type': 'application/json' } };
237
+ const opts: RequestInit = { method, headers: { 'Content-Type': 'application/json', 'x-internal': internalSecret } };
236
238
  if (body) opts.body = JSON.stringify(body);
237
239
  const res = await fetch(`http://127.0.0.1:${config.port}${apiPath}`, opts);
238
240
  return res.json();
@@ -366,17 +368,22 @@ export async function startSupervisor() {
366
368
 
367
369
  // API routes → handled in-process by worker Express app
368
370
  if (req.url?.startsWith('/api')) {
369
- // Auth check for mutation routes (POST/PUT/DELETE) — GET/HEAD are read-only, skip auth
370
- const method = req.method || 'GET';
371
- if (method !== 'GET' && method !== 'HEAD' && !isExemptRoute(method, req.url || '')) {
372
- const needsAuth = await isAuthRequired();
373
- if (needsAuth) {
374
- const authHeader = req.headers['authorization'];
375
- const token = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;
376
- if (!token || !(await validateToken(token))) {
377
- res.writeHead(401, { 'Content-Type': 'application/json' });
378
- res.end(JSON.stringify({ error: 'Unauthorized' }));
379
- return;
371
+ // Internal supervisor calls (workerApi) bypass auth they carry a per-process secret
372
+ const isInternal = req.headers['x-internal'] === internalSecret;
373
+
374
+ if (!isInternal) {
375
+ // Auth check for mutation routes (POST/PUT/DELETE) — GET/HEAD are read-only, skip auth
376
+ const method = req.method || 'GET';
377
+ if (method !== 'GET' && method !== 'HEAD' && !isExemptRoute(method, req.url || '')) {
378
+ const needsAuth = await isAuthRequired();
379
+ if (needsAuth) {
380
+ const authHeader = req.headers['authorization'];
381
+ const token = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;
382
+ if (!token || !(await validateToken(token))) {
383
+ res.writeHead(401, { 'Content-Type': 'application/json' });
384
+ res.end(JSON.stringify({ error: 'Unauthorized' }));
385
+ return;
386
+ }
380
387
  }
381
388
  }
382
389
  }