fluxy-bot 0.2.42 → 0.2.43

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.
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-content" />
6
6
  <title>Fluxy Chat</title>
7
- <script type="module" crossorigin src="/fluxy/assets/fluxy-Cfl58Zg0.js"></script>
7
+ <script type="module" crossorigin src="/fluxy/assets/fluxy-B20BJakh.js"></script>
8
8
  <link rel="modulepreload" crossorigin href="/fluxy/assets/globals--DVlL_N5.js">
9
9
  <link rel="stylesheet" crossorigin href="/fluxy/assets/globals-DMXu7CFU.css">
10
10
  </head>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxy-bot",
3
- "version": "0.2.42",
3
+ "version": "0.2.43",
4
4
  "description": "Self-hosted AI bot — run your own AI assistant from anywhere",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,14 +26,21 @@ function LoginForm({ botName, onSuccess }: { botName: string; onSuccess: () => v
26
26
  headers: { 'Content-Type': 'application/json' },
27
27
  body: JSON.stringify({ username, password }),
28
28
  });
29
+ const contentType = res.headers.get('content-type') || '';
30
+ if (!contentType.includes('application/json')) {
31
+ console.error(`[login] Non-JSON response: ${res.status} ${contentType}`);
32
+ setError(`Server error (${res.status})`);
33
+ return;
34
+ }
29
35
  const data = await res.json();
30
36
  if (data.ok) {
31
37
  onSuccess();
32
38
  } else {
33
39
  setError(data.error || 'Login failed');
34
40
  }
35
- } catch {
36
- setError('Connection error');
41
+ } catch (err) {
42
+ console.error('[login] Fetch error:', err);
43
+ setError('Connection error — check if server is running');
37
44
  } finally {
38
45
  setLoading(false);
39
46
  }
@@ -129,7 +129,10 @@ export async function startSupervisor() {
129
129
 
130
130
  // API routes → proxy to worker
131
131
  if (req.url?.startsWith('/api')) {
132
- console.log(`[supervisor] worker :${workerPort} | ${req.method} ${req.url}`);
132
+ const isAuthReq = req.url.startsWith('/api/auth/');
133
+ if (isAuthReq) console.log(`[supervisor] AUTH → worker :${workerPort} | ${req.method} ${req.url} | content-type: ${req.headers['content-type']} | content-length: ${req.headers['content-length']}`);
134
+ else console.log(`[supervisor] → worker :${workerPort} | ${req.method} ${req.url}`);
135
+
133
136
  if (!isWorkerAlive()) {
134
137
  console.log('[supervisor] Worker down — returning 503');
135
138
  res.writeHead(503, { 'Content-Type': 'text/html' });
@@ -140,6 +143,7 @@ export async function startSupervisor() {
140
143
  const proxy = http.request(
141
144
  { host: '127.0.0.1', port: workerPort, path: req.url, method: req.method, headers: req.headers },
142
145
  (proxyRes) => {
146
+ if (isAuthReq) console.log(`[supervisor] AUTH ← worker ${proxyRes.statusCode} | set-cookie: ${proxyRes.headers['set-cookie'] ? 'yes' : 'no'}`);
143
147
  res.writeHead(proxyRes.statusCode!, proxyRes.headers);
144
148
  proxyRes.pipe(res);
145
149
  },
package/worker/index.ts CHANGED
@@ -40,22 +40,39 @@ app.use(express.json());
40
40
  // ── Auth endpoints (public) ──
41
41
 
42
42
  app.post('/api/auth/login', async (req, res) => {
43
+ log.ok(`[auth/login] POST received — body keys: ${Object.keys(req.body || {}).join(', ') || '(empty)'}`);
43
44
  const { username, password } = req.body;
44
- if (!username || !password) { res.status(400).json({ error: 'Missing credentials' }); return; }
45
+ if (!username || !password) {
46
+ log.warn(`[auth/login] Missing credentials — username: ${!!username}, password: ${!!password}`);
47
+ res.status(400).json({ error: 'Missing credentials' }); return;
48
+ }
45
49
 
46
50
  const storedUser = getSetting('portal_user');
47
51
  const storedPass = getSetting('portal_pass');
52
+ log.ok(`[auth/login] Stored portal_user: ${storedUser || '(none)'}, portal_pass: ${storedPass ? 'set' : '(none)'}`);
48
53
  if (!storedUser || !storedPass) { res.status(401).json({ error: 'Portal not configured' }); return; }
49
54
 
50
- if (username.trim().toLowerCase() !== storedUser.toLowerCase() || !verifyPassword(password, storedPass)) {
55
+ const usernameMatch = username.trim().toLowerCase() === storedUser.toLowerCase();
56
+ const passwordMatch = verifyPassword(password, storedPass);
57
+ log.ok(`[auth/login] username match: ${usernameMatch}, password match: ${passwordMatch}`);
58
+
59
+ if (!usernameMatch || !passwordMatch) {
51
60
  res.status(401).json({ error: 'Invalid username or password' });
52
61
  return;
53
62
  }
54
63
 
55
- const token = await signToken({ sub: storedUser, role: 'owner' });
56
- const secure = req.headers['x-forwarded-proto'] === 'https' || req.protocol === 'https';
57
- res.setHeader('Set-Cookie', buildSessionCookie(token, secure));
58
- res.json({ ok: true, username: storedUser });
64
+ try {
65
+ const token = await signToken({ sub: storedUser, role: 'owner' });
66
+ log.ok(`[auth/login] JWT signed OK (length: ${token.length})`);
67
+ const secure = req.headers['x-forwarded-proto'] === 'https' || req.protocol === 'https';
68
+ log.ok(`[auth/login] secure=${secure}, x-forwarded-proto=${req.headers['x-forwarded-proto']}`);
69
+ res.setHeader('Set-Cookie', buildSessionCookie(token, secure));
70
+ res.json({ ok: true, username: storedUser });
71
+ log.ok(`[auth/login] Success — response sent`);
72
+ } catch (err: any) {
73
+ log.warn(`[auth/login] JWT sign error: ${err.message}`);
74
+ res.status(500).json({ error: 'Internal error' });
75
+ }
59
76
  });
60
77
 
61
78
  app.get('/api/auth/me', async (req, res) => {