@better-forge/ui 0.0.0-stage → 0.1.0

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 (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -3
  3. package/dist/api/client.d.ts +42 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/client.js +130 -0
  6. package/dist/api/client.js.map +1 -0
  7. package/dist/components/ConfirmIdentityModal.d.ts +18 -0
  8. package/dist/components/ConfirmIdentityModal.d.ts.map +1 -0
  9. package/dist/components/ConfirmIdentityModal.js +30 -0
  10. package/dist/components/ConfirmIdentityModal.js.map +1 -0
  11. package/dist/components/ConfirmModal.d.ts +18 -0
  12. package/dist/components/ConfirmModal.d.ts.map +1 -0
  13. package/dist/components/ConfirmModal.js +11 -0
  14. package/dist/components/ConfirmModal.js.map +1 -0
  15. package/dist/components/CopyButton.d.ts +11 -0
  16. package/dist/components/CopyButton.d.ts.map +1 -0
  17. package/dist/components/CopyButton.js +44 -0
  18. package/dist/components/CopyButton.js.map +1 -0
  19. package/dist/components/CredentialSection.d.ts +38 -0
  20. package/dist/components/CredentialSection.d.ts.map +1 -0
  21. package/dist/components/CredentialSection.js +69 -0
  22. package/dist/components/CredentialSection.js.map +1 -0
  23. package/dist/components/ErrorBoundary.d.ts +18 -0
  24. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  25. package/dist/components/ErrorBoundary.js +25 -0
  26. package/dist/components/ErrorBoundary.js.map +1 -0
  27. package/dist/components/ModalShell.d.ts +58 -0
  28. package/dist/components/ModalShell.d.ts.map +1 -0
  29. package/dist/components/ModalShell.js +92 -0
  30. package/dist/components/ModalShell.js.map +1 -0
  31. package/dist/components/ResetTwoFactorModal.d.ts +14 -0
  32. package/dist/components/ResetTwoFactorModal.d.ts.map +1 -0
  33. package/dist/components/ResetTwoFactorModal.js +16 -0
  34. package/dist/components/ResetTwoFactorModal.js.map +1 -0
  35. package/dist/components/SidePanel.d.ts +35 -0
  36. package/dist/components/SidePanel.d.ts.map +1 -0
  37. package/dist/components/SidePanel.js +19 -0
  38. package/dist/components/SidePanel.js.map +1 -0
  39. package/dist/components/SingleSignOnModal.d.ts +4 -0
  40. package/dist/components/SingleSignOnModal.d.ts.map +1 -0
  41. package/dist/components/SingleSignOnModal.js +64 -0
  42. package/dist/components/SingleSignOnModal.js.map +1 -0
  43. package/dist/components/SsoConfirmation.d.ts +22 -0
  44. package/dist/components/SsoConfirmation.d.ts.map +1 -0
  45. package/dist/components/SsoConfirmation.js +87 -0
  46. package/dist/components/SsoConfirmation.js.map +1 -0
  47. package/dist/components/VaultTypePicker.d.ts +13 -0
  48. package/dist/components/VaultTypePicker.d.ts.map +1 -0
  49. package/dist/components/VaultTypePicker.js +62 -0
  50. package/dist/components/VaultTypePicker.js.map +1 -0
  51. package/dist/components/WhatsNew.d.ts +18 -0
  52. package/dist/components/WhatsNew.d.ts.map +1 -0
  53. package/dist/components/WhatsNew.js +50 -0
  54. package/dist/components/WhatsNew.js.map +1 -0
  55. package/dist/components/formParts.d.ts +40 -0
  56. package/dist/components/formParts.d.ts.map +1 -0
  57. package/dist/components/formParts.js +31 -0
  58. package/dist/components/formParts.js.map +1 -0
  59. package/dist/components/ui/Alert.d.ts +15 -0
  60. package/dist/components/ui/Alert.d.ts.map +1 -0
  61. package/dist/components/ui/Alert.js +14 -0
  62. package/dist/components/ui/Alert.js.map +1 -0
  63. package/dist/components/ui/DataTable.d.ts +52 -0
  64. package/dist/components/ui/DataTable.d.ts.map +1 -0
  65. package/dist/components/ui/DataTable.js +112 -0
  66. package/dist/components/ui/DataTable.js.map +1 -0
  67. package/dist/components/ui/Field.d.ts +27 -0
  68. package/dist/components/ui/Field.d.ts.map +1 -0
  69. package/dist/components/ui/Field.js +25 -0
  70. package/dist/components/ui/Field.js.map +1 -0
  71. package/dist/components/ui/PageHeader.d.ts +18 -0
  72. package/dist/components/ui/PageHeader.d.ts.map +1 -0
  73. package/dist/components/ui/PageHeader.js +10 -0
  74. package/dist/components/ui/PageHeader.js.map +1 -0
  75. package/dist/components/ui/Pagination.d.ts +21 -0
  76. package/dist/components/ui/Pagination.d.ts.map +1 -0
  77. package/dist/components/ui/Pagination.js +10 -0
  78. package/dist/components/ui/Pagination.js.map +1 -0
  79. package/dist/components/ui/QuickStartPanel.d.ts +21 -0
  80. package/dist/components/ui/QuickStartPanel.d.ts.map +1 -0
  81. package/dist/components/ui/QuickStartPanel.js +11 -0
  82. package/dist/components/ui/QuickStartPanel.js.map +1 -0
  83. package/dist/components/ui/StateViews.d.ts +50 -0
  84. package/dist/components/ui/StateViews.d.ts.map +1 -0
  85. package/dist/components/ui/StateViews.js +33 -0
  86. package/dist/components/ui/StateViews.js.map +1 -0
  87. package/dist/components/ui/Switch.d.ts +16 -0
  88. package/dist/components/ui/Switch.d.ts.map +1 -0
  89. package/dist/components/ui/Switch.js +15 -0
  90. package/dist/components/ui/Switch.js.map +1 -0
  91. package/dist/components/ui/Toast.d.ts +20 -0
  92. package/dist/components/ui/Toast.d.ts.map +1 -0
  93. package/dist/components/ui/Toast.js +46 -0
  94. package/dist/components/ui/Toast.js.map +1 -0
  95. package/dist/components/ui/index.d.ts +10 -0
  96. package/dist/components/ui/index.d.ts.map +1 -0
  97. package/dist/components/ui/index.js +10 -0
  98. package/dist/components/ui/index.js.map +1 -0
  99. package/dist/config.d.ts +46 -0
  100. package/dist/config.d.ts.map +1 -0
  101. package/dist/config.js +12 -0
  102. package/dist/config.js.map +1 -0
  103. package/dist/hooks/useDarkMode.d.ts +2 -0
  104. package/dist/hooks/useDarkMode.d.ts.map +1 -0
  105. package/dist/hooks/useDarkMode.js +37 -0
  106. package/dist/hooks/useDarkMode.js.map +1 -0
  107. package/dist/hooks/useDebouncedValue.d.ts +6 -0
  108. package/dist/hooks/useDebouncedValue.d.ts.map +1 -0
  109. package/dist/hooks/useDebouncedValue.js +19 -0
  110. package/dist/hooks/useDebouncedValue.js.map +1 -0
  111. package/dist/index.d.ts +36 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +36 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/lib/changelog.d.ts +32 -0
  116. package/dist/lib/changelog.d.ts.map +1 -0
  117. package/dist/lib/changelog.js +71 -0
  118. package/dist/lib/changelog.js.map +1 -0
  119. package/dist/lib/dateFormat.d.ts +24 -0
  120. package/dist/lib/dateFormat.d.ts.map +1 -0
  121. package/dist/lib/dateFormat.js +67 -0
  122. package/dist/lib/dateFormat.js.map +1 -0
  123. package/dist/navigation.d.ts +5 -0
  124. package/dist/navigation.d.ts.map +1 -0
  125. package/dist/navigation.js +7 -0
  126. package/dist/navigation.js.map +1 -0
  127. package/dist/pages/ApiTokens.d.ts +9 -0
  128. package/dist/pages/ApiTokens.d.ts.map +1 -0
  129. package/dist/pages/ApiTokens.js +116 -0
  130. package/dist/pages/ApiTokens.js.map +1 -0
  131. package/dist/pages/AuditLog.d.ts +14 -0
  132. package/dist/pages/AuditLog.d.ts.map +1 -0
  133. package/dist/pages/AuditLog.js +104 -0
  134. package/dist/pages/AuditLog.js.map +1 -0
  135. package/dist/pages/Backups.d.ts +2 -0
  136. package/dist/pages/Backups.d.ts.map +1 -0
  137. package/dist/pages/Backups.js +118 -0
  138. package/dist/pages/Backups.js.map +1 -0
  139. package/dist/pages/ChangePassword.d.ts +2 -0
  140. package/dist/pages/ChangePassword.d.ts.map +1 -0
  141. package/dist/pages/ChangePassword.js +40 -0
  142. package/dist/pages/ChangePassword.js.map +1 -0
  143. package/dist/pages/Login.d.ts +12 -0
  144. package/dist/pages/Login.d.ts.map +1 -0
  145. package/dist/pages/Login.js +69 -0
  146. package/dist/pages/Login.js.map +1 -0
  147. package/dist/pages/Settings.d.ts +2 -0
  148. package/dist/pages/Settings.d.ts.map +1 -0
  149. package/dist/pages/Settings.js +149 -0
  150. package/dist/pages/Settings.js.map +1 -0
  151. package/dist/pages/Setup.d.ts +2 -0
  152. package/dist/pages/Setup.d.ts.map +1 -0
  153. package/dist/pages/Setup.js +113 -0
  154. package/dist/pages/Setup.js.map +1 -0
  155. package/dist/pages/SsoConfirm.d.ts +3 -0
  156. package/dist/pages/SsoConfirm.d.ts.map +1 -0
  157. package/dist/pages/SsoConfirm.js +20 -0
  158. package/dist/pages/SsoConfirm.js.map +1 -0
  159. package/dist/pages/SsoTestResult.d.ts +2 -0
  160. package/dist/pages/SsoTestResult.d.ts.map +1 -0
  161. package/dist/pages/SsoTestResult.js +49 -0
  162. package/dist/pages/SsoTestResult.js.map +1 -0
  163. package/dist/pages/Users.d.ts +22 -0
  164. package/dist/pages/Users.d.ts.map +1 -0
  165. package/dist/pages/Users.js +124 -0
  166. package/dist/pages/Users.js.map +1 -0
  167. package/dist/pages/Vault.d.ts +2 -0
  168. package/dist/pages/Vault.d.ts.map +1 -0
  169. package/dist/pages/Vault.js +372 -0
  170. package/dist/pages/Vault.js.map +1 -0
  171. package/dist/shell/AdminShell.d.ts +46 -0
  172. package/dist/shell/AdminShell.d.ts.map +1 -0
  173. package/dist/shell/AdminShell.js +76 -0
  174. package/dist/shell/AdminShell.js.map +1 -0
  175. package/dist/shell/guards.d.ts +28 -0
  176. package/dist/shell/guards.d.ts.map +1 -0
  177. package/dist/shell/guards.js +71 -0
  178. package/dist/shell/guards.js.map +1 -0
  179. package/icons.json +170 -0
  180. package/package.json +71 -6
  181. package/src/api/client.ts +139 -0
  182. package/src/components/ConfirmIdentityModal.tsx +82 -0
  183. package/src/components/ConfirmModal.tsx +83 -0
  184. package/src/components/CopyButton.tsx +71 -0
  185. package/src/components/CredentialSection.tsx +270 -0
  186. package/src/components/ErrorBoundary.tsx +47 -0
  187. package/src/components/ModalShell.tsx +160 -0
  188. package/src/components/ResetTwoFactorModal.tsx +74 -0
  189. package/src/components/SidePanel.tsx +96 -0
  190. package/src/components/SingleSignOnModal.tsx +161 -0
  191. package/src/components/SsoConfirmation.tsx +96 -0
  192. package/src/components/VaultTypePicker.tsx +131 -0
  193. package/src/components/WhatsNew.tsx +84 -0
  194. package/src/components/formParts.tsx +59 -0
  195. package/src/components/ui/Alert.tsx +45 -0
  196. package/src/components/ui/DataTable.tsx +225 -0
  197. package/src/components/ui/Field.tsx +63 -0
  198. package/src/components/ui/PageHeader.tsx +36 -0
  199. package/src/components/ui/Pagination.tsx +37 -0
  200. package/src/components/ui/QuickStartPanel.tsx +57 -0
  201. package/src/components/ui/StateViews.tsx +135 -0
  202. package/src/components/ui/Switch.tsx +65 -0
  203. package/src/components/ui/Toast.tsx +104 -0
  204. package/src/components/ui/index.ts +9 -0
  205. package/src/config.ts +46 -0
  206. package/src/hooks/useDarkMode.ts +38 -0
  207. package/src/hooks/useDebouncedValue.ts +22 -0
  208. package/src/index.ts +42 -0
  209. package/src/lib/changelog.ts +93 -0
  210. package/src/lib/dateFormat.ts +90 -0
  211. package/src/navigation.ts +6 -0
  212. package/src/pages/ApiTokens.tsx +361 -0
  213. package/src/pages/AuditLog.tsx +388 -0
  214. package/src/pages/Backups.tsx +170 -0
  215. package/src/pages/ChangePassword.tsx +84 -0
  216. package/src/pages/Login.tsx +275 -0
  217. package/src/pages/Settings.tsx +264 -0
  218. package/src/pages/Setup.tsx +438 -0
  219. package/src/pages/SsoConfirm.tsx +26 -0
  220. package/src/pages/SsoTestResult.tsx +104 -0
  221. package/src/pages/Users.tsx +426 -0
  222. package/src/pages/Vault.tsx +1036 -0
  223. package/src/shell/AdminShell.tsx +256 -0
  224. package/src/shell/guards.tsx +88 -0
  225. package/styles/base.css +521 -0
  226. package/styles/fonts/inter-latin-1.woff2 +0 -0
  227. package/styles/fonts/inter-latin-ext.woff2 +0 -0
  228. package/styles/fonts/jetbrains-mono-latin-3.woff2 +0 -0
  229. package/styles/fonts/jetbrains-mono-latin-ext-2.woff2 +0 -0
  230. package/styles/fonts/manrope-latin-5.woff2 +0 -0
  231. package/styles/fonts/manrope-latin-ext-4.woff2 +0 -0
  232. package/styles/fonts/material-symbols-outlined-fill.woff2 +0 -0
  233. package/styles/icons.css +4 -0
  234. package/tailwind-preset.js +79 -0
@@ -0,0 +1,118 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useId, useRef, useState } from 'react';
3
+ import { api } from '../api/client';
4
+ import { ConfirmModal } from '../components/ConfirmModal';
5
+ import { Alert, EmptyState, EmptyStateLink, ErrorState, LoadingState, PageContainer, PageHeader, Switch } from '../components/ui';
6
+ import { formatDateTime } from '../lib/dateFormat';
7
+ const WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
8
+ const errorText = (e) => e instanceof Error ? e.message : String(e);
9
+ export default function BackupsPage() {
10
+ const [state, setState] = useState(null);
11
+ const [loadError, setLoadError] = useState('');
12
+ const [busy, setBusy] = useState(null);
13
+ const [message, setMessage] = useState(null);
14
+ const [deleteTarget, setDeleteTarget] = useState(null);
15
+ const [savedConfig, setSavedConfig] = useState(null);
16
+ const file = useRef(null);
17
+ const scheduleSwitchId = useId();
18
+ const load = useCallback(() => api.get('/admin/backups')
19
+ .then((data) => { setState(data); setSavedConfig(data.config); setLoadError(''); })
20
+ .catch((e) => setLoadError(errorText(e))), []);
21
+ useEffect(() => { void load(); }, [load]);
22
+ async function create() {
23
+ setBusy('create');
24
+ setMessage(null);
25
+ try {
26
+ await api.post('/admin/backups', {});
27
+ await load();
28
+ setMessage({ tone: 'success', text: 'Backup created successfully.' });
29
+ }
30
+ catch (e) {
31
+ setMessage({ tone: 'error', text: errorText(e) });
32
+ }
33
+ finally {
34
+ setBusy(null);
35
+ }
36
+ }
37
+ async function saveConfig(config) {
38
+ setBusy('save');
39
+ setMessage(null);
40
+ try {
41
+ const saved = await api.put('/admin/backups/config', config);
42
+ setState((s) => s && ({ ...s, config: saved }));
43
+ setSavedConfig(saved);
44
+ setMessage({ tone: 'success', text: 'Schedule saved.' });
45
+ }
46
+ catch (e) {
47
+ setMessage({ tone: 'error', text: errorText(e) });
48
+ }
49
+ finally {
50
+ setBusy(null);
51
+ }
52
+ }
53
+ async function validate(selected) {
54
+ setBusy('validate');
55
+ setMessage(null);
56
+ const form = new FormData();
57
+ form.append('file', selected);
58
+ try {
59
+ const result = await api.upload('/admin/backups/validate', form);
60
+ const keyMismatch = result.vaultKeyMatches === false;
61
+ const key = keyMismatch ? ' Warning: VAULT_ENCRYPTION_KEY does not match.' : '';
62
+ setMessage({ tone: keyMismatch ? 'warning' : 'success', text: `Backup is valid (${formatDateTime(result.manifest.createdAt)}).${key} Stop the app and run: npm run restore -- --input <file>` });
63
+ }
64
+ catch (e) {
65
+ setMessage({ tone: 'error', text: errorText(e) });
66
+ }
67
+ finally {
68
+ setBusy(null);
69
+ if (file.current)
70
+ file.current.value = '';
71
+ }
72
+ }
73
+ async function removeBackup(filename) {
74
+ setBusy('delete');
75
+ setMessage(null);
76
+ try {
77
+ await api.delete(`/admin/backups/${encodeURIComponent(filename)}?confirm=${encodeURIComponent(filename)}`);
78
+ setDeleteTarget(null);
79
+ await load();
80
+ setMessage({ tone: 'success', text: 'Backup deleted.' });
81
+ }
82
+ catch (e) {
83
+ setDeleteTarget(null);
84
+ setMessage({ tone: 'error', text: errorText(e) });
85
+ }
86
+ finally {
87
+ setBusy(null);
88
+ }
89
+ }
90
+ const header = _jsx(PageHeader, { title: "Backups", subtitle: "Create, download, validate and schedule complete application backups." });
91
+ if (!state && loadError)
92
+ return _jsxs(PageContainer, { children: [header, _jsx(ErrorState, { message: loadError, onRetry: () => void load() })] });
93
+ if (!state)
94
+ return _jsxs(PageContainer, { children: [header, _jsx(LoadingState, { label: "Loading backups\u2026" })] });
95
+ const config = state.config;
96
+ const scheduleChanged = JSON.stringify(config) !== JSON.stringify(savedConfig);
97
+ const scheduleSummary = config.enabled
98
+ ? `${config.frequency === 'daily' ? 'Every day' : `Every ${WEEKDAYS[config.weekday]}`} at ${String(config.hour).padStart(2, '0')}:${String(config.minute).padStart(2, '0')} · keep ${config.retention} ${config.retention === 1 ? 'backup' : 'backups'}`
99
+ : 'Automatic backups are disabled';
100
+ const updateConfig = (updates) => setState({ ...state, config: { ...config, ...updates } });
101
+ // Turns the switch on and moves focus to it; the schedule is still saved with "Save schedule".
102
+ const enableAutomaticBackups = () => {
103
+ updateConfig({ enabled: true });
104
+ document.getElementById(scheduleSwitchId)?.focus();
105
+ };
106
+ return _jsxs(PageContainer, { children: [header, message && _jsx(Alert, { tone: message.tone, onDismiss: () => setMessage(null), children: message.text }), state.status.lastCompletedAt && _jsxs("div", { className: "text-sm", style: { color: state.status.state === 'error' ? 'var(--m3-down)' : 'var(--m3-secondary)' }, children: ["Last run: ", formatDateTime(state.status.lastCompletedAt), " \u00B7 ", state.status.state, state.status.lastError ? ` · ${state.status.lastError}` : ''] }), _jsxs("section", { className: "rounded-2xl p-6 space-y-4", style: { background: 'var(--m3-surface-container-lowest)', color: 'var(--m3-on-surface)' }, children: [_jsxs("div", { className: "flex flex-wrap gap-3", children: [_jsx("button", { type: "button", disabled: busy !== null, onClick: create, className: "btn btn-primary", children: busy === 'create' ? 'Creating backup…' : 'Create backup' }), _jsx("button", { type: "button", disabled: busy !== null, onClick: () => file.current?.click(), className: "btn btn-secondary", children: busy === 'validate' ? 'Validating…' : 'Validate restore file' }), _jsx("input", { ref: file, className: "hidden", type: "file", accept: ".backup", "aria-label": "Restore file", onChange: (e) => { const selected = e.target.files?.[0]; if (selected)
107
+ void validate(selected); } })] }), _jsx("p", { className: "text-sm", style: { color: 'var(--m3-secondary)' }, children: "Restore is intentionally offline. The encryption key is never included; keep VAULT_ENCRYPTION_KEY separately." })] }), _jsxs("section", { className: "rounded-2xl overflow-hidden", style: { background: 'var(--m3-surface-container-lowest)', border: '1px solid var(--m3-outline-variant)', color: 'var(--m3-on-surface)' }, children: [_jsxs("div", { className: "p-5 md:p-6 flex items-start justify-between gap-5", children: [_jsxs("div", { className: "flex gap-4 min-w-0", children: [_jsx("span", { className: "material-symbols-outlined rounded-xl p-2.5 h-fit", "aria-hidden": "true", style: { background: 'var(--admin-icon-container)', color: 'var(--admin-icon-color)' }, children: "schedule" }), _jsxs("div", { children: [_jsx("h2", { className: "font-headline text-xl font-semibold", children: "Automatic backups" }), _jsx("p", { className: "text-sm mt-1", style: { color: 'var(--m3-secondary)' }, children: "Create backups on a recurring schedule using the server's local time." })] })] }), _jsx(Switch, { id: scheduleSwitchId, checked: config.enabled, onChange: (enabled) => updateConfig({ enabled }), "aria-label": "Automatic backups" })] }), _jsxs("div", { className: "px-5 pb-5 md:px-6 md:pb-6", children: [config.enabled ? (_jsxs("div", { className: "rounded-2xl p-4 md:p-5 grid gap-5 md:grid-cols-3", style: { background: 'var(--m3-surface-container-low)' }, children: [_jsxs("fieldset", { children: [_jsx("legend", { className: "font-mono text-xs uppercase tracking-wider mb-2", style: { color: 'var(--m3-secondary)' }, children: "Frequency" }), _jsx("div", { className: "grid grid-cols-2 rounded-xl overflow-hidden", style: { border: '1px solid var(--m3-outline-variant)' }, children: ['daily', 'weekly'].map((frequency) => {
108
+ const active = config.frequency === frequency;
109
+ return (_jsx("button", { type: "button", "aria-pressed": active, onClick: () => updateConfig({ frequency }), className: `px-3 py-2 text-sm font-semibold transition-colors focus-ring ${active ? 'selection-active' : ''}`, style: { background: 'transparent', color: 'var(--m3-secondary)' }, children: frequency === 'daily' ? 'Daily' : 'Weekly' }, frequency));
110
+ }) })] }), config.frequency === 'weekly' && _jsxs("label", { children: [_jsx("span", { className: "block font-mono text-xs uppercase tracking-wider mb-2", style: { color: 'var(--m3-secondary)' }, children: "Day of week" }), _jsx("select", { className: "input-sig w-full", value: config.weekday, onChange: (e) => updateConfig({ weekday: Number(e.target.value) }), children: WEEKDAYS.map((day, index) => _jsx("option", { value: index, children: day }, day)) })] }), _jsxs("label", { children: [_jsx("span", { className: "block font-mono text-xs uppercase tracking-wider mb-2", style: { color: 'var(--m3-secondary)' }, children: "Start time" }), _jsx("input", { className: "input-sig w-full", type: "time", step: "60", value: `${String(config.hour).padStart(2, '0')}:${String(config.minute).padStart(2, '0')}`, onChange: (e) => { const parts = e.target.value.split(':'); const hour = Number(parts[0]); const minute = Number(parts[1]); if (parts.length === 2 && Number.isInteger(hour) && Number.isInteger(minute))
111
+ updateConfig({ hour, minute }); } }), _jsx("span", { className: "block text-xs mt-1.5", style: { color: 'var(--m3-secondary)' }, children: "Server local time" })] }), _jsxs("label", { children: [_jsx("span", { className: "block font-mono text-xs uppercase tracking-wider mb-2", style: { color: 'var(--m3-secondary)' }, children: "Retention" }), _jsxs("div", { className: "relative", children: [_jsx("input", { className: "input-sig w-full pr-24", type: "number", min: "1", max: "365", value: config.retention, onChange: (e) => updateConfig({ retention: Number(e.target.value) }) }), _jsx("span", { className: "absolute right-3 top-1/2 -translate-y-1/2 text-sm", "aria-hidden": "true", style: { color: 'var(--m3-secondary)' }, children: "backups" })] }), _jsx("span", { className: "block text-xs mt-1.5", style: { color: 'var(--m3-secondary)' }, children: "Older automatic backups are removed after a successful run." })] })] })) : _jsxs("div", { className: "rounded-xl px-4 py-3 text-sm flex items-center gap-3", style: { background: 'var(--m3-surface-container-low)', color: 'var(--m3-secondary)' }, children: [_jsx("span", { className: "material-symbols-outlined", "aria-hidden": "true", style: { fontSize: '20px' }, children: "info" }), "Enable scheduling to configure recurring backups."] }), _jsxs("div", { className: "mt-5 pt-5 flex flex-col sm:flex-row sm:items-center justify-between gap-4", style: { borderTop: '1px solid var(--m3-outline-variant)' }, children: [_jsxs("div", { children: [_jsx("p", { className: "text-xs font-mono uppercase tracking-wider", style: { color: 'var(--m3-secondary)' }, children: "Current schedule" }), _jsx("p", { className: "text-sm font-medium mt-1", children: scheduleSummary })] }), _jsx("button", { type: "button", disabled: busy !== null || !scheduleChanged, onClick: () => saveConfig(config), className: "btn btn-primary", children: busy === 'save' ? 'Saving…' : scheduleChanged ? 'Save schedule' : 'Saved' })] })] })] }), _jsxs("section", { className: "rounded-2xl overflow-hidden", style: { background: 'var(--m3-surface-container-lowest)', color: 'var(--m3-on-surface)' }, children: [_jsx("h2", { className: "font-headline text-xl font-semibold p-6 pb-3", children: "Available backups" }), state.backups.length === 0
112
+ ? _jsx(EmptyState, { variant: "inset", icon: "cloud_off", title: "No backups yet", description: savedConfig?.enabled
113
+ ? 'Automatic backups are on; the first one will appear here after it runs.'
114
+ : 'Automatic backups are off. The database is not protected until the first backup exists.', action: config.enabled ? undefined : _jsx(EmptyStateLink, { onClick: enableAutomaticBackups, children: "Enable automatic backups" }) })
115
+ : state.backups.map((item) => _jsxs("div", { className: "p-4 px-6 flex flex-wrap items-center justify-between gap-3", style: { borderTop: '1px solid var(--m3-outline-variant)' }, children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "font-mono text-sm break-all", children: item.filename }), _jsxs("div", { className: "text-xs", style: { color: 'var(--m3-secondary)' }, children: [formatDateTime(item.createdAt), " \u00B7 ", (item.size / 1024 / 1024).toFixed(2), " MB"] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { type: "button", onClick: () => api.download(`/admin/backups/${encodeURIComponent(item.filename)}/download`, item.filename), "aria-label": `Download ${item.filename}`, className: "btn btn-secondary btn-sm", children: "Download" }), _jsx("button", { type: "button", onClick: () => setDeleteTarget(item.filename), "aria-label": `Delete ${item.filename}`, className: "btn btn-danger-outline btn-sm", children: "Delete" })] })] }, item.filename))] }), deleteTarget && _jsx(ConfirmModal, { title: "Delete backup", message: "This permanently deletes the backup archive. This action cannot be undone.", confirmLabel: "Delete backup", confirmationText: deleteTarget, pending: busy === 'delete', pendingLabel: "Deleting\u2026", onConfirm: () => { if (!busy)
116
+ void removeBackup(deleteTarget); }, onCancel: () => setDeleteTarget(null) })] });
117
+ }
118
+ //# sourceMappingURL=Backups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Backups.js","sourceRoot":"","sources":["../../src/pages/Backups.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default function ChangePasswordPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=ChangePassword.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChangePassword.d.ts","sourceRoot":"","sources":["../../src/pages/ChangePassword.tsx"],"names":[],"mappings":"AAKA,MAAM,CAAC,OAAO,UAAU,kBAAkB,gCA8EzC"}
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useNavigate } from 'react-router-dom';
4
+ import { api, enterAfterSignIn, getCurrentUser, setSession } from '../api/client';
5
+ import { Alert, Field } from '../components/ui';
6
+ export default function ChangePasswordPage() {
7
+ const navigate = useNavigate();
8
+ const [password, setPassword] = useState('');
9
+ const [confirm, setConfirm] = useState('');
10
+ const [loading, setLoading] = useState(false);
11
+ const [error, setError] = useState('');
12
+ async function handleSubmit(e) {
13
+ e.preventDefault();
14
+ if (password !== confirm) {
15
+ setError('Passwords do not match');
16
+ return;
17
+ }
18
+ if (password.length < 8) {
19
+ setError('Password must be at least 8 characters');
20
+ return;
21
+ }
22
+ setError('');
23
+ setLoading(true);
24
+ try {
25
+ const res = await api.post('/auth/change-password', { newPassword: password });
26
+ setSession(res);
27
+ enterAfterSignIn(res, navigate);
28
+ }
29
+ catch (err) {
30
+ setError(err instanceof Error ? err.message : 'Failed to change password');
31
+ }
32
+ finally {
33
+ setLoading(false);
34
+ }
35
+ }
36
+ return (_jsx("div", { className: "min-h-screen flex items-center justify-center p-4", style: { background: 'var(--m3-surface)' }, children: _jsx("div", { className: "w-full max-w-sm", children: _jsxs("div", { className: "rounded-2xl p-8", style: { background: 'var(--m3-surface-container-low)', border: '1px solid var(--m3-outline-variant)' }, children: [_jsxs("div", { className: "mb-6", children: [_jsx("div", { className: "w-12 h-12 rounded-2xl flex items-center justify-center mb-4", style: { background: 'var(--m3-on-surface)' }, children: _jsx("span", { className: "material-symbols-outlined", "aria-hidden": "true", style: { color: 'var(--m3-surface)', fontSize: '22px' }, children: "lock_reset" }) }), _jsx("h1", { className: "font-headline font-bold text-2xl", style: { color: 'var(--m3-on-surface)' }, children: "Set your password" }), _jsx("p", { className: "text-sm mt-1", style: { color: 'var(--m3-secondary)' }, children: getCurrentUser()?.authMethod === 'oidc'
37
+ ? 'Password sign-in is enabled, so set your own password to replace the temporary one before continuing.'
38
+ : 'You must change your temporary password before continuing.' })] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [error && _jsx(Alert, { tone: "error", children: error }), _jsx(Field, { label: "New Password", hint: "Minimum 8 characters", children: _jsx("input", { type: "password", autoComplete: "new-password", value: password, onChange: (e) => setPassword(e.target.value), required: true, minLength: 8, className: "input-sig w-full", placeholder: "Minimum 8 characters", autoFocus: true }) }), _jsx(Field, { label: "Confirm Password", children: _jsx("input", { type: "password", autoComplete: "new-password", value: confirm, onChange: (e) => setConfirm(e.target.value), required: true, className: "input-sig w-full", placeholder: "Repeat the password" }) }), _jsx("button", { type: "submit", disabled: loading, className: "btn btn-primary w-full py-3 font-headline font-bold", children: loading ? 'Saving…' : 'Set Password & Continue' })] })] }) }) }));
39
+ }
40
+ //# sourceMappingURL=ChangePassword.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChangePassword.js","sourceRoot":"","sources":["../../src/pages/ChangePassword.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type ReactNode } from 'react';
2
+ /** What the sign-in page says about the product beside the form. */
3
+ export interface LoginPageProps {
4
+ headline: ReactNode;
5
+ tagline: string;
6
+ features: ReadonlyArray<{
7
+ icon: string;
8
+ label: string;
9
+ }>;
10
+ }
11
+ export default function LoginPage({ headline, tagline, features }: LoginPageProps): import("react").JSX.Element;
12
+ //# sourceMappingURL=Login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Login.d.ts","sourceRoot":"","sources":["../../src/pages/Login.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAkB3D,oEAAoE;AACpE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,SAAS,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACzD;AAED,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,cAAc,+BAyPhF"}
@@ -0,0 +1,69 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { useNavigate, useSearchParams } from 'react-router-dom';
4
+ import { api, enterAfterSignIn, setSession } from '../api/client';
5
+ import { uiConfig } from '../config';
6
+ import { useDarkMode } from '../hooks/useDarkMode';
7
+ import { Alert } from '../components/ui';
8
+ const SSO_ERRORS = {
9
+ oidc_failed: 'Single sign-on failed. Try again or contact an administrator.',
10
+ oidc_no_account: 'No account matches your single sign-on identity. Ask an administrator to create one.',
11
+ };
12
+ export default function LoginPage({ headline, tagline, features }) {
13
+ const navigate = useNavigate();
14
+ const [isDark, toggleDark] = useDarkMode();
15
+ const [email, setEmail] = useState('');
16
+ const [password, setPassword] = useState('');
17
+ const [code, setCode] = useState('');
18
+ const [challengeToken, setChallengeToken] = useState('');
19
+ const [error, setError] = useState('');
20
+ const [loading, setLoading] = useState(false);
21
+ const [showPassword, setShowPassword] = useState(false);
22
+ const [searchParams] = useSearchParams();
23
+ // An SSO sign-in of a user with 2FA comes back here for the code; the server holds the challenge in a cookie.
24
+ const [ssoChallenge, setSsoChallenge] = useState(searchParams.get('two-factor') === 'sso');
25
+ const codeStep = !!challengeToken || ssoChallenge;
26
+ const [authConfig, setAuthConfig] = useState({ passwordLogin: true, oidc: null });
27
+ const ssoError = SSO_ERRORS[searchParams.get('error') ?? ''];
28
+ useEffect(() => {
29
+ api.get('/auth/config').then(setAuthConfig).catch(() => { });
30
+ }, []);
31
+ async function handleSubmit(e) {
32
+ e.preventDefault();
33
+ setError('');
34
+ setLoading(true);
35
+ try {
36
+ if (codeStep) {
37
+ const user = await api.post('/auth/2fa/verify', challengeToken ? { challengeToken, code } : { code });
38
+ setSession(user);
39
+ enterAfterSignIn(user, navigate);
40
+ }
41
+ else {
42
+ const res = await api.post('/auth/login', { email, password });
43
+ if ('requiresTwoFactor' in res) {
44
+ setChallengeToken(res.challengeToken);
45
+ setPassword('');
46
+ }
47
+ else {
48
+ setSession(res);
49
+ enterAfterSignIn(res, navigate);
50
+ }
51
+ }
52
+ }
53
+ catch (err) {
54
+ setError(err instanceof Error ? err.message : 'Login failed');
55
+ }
56
+ finally {
57
+ setLoading(false);
58
+ }
59
+ }
60
+ return (_jsxs("div", { className: "min-h-screen flex", style: { background: 'var(--m3-surface)' }, children: [_jsxs("div", { className: "hidden lg:flex flex-col justify-between w-[400px] flex-shrink-0 p-12 relative overflow-hidden", style: {
61
+ background: 'var(--m3-surface-container-low)',
62
+ borderRight: '1px solid var(--m3-outline-variant)',
63
+ }, children: [_jsx("div", { className: "absolute -top-32 -left-32 w-80 h-80 rounded-full pointer-events-none", style: { background: 'radial-gradient(circle, color-mix(in srgb, var(--m3-primary) 12%, transparent) 0%, transparent 70%)' } }), _jsx("div", { className: "absolute bottom-0 right-0 w-96 h-96 rounded-full pointer-events-none", style: { background: 'radial-gradient(circle, color-mix(in srgb, var(--m3-primary) 6%, transparent) 0%, transparent 70%)' } }), _jsx("div", { className: "relative flex justify-center", children: _jsx("img", { src: isDark ? uiConfig().brand.logoDark : uiConfig().brand.logoLight, alt: uiConfig().brand.name, style: { height: '160px', objectFit: 'contain' } }) }), _jsxs("div", { className: "relative space-y-4", children: [_jsx("h2", { className: "font-headline font-extrabold text-4xl leading-[1.1] tracking-tight", style: { color: 'var(--m3-on-surface)' }, children: headline }), _jsx("p", { className: "text-base font-sans leading-relaxed", style: { color: 'var(--m3-secondary)' }, children: tagline })] }), _jsx("ul", { className: "relative space-y-3", children: features.map((feature) => (_jsxs("li", { className: "flex items-center gap-3 text-sm font-sans", style: { color: 'var(--m3-on-surface-variant)' }, children: [_jsx("span", { className: "material-symbols-outlined rounded-lg p-1.5", "aria-hidden": "true", style: { fontSize: '18px', background: 'var(--admin-icon-container)', color: 'var(--admin-icon-color)' }, children: feature.icon }), feature.label] }, feature.label))) })] }), _jsxs("div", { className: "flex-1 relative flex items-center justify-center px-6 py-12", children: [_jsx("button", { type: "button", onClick: toggleDark, className: "btn-icon absolute top-5 right-5 w-9 h-9 rounded-full", "aria-label": "Toggle dark mode", children: _jsx("span", { className: "material-symbols-outlined", "aria-hidden": "true", children: isDark ? 'light_mode' : 'dark_mode' }) }), _jsxs("div", { className: "w-full max-w-[400px]", children: [_jsx("div", { className: "flex justify-center mb-8 lg:hidden", children: _jsx("img", { src: isDark ? uiConfig().brand.logoDark : uiConfig().brand.logoLight, alt: uiConfig().brand.name, style: { height: '32px', objectFit: 'contain' } }) }), _jsxs("div", { className: "rounded-[20px] px-6 py-8 md:px-9 md:pt-9 md:pb-8", style: {
64
+ background: 'var(--m3-surface-container-lowest)',
65
+ border: '1px solid var(--m3-outline-variant)',
66
+ boxShadow: '0 1px 2px rgba(19,27,46,0.04), 0 16px 40px rgba(19,27,46,0.06)',
67
+ }, children: [_jsxs("div", { className: "mb-8", children: [_jsx("h1", { className: "font-headline font-bold text-2xl", style: { color: 'var(--m3-on-surface)' }, children: "Welcome back" }), _jsx("p", { className: "text-sm font-sans mt-1.5", style: { color: 'var(--m3-secondary)' }, children: "Sign in to your admin panel" })] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [(error || ssoError) && _jsx(Alert, { tone: "error", children: error || ssoError }), authConfig.oidc && !codeStep && (_jsxs("a", { href: authConfig.oidc.loginUrl ?? '/api/v1/auth/oidc/login', className: "btn btn-primary w-full h-12 font-headline font-bold text-[15px]", children: [_jsx("span", { className: "material-symbols-outlined", "aria-hidden": "true", style: { fontSize: '20px' }, children: "key" }), authConfig.oidc.label] })), authConfig.oidc && authConfig.passwordLogin && !codeStep && (_jsxs("div", { className: "flex items-center gap-3 text-xs font-sans", style: { color: 'var(--m3-secondary)' }, children: [_jsx("span", { className: "flex-1 h-px", style: { background: 'var(--m3-outline-variant)' } }), "or with email", _jsx("span", { className: "flex-1 h-px", style: { background: 'var(--m3-outline-variant)' } })] })), (authConfig.passwordLogin || codeStep) && _jsxs(_Fragment, { children: [!codeStep && _jsxs("div", { children: [_jsx("label", { htmlFor: "login-email", className: "block text-[13px] font-sans font-semibold mb-1.5", style: { color: 'var(--m3-on-surface-variant)' }, children: "Email" }), _jsx("input", { id: "login-email", type: "email", autoComplete: "username", value: email, onChange: (e) => setEmail(e.target.value), required: true, className: "input-m3", placeholder: "name@company.com" })] }), !codeStep && _jsxs("div", { children: [_jsx("label", { htmlFor: "login-password", className: "block text-[13px] font-sans font-semibold mb-1.5", style: { color: 'var(--m3-on-surface-variant)' }, children: "Password" }), _jsxs("div", { className: "relative", children: [_jsx("input", { id: "login-password", type: showPassword ? 'text' : 'password', autoComplete: "current-password", value: password, onChange: (e) => setPassword(e.target.value), required: true, className: "input-m3", style: { paddingRight: '44px' } }), _jsx("button", { type: "button", onClick: () => setShowPassword((shown) => !shown), className: "btn-icon absolute right-1 top-1/2 -translate-y-1/2 w-9 h-9 rounded-lg", "aria-label": showPassword ? 'Hide password' : 'Show password', "aria-pressed": showPassword, children: _jsx("span", { className: "material-symbols-outlined", "aria-hidden": "true", style: { fontSize: '20px' }, children: showPassword ? 'visibility_off' : 'visibility' }) })] })] }), codeStep && (_jsxs("div", { children: [_jsx("label", { htmlFor: "login-two-factor-code", className: "block text-[13px] font-sans font-semibold mb-1.5", style: { color: 'var(--m3-on-surface-variant)' }, children: "Authentication code" }), _jsx("input", { id: "login-two-factor-code", type: "text", autoComplete: "one-time-code", value: code, onChange: (e) => setCode(e.target.value), required: true, autoFocus: true, className: "input-m3", placeholder: "6-digit code or recovery code" }), _jsx("button", { type: "button", className: "text-xs mt-2 rounded focus-ring hover:underline", style: { color: 'var(--m3-secondary)' }, onClick: () => { setChallengeToken(''); setSsoChallenge(false); setCode(''); }, children: "Back to sign-in" })] })), _jsx("button", { type: "submit", disabled: loading, className: `btn ${authConfig.oidc && !codeStep ? 'btn-secondary h-11' : 'btn-primary h-12'} w-full mt-2 font-headline font-bold`, children: loading ? 'Signing in…' : codeStep ? 'Verify & sign in' : 'Sign in' })] })] })] })] })] })] }));
68
+ }
69
+ //# sourceMappingURL=Login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Login.js","sourceRoot":"","sources":["../../src/pages/Login.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default function SettingsPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=Settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Settings.d.ts","sourceRoot":"","sources":["../../src/pages/Settings.tsx"],"names":[],"mappings":"AAiBA,MAAM,CAAC,OAAO,UAAU,YAAY,gCAoOnC"}
@@ -0,0 +1,149 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useNavigate } from 'react-router-dom';
4
+ import { api, clearSession, getCurrentUser, setSession } from '../api/client';
5
+ import { uiConfig } from '../config';
6
+ import { ConfirmModal } from '../components/ConfirmModal';
7
+ import { CopyButton } from '../components/CopyButton';
8
+ import { SsoConfirmationNote, isSsoSession, useSsoConfirmation } from '../components/SsoConfirmation';
9
+ import { Alert, PageContainer, PageHeader } from '../components/ui';
10
+ import { DATE_FORMATS, TIME_FORMATS, formatDateTime, setDatePrefs, useDatePrefs } from '../lib/dateFormat';
11
+ export default function SettingsPage() {
12
+ const datePrefs = useDatePrefs();
13
+ const navigate = useNavigate();
14
+ const currentUser = getCurrentUser();
15
+ // An SSO session confirms these actions at the identity provider instead of with a password.
16
+ const sso = isSsoSession();
17
+ const confirmation = useSsoConfirmation();
18
+ const [current, setCurrent] = useState('');
19
+ const [password, setPassword] = useState('');
20
+ const [confirm, setConfirm] = useState('');
21
+ const [securityPassword, setSecurityPassword] = useState('');
22
+ const [code, setCode] = useState('');
23
+ const [twoFactorEnabled, setTwoFactorEnabled] = useState(!!currentUser?.twoFactorEnabled);
24
+ const [setup, setSetup] = useState(null);
25
+ const [recoveryCodes, setRecoveryCodes] = useState([]);
26
+ const [loading, setLoading] = useState(false);
27
+ const [error, setError] = useState('');
28
+ const [message, setMessage] = useState('');
29
+ const [confirmLogoutAll, setConfirmLogoutAll] = useState(false);
30
+ function resetFeedback() {
31
+ setError('');
32
+ setMessage('');
33
+ }
34
+ function fail(err, fallback) {
35
+ setError(err instanceof Error ? err.message : fallback);
36
+ }
37
+ async function changePassword() {
38
+ if (password !== confirm) {
39
+ setError('Passwords do not match');
40
+ return;
41
+ }
42
+ if (password.length < 8) {
43
+ setError('Password must be at least 8 characters');
44
+ return;
45
+ }
46
+ resetFeedback();
47
+ setLoading(true);
48
+ try {
49
+ const user = await confirmation.run(() => api.post('/auth/change-password', sso ? { newPassword: password } : { currentPassword: current, newPassword: password }));
50
+ setSession(user);
51
+ setCurrent('');
52
+ setPassword('');
53
+ setConfirm('');
54
+ setMessage('Password changed. Other active sessions were signed out.');
55
+ }
56
+ catch (err) {
57
+ fail(err, 'Failed to change password');
58
+ }
59
+ finally {
60
+ setLoading(false);
61
+ }
62
+ }
63
+ async function beginTwoFactorSetup() {
64
+ resetFeedback();
65
+ setLoading(true);
66
+ try {
67
+ const result = await confirmation.run(() => api.post('/auth/2fa/setup', sso ? {} : { currentPassword: securityPassword }));
68
+ setSetup(result);
69
+ setCode('');
70
+ }
71
+ catch (err) {
72
+ fail(err, 'Failed to start two-factor setup');
73
+ }
74
+ finally {
75
+ setLoading(false);
76
+ }
77
+ }
78
+ async function enableTwoFactor() {
79
+ if (!setup)
80
+ return;
81
+ resetFeedback();
82
+ setLoading(true);
83
+ try {
84
+ const result = await api.post('/auth/2fa/enable', { setupToken: setup.setupToken, code });
85
+ setRecoveryCodes(result.recoveryCodes);
86
+ setTwoFactorEnabled(true);
87
+ if (currentUser)
88
+ setSession({ ...currentUser, twoFactorEnabled: true });
89
+ setSetup(null);
90
+ setSecurityPassword('');
91
+ setCode('');
92
+ setMessage('Two-factor authentication is enabled. Save the recovery codes now.');
93
+ }
94
+ catch (err) {
95
+ setError(err instanceof Error ? err.message : 'Failed to enable two-factor authentication');
96
+ }
97
+ finally {
98
+ setLoading(false);
99
+ }
100
+ }
101
+ async function disableTwoFactor() {
102
+ resetFeedback();
103
+ setLoading(true);
104
+ try {
105
+ await confirmation.run(() => api.post('/auth/2fa/disable', sso ? { code } : { currentPassword: securityPassword, code }));
106
+ setTwoFactorEnabled(false);
107
+ if (currentUser)
108
+ setSession({ ...currentUser, twoFactorEnabled: false });
109
+ setSecurityPassword('');
110
+ setCode('');
111
+ setRecoveryCodes([]);
112
+ setMessage('Two-factor authentication is disabled.');
113
+ }
114
+ catch (err) {
115
+ fail(err, 'Failed to disable two-factor authentication');
116
+ }
117
+ finally {
118
+ setLoading(false);
119
+ }
120
+ }
121
+ async function logoutEverywhere() {
122
+ resetFeedback();
123
+ setLoading(true);
124
+ try {
125
+ await api.post('/auth/logout-all');
126
+ }
127
+ finally {
128
+ clearSession();
129
+ navigate(`${uiConfig().basePath}/login`);
130
+ }
131
+ }
132
+ return (_jsxs(PageContainer, { children: [_jsx(PageHeader, { title: "Settings", subtitle: "Manage your account and sign-in security" }), (error || message) && (_jsx(Alert, { tone: error ? 'error' : 'success', className: "max-w-2xl", children: error || message })), _jsxs("div", { className: "grid gap-6 xl:grid-cols-3 max-w-7xl", children: [_jsxs("section", { className: "rounded-2xl p-6", style: { background: 'var(--m3-surface-container-low)', border: '1px solid var(--m3-outline-variant)' }, children: [_jsx("h2", { className: "font-headline font-semibold text-lg mb-1", children: "Change password" }), _jsx("p", { className: "text-sm mb-5", style: { color: 'var(--m3-secondary)' }, children: "Changing your password signs out every other active session." }), _jsxs("form", { onSubmit: (event) => { event.preventDefault(); void changePassword(); }, className: "space-y-4", children: [sso
133
+ ? _jsx(SsoConfirmationNote, { confirmation: confirmation })
134
+ : _jsx(PasswordField, { label: "Current password", value: current, onChange: setCurrent, placeholder: "Enter current password" }), _jsx(PasswordField, { label: "New password", value: password, onChange: setPassword, placeholder: "Minimum 8 characters", minLength: 8 }), _jsx(PasswordField, { label: "Confirm new password", value: confirm, onChange: setConfirm, placeholder: "Repeat the new password" }), _jsx("button", { type: "submit", disabled: loading, className: "btn btn-primary", children: loading ? 'Saving…' : 'Update password' })] })] }), _jsxs("section", { className: "rounded-2xl p-6", style: { background: 'var(--m3-surface-container-low)', border: '1px solid var(--m3-outline-variant)' }, children: [_jsxs("div", { className: "flex items-center justify-between gap-3 mb-1", children: [_jsx("h2", { className: "font-headline font-semibold text-lg", children: "Two-factor authentication" }), _jsx("span", { className: "text-xs font-semibold px-2.5 py-1 rounded-full", style: {
135
+ background: twoFactorEnabled ? 'var(--m3-up-bg)' : 'var(--m3-surface-container-high)',
136
+ color: twoFactorEnabled ? 'var(--m3-up)' : 'var(--m3-secondary)',
137
+ }, children: twoFactorEnabled ? 'Enabled' : 'Disabled' })] }), _jsx("p", { className: "text-sm mb-5", style: { color: 'var(--m3-secondary)' }, children: "Use any TOTP authenticator application. Recovery codes work once each." }), !twoFactorEnabled && !setup && recoveryCodes.length === 0 && (_jsxs("form", { className: "space-y-4", onSubmit: (event) => { event.preventDefault(); void beginTwoFactorSetup(); }, children: [sso
138
+ ? _jsx(SsoConfirmationNote, { confirmation: confirmation })
139
+ : _jsx(PasswordField, { label: "Current password", value: securityPassword, onChange: setSecurityPassword, placeholder: "Confirm your password" }), _jsx("button", { type: "submit", disabled: loading || (!sso && !securityPassword), className: "btn btn-primary", children: "Set up 2FA" })] })), setup && (_jsxs("form", { className: "space-y-4", onSubmit: (event) => { event.preventDefault(); void enableTwoFactor(); }, children: [_jsxs("div", { className: "rounded-xl p-5 flex flex-col items-center text-center", style: { background: 'var(--m3-surface-container)' }, children: [_jsx("p", { className: "text-sm font-semibold mb-3", children: "Scan this QR code with your authenticator app" }), _jsx("img", { src: setup.qrDataUrl, alt: "QR code for two-factor authentication setup", width: 240, height: 240, className: "rounded-xl", style: { background: '#ffffff' } }), _jsxs("details", { className: "w-full mt-4 text-left", children: [_jsx("summary", { className: "text-sm cursor-pointer", style: { color: 'var(--m3-secondary)' }, children: "Cannot scan the QR code?" }), _jsx("p", { className: "text-xs mt-3 mb-2", style: { color: 'var(--m3-secondary)' }, children: "Enter this setup key manually:" }), _jsx("code", { className: "block text-sm break-all select-all", children: setup.secret }), _jsx("a", { href: setup.uri, className: "inline-block text-sm mt-3 underline", children: "Open in authenticator app" })] })] }), _jsx(TextField, { label: "Authentication code", value: code, onChange: setCode, placeholder: "123456", autoComplete: "one-time-code", inputMode: "numeric" }), _jsx("button", { type: "submit", disabled: loading || !code, className: "btn btn-primary", children: "Verify and enable" })] })), recoveryCodes.length > 0 && (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "rounded-xl p-4", style: { background: 'var(--m3-surface-container)' }, children: [_jsx("p", { className: "text-sm font-semibold mb-3", children: "Recovery codes \u2014 store them somewhere safe" }), _jsx("div", { className: "grid grid-cols-2 gap-2 font-mono text-sm select-all", children: recoveryCodes.map((recoveryCode) => _jsx("code", { children: recoveryCode }, recoveryCode)) })] }), _jsx(CopyButton, { value: recoveryCodes.join('\n'), label: "Copy codes" })] })), twoFactorEnabled && recoveryCodes.length === 0 && (_jsxs("form", { className: "space-y-4", onSubmit: (event) => { event.preventDefault(); void disableTwoFactor(); }, children: [sso
140
+ ? _jsx(SsoConfirmationNote, { confirmation: confirmation })
141
+ : _jsx(PasswordField, { label: "Current password", value: securityPassword, onChange: setSecurityPassword, placeholder: "Confirm your password" }), _jsx(TextField, { label: "Authentication or recovery code", value: code, onChange: setCode, placeholder: "Code", autoComplete: "one-time-code" }), _jsx("button", { type: "submit", disabled: loading || (!sso && !securityPassword) || !code, className: "btn btn-danger-outline", children: "Disable 2FA" })] }))] }), _jsxs("section", { className: "rounded-2xl p-6", style: { background: 'var(--m3-surface-container-low)', border: '1px solid var(--m3-outline-variant)' }, children: [_jsx("h2", { className: "font-headline font-semibold text-lg", children: "Date and time format" }), _jsxs("p", { className: "text-sm mt-1 mb-4", style: { color: 'var(--m3-secondary)' }, children: ["Applies to this browser only. Now: ", formatDateTime(Date.now())] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: "date-format", className: "text-sm font-medium", children: "Date" }), _jsx("select", { id: "date-format", className: "input-sig", value: datePrefs.date, onChange: (e) => setDatePrefs({ ...datePrefs, date: e.target.value }), children: DATE_FORMATS.map((f) => _jsx("option", { value: f.value, children: f.label }, f.value)) })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: "time-format", className: "text-sm font-medium", children: "Time" }), _jsx("select", { id: "time-format", className: "input-sig", value: datePrefs.time, onChange: (e) => setDatePrefs({ ...datePrefs, time: e.target.value }), children: TIME_FORMATS.map((f) => _jsx("option", { value: f.value, children: f.label }, f.value)) })] })] })] })] }), _jsxs("section", { className: "rounded-2xl p-6 max-w-5xl", style: { background: 'var(--m3-surface-container-low)', border: '1px solid var(--m3-outline-variant)' }, children: [_jsx("h2", { className: "font-headline font-semibold text-lg", children: "Active sessions" }), _jsx("p", { className: "text-sm mt-1 mb-4", style: { color: 'var(--m3-secondary)' }, children: "Sign out this browser and every other active session for your account." }), _jsx("button", { type: "button", disabled: loading, onClick: () => setConfirmLogoutAll(true), className: "btn btn-danger-outline", children: "Sign out everywhere" })] }), confirmLogoutAll && (_jsx(ConfirmModal, { title: "Sign out everywhere", message: "Sign out this browser and every other active session for your account? You will need to sign in again.", confirmLabel: "Sign out everywhere", pending: loading, pendingLabel: "Signing out\u2026", onConfirm: () => void logoutEverywhere(), onCancel: () => setConfirmLogoutAll(false) }))] }));
142
+ }
143
+ function PasswordField({ label, value, onChange, placeholder, minLength }) {
144
+ return (_jsxs("label", { className: "block", children: [_jsx("span", { className: "block font-mono text-xs uppercase tracking-wider mb-2", style: { color: 'var(--m3-secondary)' }, children: label }), _jsx("input", { type: "password", value: value, onChange: (event) => onChange(event.target.value), required: true, minLength: minLength, className: "input-sig w-full", placeholder: placeholder })] }));
145
+ }
146
+ function TextField({ label, value, onChange, placeholder, autoComplete, inputMode }) {
147
+ return (_jsxs("label", { className: "block", children: [_jsx("span", { className: "block font-mono text-xs uppercase tracking-wider mb-2", style: { color: 'var(--m3-secondary)' }, children: label }), _jsx("input", { type: "text", inputMode: inputMode, value: value, onChange: (event) => onChange(event.target.value), required: true, className: "input-sig w-full", placeholder: placeholder, autoComplete: autoComplete })] }));
148
+ }
149
+ //# sourceMappingURL=Settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Settings.js","sourceRoot":"","sources":["../../src/pages/Settings.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default function SetupPage(): import("react").JSX.Element | null;
2
+ //# sourceMappingURL=Setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Setup.d.ts","sourceRoot":"","sources":["../../src/pages/Setup.tsx"],"names":[],"mappings":"AAeA,MAAM,CAAC,OAAO,UAAU,SAAS,uCAsahC"}