fluxy-bot 0.7.5 → 0.7.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/dist-fluxy/assets/{fluxy-CR6Sg8AD.js → fluxy-Bcd5tJrt.js} +25 -25
- package/dist-fluxy/assets/{globals-DxeORYnQ.js → globals-CMrTFJSE.js} +7 -7
- package/dist-fluxy/assets/{onboard-ChgrXiME.js → onboard-BSlNrxVH.js} +1 -1
- package/dist-fluxy/fluxy.html +2 -2
- package/dist-fluxy/onboard.html +2 -2
- package/package.json +1 -1
- package/supervisor/chat/OnboardWizard.tsx +4 -1
- package/supervisor/chat/src/components/LoginScreen.tsx +44 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{e as o,j as e,R as n,O as r}from"./globals-
|
|
1
|
+
import{e as o,j as e,R as n,O as r}from"./globals-CMrTFJSE.js";function a(){const t=()=>{window.parent?.postMessage({type:"fluxy:onboard-complete"},"*")};return e.jsx(r,{onComplete:t,isInitialSetup:!0})}o.createRoot(document.getElementById("root")).render(e.jsx(n.StrictMode,{children:e.jsx(a,{})}));
|
package/dist-fluxy/fluxy.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, interactive-widget=resizes-content" />
|
|
6
6
|
<title>Fluxy Chat</title>
|
|
7
|
-
<script type="module" crossorigin src="/fluxy/assets/fluxy-
|
|
8
|
-
<link rel="modulepreload" crossorigin href="/fluxy/assets/globals-
|
|
7
|
+
<script type="module" crossorigin src="/fluxy/assets/fluxy-Bcd5tJrt.js"></script>
|
|
8
|
+
<link rel="modulepreload" crossorigin href="/fluxy/assets/globals-CMrTFJSE.js">
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/fluxy/assets/globals-Bs_wR6rP.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body class="bg-background text-foreground">
|
package/dist-fluxy/onboard.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, interactive-widget=resizes-content" />
|
|
6
6
|
<title>Fluxy Setup</title>
|
|
7
|
-
<script type="module" crossorigin src="/fluxy/assets/onboard-
|
|
8
|
-
<link rel="modulepreload" crossorigin href="/fluxy/assets/globals-
|
|
7
|
+
<script type="module" crossorigin src="/fluxy/assets/onboard-BSlNrxVH.js"></script>
|
|
8
|
+
<link rel="modulepreload" crossorigin href="/fluxy/assets/globals-CMrTFJSE.js">
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/fluxy/assets/globals-Bs_wR6rP.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body class="bg-background text-foreground">
|
package/package.json
CHANGED
|
@@ -182,13 +182,15 @@ export default function OnboardWizard({ onComplete, isInitialSetup = false, onSa
|
|
|
182
182
|
|
|
183
183
|
const isConnected = authState[provider] === 'connected';
|
|
184
184
|
|
|
185
|
-
// Persist/restore TOTP setup state across page reloads (mobile
|
|
185
|
+
// Persist/restore TOTP setup state across page reloads (mobile: OS suspends PWA on app-switch)
|
|
186
186
|
const TOTP_STORAGE_KEY = 'fluxy_totp_setup';
|
|
187
187
|
|
|
188
188
|
function saveTotpState() {
|
|
189
189
|
try {
|
|
190
190
|
sessionStorage.setItem(TOTP_STORAGE_KEY, JSON.stringify({
|
|
191
191
|
secret: totpSecret, qrUri: totpQrUri, otpauthUri: totpOtpauthUri, phase: step3Phase,
|
|
192
|
+
// Also persist password fields so user doesn't re-type after returning
|
|
193
|
+
portalPass, portalPassConfirm,
|
|
192
194
|
}));
|
|
193
195
|
} catch {}
|
|
194
196
|
}
|
|
@@ -205,6 +207,7 @@ export default function OnboardWizard({ onComplete, isInitialSetup = false, onSa
|
|
|
205
207
|
setTotpEnabled(true);
|
|
206
208
|
setStep3Phase('totp-setup');
|
|
207
209
|
setStep(3);
|
|
210
|
+
if (saved.portalPass) { setPortalPass(saved.portalPass); setPortalPassConfirm(saved.portalPassConfirm || ''); }
|
|
208
211
|
return true;
|
|
209
212
|
}
|
|
210
213
|
} catch {}
|
|
@@ -2,6 +2,8 @@ import { useState, useRef, useEffect, type KeyboardEvent } from 'react';
|
|
|
2
2
|
import { Lock, LoaderCircle, ArrowRight, ArrowLeft, Shield, Check } from 'lucide-react';
|
|
3
3
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
4
4
|
|
|
5
|
+
const LOGIN_STORAGE_KEY = 'fluxy_login_totp';
|
|
6
|
+
|
|
5
7
|
interface Props {
|
|
6
8
|
onLogin: (token: string) => void;
|
|
7
9
|
totpEnabled?: boolean;
|
|
@@ -20,6 +22,21 @@ export default function LoginScreen({ onLogin, totpEnabled }: Props) {
|
|
|
20
22
|
const [useRecovery, setUseRecovery] = useState(false);
|
|
21
23
|
const totpInputRef = useRef<HTMLInputElement>(null);
|
|
22
24
|
|
|
25
|
+
// Restore TOTP phase after page reload (mobile: OS suspends PWA on app-switch)
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
try {
|
|
28
|
+
const raw = sessionStorage.getItem(LOGIN_STORAGE_KEY);
|
|
29
|
+
if (!raw) return;
|
|
30
|
+
const saved = JSON.parse(raw);
|
|
31
|
+
if (saved.pendingToken && saved.expiresAt > Date.now()) {
|
|
32
|
+
setPendingToken(saved.pendingToken);
|
|
33
|
+
setPhase('totp');
|
|
34
|
+
} else {
|
|
35
|
+
sessionStorage.removeItem(LOGIN_STORAGE_KEY);
|
|
36
|
+
}
|
|
37
|
+
} catch {}
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
23
40
|
// Auto-focus TOTP input when switching to TOTP phase
|
|
24
41
|
useEffect(() => {
|
|
25
42
|
if (phase === 'totp') {
|
|
@@ -27,6 +44,20 @@ export default function LoginScreen({ onLogin, totpEnabled }: Props) {
|
|
|
27
44
|
}
|
|
28
45
|
}, [phase]);
|
|
29
46
|
|
|
47
|
+
function saveLoginState(token: string) {
|
|
48
|
+
try {
|
|
49
|
+
// Pending token has 5min server expiry — save with matching client expiry
|
|
50
|
+
sessionStorage.setItem(LOGIN_STORAGE_KEY, JSON.stringify({
|
|
51
|
+
pendingToken: token,
|
|
52
|
+
expiresAt: Date.now() + 4.5 * 60 * 1000,
|
|
53
|
+
}));
|
|
54
|
+
} catch {}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function clearLoginState() {
|
|
58
|
+
try { sessionStorage.removeItem(LOGIN_STORAGE_KEY); } catch {}
|
|
59
|
+
}
|
|
60
|
+
|
|
30
61
|
const handleSubmit = async () => {
|
|
31
62
|
if (!password.trim() || loading) return;
|
|
32
63
|
setLoading(true);
|
|
@@ -41,9 +72,11 @@ export default function LoginScreen({ onLogin, totpEnabled }: Props) {
|
|
|
41
72
|
const data = await res.json();
|
|
42
73
|
|
|
43
74
|
if (res.ok && data.token) {
|
|
75
|
+
clearLoginState();
|
|
44
76
|
onLogin(data.token);
|
|
45
77
|
} else if (res.ok && data.requiresTOTP) {
|
|
46
78
|
setPendingToken(data.pendingToken);
|
|
79
|
+
saveLoginState(data.pendingToken);
|
|
47
80
|
setPhase('totp');
|
|
48
81
|
setError('');
|
|
49
82
|
} else {
|
|
@@ -69,6 +102,7 @@ export default function LoginScreen({ onLogin, totpEnabled }: Props) {
|
|
|
69
102
|
const data = await res.json();
|
|
70
103
|
|
|
71
104
|
if (res.ok && data.token) {
|
|
105
|
+
clearLoginState();
|
|
72
106
|
onLogin(data.token);
|
|
73
107
|
} else {
|
|
74
108
|
setError(data.error || 'Invalid code');
|
|
@@ -87,6 +121,14 @@ export default function LoginScreen({ onLogin, totpEnabled }: Props) {
|
|
|
87
121
|
}
|
|
88
122
|
};
|
|
89
123
|
|
|
124
|
+
const handleBackToPassword = () => {
|
|
125
|
+
setPhase('password');
|
|
126
|
+
setError('');
|
|
127
|
+
setTotpCode('');
|
|
128
|
+
setUseRecovery(false);
|
|
129
|
+
clearLoginState();
|
|
130
|
+
};
|
|
131
|
+
|
|
90
132
|
const inputCls = 'w-full bg-white/[0.05] border border-white/[0.08] text-white rounded-xl px-4 py-3 text-base outline-none input-glow placeholder:text-white/20 transition-all';
|
|
91
133
|
|
|
92
134
|
return (
|
|
@@ -183,6 +225,7 @@ export default function LoginScreen({ onLogin, totpEnabled }: Props) {
|
|
|
183
225
|
}}
|
|
184
226
|
onKeyDown={handleKeyDown}
|
|
185
227
|
placeholder={useRecovery ? 'Recovery code' : '000000'}
|
|
228
|
+
autoFocus
|
|
186
229
|
className={inputCls + (useRecovery ? '' : ' tracking-[0.3em] text-center font-mono')}
|
|
187
230
|
/>
|
|
188
231
|
|
|
@@ -215,7 +258,7 @@ export default function LoginScreen({ onLogin, totpEnabled }: Props) {
|
|
|
215
258
|
|
|
216
259
|
<div className="flex items-center gap-4 mt-4">
|
|
217
260
|
<button
|
|
218
|
-
onClick={
|
|
261
|
+
onClick={handleBackToPassword}
|
|
219
262
|
className="text-[12px] text-white/30 hover:text-white/50 flex items-center gap-1 transition-colors"
|
|
220
263
|
>
|
|
221
264
|
<ArrowLeft className="h-3 w-3" />
|