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.
package/dist-fluxy/fluxy.html
CHANGED
|
@@ -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-
|
|
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
|
@@ -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
|
-
|
|
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
|
}
|
package/supervisor/index.ts
CHANGED
|
@@ -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
|
-
|
|
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) {
|
|
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
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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) => {
|