@actuate-media/cms-admin 0.28.0 → 0.30.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.
- package/dist/AdminRoot.d.ts +13 -0
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +22 -4
- package/dist/AdminRoot.js.map +1 -1
- package/dist/__tests__/views/account-security.render.test.d.ts +2 -0
- package/dist/__tests__/views/account-security.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/account-security.render.test.js +98 -0
- package/dist/__tests__/views/account-security.render.test.js.map +1 -0
- package/dist/__tests__/views/login-mfa.render.test.d.ts +2 -0
- package/dist/__tests__/views/login-mfa.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/login-mfa.render.test.js +73 -0
- package/dist/__tests__/views/login-mfa.render.test.js.map +1 -0
- package/dist/__tests__/views/settings-save-footer.render.test.d.ts +2 -0
- package/dist/__tests__/views/settings-save-footer.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/settings-save-footer.render.test.js +53 -0
- package/dist/__tests__/views/settings-save-footer.render.test.js.map +1 -0
- package/dist/actuate-admin.css +1 -1
- package/dist/components/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/Breadcrumbs.js +1 -0
- package/dist/components/Breadcrumbs.js.map +1 -1
- package/dist/layout/Header.d.ts +3 -1
- package/dist/layout/Header.d.ts.map +1 -1
- package/dist/layout/Header.js +2 -2
- package/dist/layout/Header.js.map +1 -1
- package/dist/layout/Layout.d.ts +2 -1
- package/dist/layout/Layout.d.ts.map +1 -1
- package/dist/layout/Layout.js +2 -2
- package/dist/layout/Layout.js.map +1 -1
- package/dist/views/Login.d.ts +16 -1
- package/dist/views/Login.d.ts.map +1 -1
- package/dist/views/Login.js +55 -3
- package/dist/views/Login.js.map +1 -1
- package/dist/views/Profile.d.ts +12 -0
- package/dist/views/Profile.d.ts.map +1 -0
- package/dist/views/Profile.js +16 -0
- package/dist/views/Profile.js.map +1 -0
- package/dist/views/Settings.d.ts.map +1 -1
- package/dist/views/Settings.js +54 -51
- package/dist/views/Settings.js.map +1 -1
- package/dist/views/Users.d.ts.map +1 -1
- package/dist/views/Users.js +50 -7
- package/dist/views/Users.js.map +1 -1
- package/dist/views/profile/AccountSecurity.d.ts +2 -0
- package/dist/views/profile/AccountSecurity.d.ts.map +1 -0
- package/dist/views/profile/AccountSecurity.js +117 -0
- package/dist/views/profile/AccountSecurity.js.map +1 -0
- package/dist/views/profile/useMfaEnrollment.d.ts +35 -0
- package/dist/views/profile/useMfaEnrollment.d.ts.map +1 -0
- package/dist/views/profile/useMfaEnrollment.js +103 -0
- package/dist/views/profile/useMfaEnrollment.js.map +1 -0
- package/dist/views/settings/AuthMfaCard.d.ts +2 -1
- package/dist/views/settings/AuthMfaCard.d.ts.map +1 -1
- package/dist/views/settings/AuthMfaCard.js +3 -2
- package/dist/views/settings/AuthMfaCard.js.map +1 -1
- package/dist/views/settings/SecurityTab.d.ts.map +1 -1
- package/dist/views/settings/SecurityTab.js +1 -1
- package/dist/views/settings/SecurityTab.js.map +1 -1
- package/package.json +3 -2
- package/src/AdminRoot.tsx +46 -2
- package/src/__tests__/views/account-security.render.test.tsx +140 -0
- package/src/__tests__/views/login-mfa.render.test.tsx +88 -0
- package/src/__tests__/views/settings-save-footer.render.test.tsx +63 -0
- package/src/components/Breadcrumbs.tsx +1 -0
- package/src/layout/Header.tsx +10 -2
- package/src/layout/Layout.tsx +10 -1
- package/src/views/Login.tsx +247 -94
- package/src/views/Profile.tsx +54 -0
- package/src/views/Settings.tsx +142 -263
- package/src/views/Users.tsx +94 -12
- package/src/views/profile/AccountSecurity.tsx +406 -0
- package/src/views/profile/useMfaEnrollment.ts +120 -0
- package/src/views/settings/AuthMfaCard.tsx +19 -4
- package/src/views/settings/SecurityTab.tsx +1 -0
package/dist/views/Users.js
CHANGED
|
@@ -11,7 +11,9 @@ export function Users({ onNavigate, embedded = false } = {}) {
|
|
|
11
11
|
const { data, loading, error, refetch } = useApiData('/users');
|
|
12
12
|
const [showInviteDialog, setShowInviteDialog] = useState(false);
|
|
13
13
|
const [inviteEmail, setInviteEmail] = useState('');
|
|
14
|
-
const [
|
|
14
|
+
const [inviteName, setInviteName] = useState('');
|
|
15
|
+
const [inviteRole, setInviteRole] = useState('author');
|
|
16
|
+
const [inviting, setInviting] = useState(false);
|
|
15
17
|
const [searchQuery, setSearchQuery] = useState('');
|
|
16
18
|
const [filterRole, setFilterRole] = useState('all');
|
|
17
19
|
const [sortConfig, setSortConfig] = useState(null);
|
|
@@ -36,12 +38,53 @@ export function Users({ onNavigate, embedded = false } = {}) {
|
|
|
36
38
|
}
|
|
37
39
|
return results;
|
|
38
40
|
}, [users, searchQuery, filterRole, sortConfig]);
|
|
39
|
-
const
|
|
40
|
-
e.preventDefault();
|
|
41
|
-
toast.success(`Invitation sent to ${inviteEmail}`);
|
|
42
|
-
setShowInviteDialog(false);
|
|
41
|
+
const resetInviteForm = () => {
|
|
43
42
|
setInviteEmail('');
|
|
44
|
-
|
|
43
|
+
setInviteName('');
|
|
44
|
+
setInviteRole('author');
|
|
45
|
+
};
|
|
46
|
+
const handleInvite = async (e) => {
|
|
47
|
+
e.preventDefault();
|
|
48
|
+
if (inviting)
|
|
49
|
+
return;
|
|
50
|
+
setInviting(true);
|
|
51
|
+
try {
|
|
52
|
+
const res = await cmsApi('/users/invite', {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
body: JSON.stringify({
|
|
55
|
+
email: inviteEmail.trim(),
|
|
56
|
+
name: inviteName.trim() || undefined,
|
|
57
|
+
role: inviteRole,
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
60
|
+
if (res.error) {
|
|
61
|
+
toast.error(res.error);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (res.data?.emailed) {
|
|
65
|
+
toast.success(`Invitation sent to ${inviteEmail.trim()}`);
|
|
66
|
+
}
|
|
67
|
+
else if (res.data?.inviteUrl) {
|
|
68
|
+
// No email provider configured (or the send failed): surface the link
|
|
69
|
+
// so the admin can share it manually rather than silently succeeding.
|
|
70
|
+
await navigator.clipboard?.writeText(res.data.inviteUrl).catch(() => { });
|
|
71
|
+
toast.success('Invite created. Link copied — email isn’t configured, so share it manually.', {
|
|
72
|
+
duration: 8000,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
toast.success('Invitation created.');
|
|
77
|
+
}
|
|
78
|
+
setShowInviteDialog(false);
|
|
79
|
+
resetInviteForm();
|
|
80
|
+
refetch();
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
toast.error('Could not create the invitation. Please try again.');
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
setInviting(false);
|
|
87
|
+
}
|
|
45
88
|
};
|
|
46
89
|
const handleDelete = async (userId) => {
|
|
47
90
|
const res = await cmsApi(`/users/${userId}`, { method: 'DELETE' });
|
|
@@ -68,6 +111,6 @@ export function Users({ onNavigate, embedded = false } = {}) {
|
|
|
68
111
|
? 'bg-blue-100 text-blue-800'
|
|
69
112
|
: 'bg-gray-100 text-gray-800'}`, children: user.role }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${user.status === 'Active'
|
|
70
113
|
? 'bg-green-100 text-green-800'
|
|
71
|
-
: 'bg-gray-100 text-gray-800'}`, children: user.status }) }), _jsx("td", { className: "px-4 py-3 text-sm text-gray-600", children: user.lastLogin }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/users/${user.id}`), className: "rounded p-1.5 transition-colors hover:bg-gray-100", "aria-label": `Edit ${user.name}`, children: _jsx(Pencil, { className: "h-4 w-4 text-gray-600" }) }), _jsx("button", { type: "button", onClick: () => handleDelete(user.id), className: "rounded p-1.5 transition-colors hover:bg-gray-100", "aria-label": `Remove ${user.name}`, children: _jsx(Trash2, { className: "h-4 w-4 text-red-600" }) })] }) })] }, user.id))) })] }) }) })), _jsx(Dialog.Root, { open: showInviteDialog, onOpenChange: setShowInviteDialog, children: _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/50" }), _jsxs(Dialog.Content, { className: "fixed top-1/2 left-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg", children: [_jsx(Dialog.Title, { className: "mb-
|
|
114
|
+
: 'bg-gray-100 text-gray-800'}`, children: user.status }) }), _jsx("td", { className: "px-4 py-3 text-sm text-gray-600", children: user.lastLogin }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/users/${user.id}`), className: "rounded p-1.5 transition-colors hover:bg-gray-100", "aria-label": `Edit ${user.name}`, children: _jsx(Pencil, { className: "h-4 w-4 text-gray-600" }) }), _jsx("button", { type: "button", onClick: () => handleDelete(user.id), className: "rounded p-1.5 transition-colors hover:bg-gray-100", "aria-label": `Remove ${user.name}`, children: _jsx(Trash2, { className: "h-4 w-4 text-red-600" }) })] }) })] }, user.id))) })] }) }) })), _jsx(Dialog.Root, { open: showInviteDialog, onOpenChange: setShowInviteDialog, children: _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/50" }), _jsxs(Dialog.Content, { className: "fixed top-1/2 left-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg", children: [_jsx(Dialog.Title, { className: "mb-1 text-lg font-semibold text-gray-900", children: "Invite User" }), _jsx(Dialog.Description, { className: "mb-4 text-sm text-gray-500", children: "They\u2019ll get a link to set a password and sign in. If email isn\u2019t configured, you\u2019ll get a link to share." }), _jsxs("form", { onSubmit: handleInvite, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "invite-email", className: "mb-1 block text-sm font-medium text-gray-700", children: "Email Address" }), _jsx("input", { id: "invite-email", type: "email", value: inviteEmail, onChange: (e) => setInviteEmail(e.target.value), placeholder: "user@example.com", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none", required: true })] }), _jsxs("div", { children: [_jsxs("label", { htmlFor: "invite-name", className: "mb-1 block text-sm font-medium text-gray-700", children: ["Name ", _jsx("span", { className: "font-normal text-gray-400", children: "(optional)" })] }), _jsx("input", { id: "invite-name", type: "text", value: inviteName, onChange: (e) => setInviteName(e.target.value), placeholder: "Jane Doe", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "invite-role", className: "mb-1 block text-sm font-medium text-gray-700", children: "Role" }), _jsxs("select", { id: "invite-role", value: inviteRole, onChange: (e) => setInviteRole(e.target.value), className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none", children: [_jsx("option", { value: "author", children: "Author" }), _jsx("option", { value: "editor", children: "Editor" }), _jsx("option", { value: "admin", children: "Admin" })] })] }), _jsxs("div", { className: "flex items-center justify-end gap-3 pt-4", children: [_jsx(Dialog.Close, { asChild: true, children: _jsx("button", { type: "button", className: "rounded-lg border border-gray-300 px-4 py-2 text-sm transition-colors hover:bg-gray-50", children: "Cancel" }) }), _jsxs("button", { type: "submit", disabled: inviting || !inviteEmail.trim(), className: "inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60", children: [inviting && _jsx(Loader2, { className: "h-4 w-4 animate-spin", "aria-hidden": true }), inviting ? 'Sending…' : 'Send Invite'] })] })] })] })] }) })] }));
|
|
72
115
|
}
|
|
73
116
|
//# sourceMappingURL=Users.js.map
|
package/dist/views/Users.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Users.js","sourceRoot":"","sources":["../../src/views/Users.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,MAAM,MAAM,wBAAwB,CAAA;AAChD,OAAO,EACL,MAAM,EACN,MAAM,EACN,QAAQ,EACR,MAAM,EACN,WAAW,EACX,OAAO,EACP,SAAS,EACT,OAAO,EACP,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAA;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,EAAE,eAAe,EAAmB,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAWtC,MAAM,UAAU,KAAK,CAAC,EAAE,UAAU,EAAE,QAAQ,GAAG,KAAK,KAAiB,EAAE;IACrE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,UAAU,CAAQ,QAAQ,CAAC,CAAA;IACrE,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAClD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACtD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAClD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAiC,IAAI,CAAC,CAAA;IAElF,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAA;IAExB,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE;QACrC,IAAI,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE;YACvC,MAAM,aAAa,GACjB,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;gBACnE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAA;YACtE,MAAM,WAAW,GACf,UAAU,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,WAAW,EAAE,CAAA;YACtF,OAAO,aAAa,IAAI,WAAW,CAAA;QACrC,CAAC,CAAC,CAAA;QAEF,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YACvB,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QACxF,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE;gBAC7C,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;gBACpC,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;gBACpC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;gBACpD,OAAO,UAAU,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;YACpD,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA;IAEhD,MAAM,
|
|
1
|
+
{"version":3,"file":"Users.js","sourceRoot":"","sources":["../../src/views/Users.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountSecurity.d.ts","sourceRoot":"","sources":["../../../src/views/profile/AccountSecurity.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,eAAe,4CAyX9B"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useRef, useState } from 'react';
|
|
4
|
+
import { QRCodeSVG } from 'qrcode.react';
|
|
5
|
+
import { toast } from 'sonner';
|
|
6
|
+
import { AlertTriangle, Check, Copy, Download, Loader2, ShieldCheck, ShieldAlert, } from 'lucide-react';
|
|
7
|
+
import { SecurityCard, StatusRow } from '../settings/securityPrimitives.js';
|
|
8
|
+
import { useMfaEnrollment } from './useMfaEnrollment.js';
|
|
9
|
+
function FieldError({ id, message }) {
|
|
10
|
+
if (!message)
|
|
11
|
+
return null;
|
|
12
|
+
return (_jsx("p", { id: id, role: "alert", className: "text-destructive mt-1.5 text-sm", children: message }));
|
|
13
|
+
}
|
|
14
|
+
export function AccountSecurity() {
|
|
15
|
+
const headingId = useId();
|
|
16
|
+
const pwId = useId();
|
|
17
|
+
const pwErrId = useId();
|
|
18
|
+
const codeId = useId();
|
|
19
|
+
const codeErrId = useId();
|
|
20
|
+
const disablePwId = useId();
|
|
21
|
+
const disableErrId = useId();
|
|
22
|
+
const mfa = useMfaEnrollment();
|
|
23
|
+
const [step, setStep] = useState('idle');
|
|
24
|
+
const [password, setPassword] = useState('');
|
|
25
|
+
const [verifyCode, setVerifyCode] = useState('');
|
|
26
|
+
const [setupError, setSetupError] = useState(null);
|
|
27
|
+
const [codeError, setCodeError] = useState(null);
|
|
28
|
+
const [savedAcknowledged, setSavedAcknowledged] = useState(false);
|
|
29
|
+
const [disabling, setDisabling] = useState(false);
|
|
30
|
+
const [disablePassword, setDisablePassword] = useState('');
|
|
31
|
+
const [disableError, setDisableError] = useState(null);
|
|
32
|
+
const codeInputRef = useRef(null);
|
|
33
|
+
function resetSetup() {
|
|
34
|
+
mfa.cancelSetup();
|
|
35
|
+
setStep('idle');
|
|
36
|
+
setPassword('');
|
|
37
|
+
setVerifyCode('');
|
|
38
|
+
setSetupError(null);
|
|
39
|
+
setCodeError(null);
|
|
40
|
+
setSavedAcknowledged(false);
|
|
41
|
+
}
|
|
42
|
+
async function handleBeginSetup() {
|
|
43
|
+
setSetupError(null);
|
|
44
|
+
const result = await mfa.beginSetup(password);
|
|
45
|
+
if (!result.ok) {
|
|
46
|
+
setSetupError(result.error ?? 'Could not start MFA setup.');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
setPassword('');
|
|
50
|
+
setStep('enroll');
|
|
51
|
+
// Move focus to the code field once the QR is shown.
|
|
52
|
+
requestAnimationFrame(() => codeInputRef.current?.focus());
|
|
53
|
+
}
|
|
54
|
+
async function handleConfirmSetup() {
|
|
55
|
+
setCodeError(null);
|
|
56
|
+
const result = await mfa.confirmSetup(verifyCode);
|
|
57
|
+
if (!result.ok) {
|
|
58
|
+
setCodeError(result.error ?? 'That code did not match. Try the current one.');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
toast.success('Two-factor authentication is now enabled.');
|
|
62
|
+
resetSetup();
|
|
63
|
+
}
|
|
64
|
+
async function handleDisable() {
|
|
65
|
+
setDisableError(null);
|
|
66
|
+
const result = await mfa.disable(disablePassword);
|
|
67
|
+
if (!result.ok) {
|
|
68
|
+
setDisableError(result.error ?? 'Could not disable MFA.');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
toast.success('Two-factor authentication has been disabled.');
|
|
72
|
+
setDisabling(false);
|
|
73
|
+
setDisablePassword('');
|
|
74
|
+
}
|
|
75
|
+
function copyBackupCodes() {
|
|
76
|
+
if (!mfa.enrollment)
|
|
77
|
+
return;
|
|
78
|
+
void navigator.clipboard
|
|
79
|
+
?.writeText(mfa.enrollment.backupCodes.join('\n'))
|
|
80
|
+
.then(() => toast.success('Backup codes copied to clipboard.'))
|
|
81
|
+
.catch(() => toast.error('Could not copy codes. Copy them manually.'));
|
|
82
|
+
}
|
|
83
|
+
function downloadBackupCodes() {
|
|
84
|
+
if (!mfa.enrollment)
|
|
85
|
+
return;
|
|
86
|
+
const blob = new Blob([
|
|
87
|
+
'Actuate CMS — two-factor backup codes\n',
|
|
88
|
+
'Each code can be used once if you lose access to your authenticator app.\n\n',
|
|
89
|
+
mfa.enrollment.backupCodes.join('\n'),
|
|
90
|
+
'\n',
|
|
91
|
+
], { type: 'text/plain' });
|
|
92
|
+
const url = URL.createObjectURL(blob);
|
|
93
|
+
const a = document.createElement('a');
|
|
94
|
+
a.href = url;
|
|
95
|
+
a.download = 'actuate-backup-codes.txt';
|
|
96
|
+
a.click();
|
|
97
|
+
URL.revokeObjectURL(url);
|
|
98
|
+
}
|
|
99
|
+
return (_jsxs(SecurityCard, { headingId: headingId, title: "Two-factor authentication", description: "Add a one-time code from an authenticator app to your sign-in for an extra layer of protection.", children: [mfa.status === 'loading' && (_jsxs("div", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" }), "Checking your MFA status\u2026"] })), mfa.status === 'error' && (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: "Could not load your MFA status." }), _jsx("button", { type: "button", onClick: () => void mfa.refresh(), className: "border-border text-foreground hover:bg-accent rounded-md border px-3 py-1.5 text-sm transition-colors", children: "Retry" })] })), mfa.status === 'enabled' && (_jsxs("div", { className: "space-y-4", children: [_jsx(StatusRow, { status: "pass", label: "Two-factor authentication", value: "Enabled" }), !disabling ? (_jsxs("button", { type: "button", onClick: () => {
|
|
100
|
+
setDisabling(true);
|
|
101
|
+
setDisableError(null);
|
|
102
|
+
}, className: "border-border text-foreground hover:bg-accent inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm transition-colors", children: [_jsx(ShieldAlert, { size: 16, "aria-hidden": "true" }), "Disable two-factor"] })) : (_jsxs("div", { className: "border-destructive/30 bg-destructive/5 space-y-3 rounded-md border p-3", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertTriangle, { size: 16, className: "text-destructive mt-0.5 shrink-0", "aria-hidden": "true" }), _jsx("p", { className: "text-foreground text-sm", children: "Disabling two-factor makes your account password-only and signs out your other sessions. Confirm your password to continue." })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: disablePwId, className: "text-foreground mb-1 block text-sm font-medium", children: "Current password" }), _jsx("input", { id: disablePwId, type: "password", autoComplete: "current-password", value: disablePassword, onChange: (e) => setDisablePassword(e.target.value), "aria-invalid": disableError ? true : undefined, "aria-describedby": disableError ? disableErrId : undefined, className: "border-border bg-input-background text-foreground focus-visible:ring-ring w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none" }), _jsx(FieldError, { id: disableErrId, message: disableError })] }), _jsxs("div", { className: "flex items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: () => {
|
|
103
|
+
setDisabling(false);
|
|
104
|
+
setDisablePassword('');
|
|
105
|
+
setDisableError(null);
|
|
106
|
+
}, className: "text-muted-foreground hover:text-foreground rounded-md px-3 py-2 text-sm transition-colors", children: "Cancel" }), _jsxs("button", { type: "button", onClick: () => void handleDisable(), disabled: mfa.busy || !disablePassword, className: "bg-destructive text-destructive-foreground inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50", children: [mfa.busy && _jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" }), "Disable two-factor"] })] })] }))] })), mfa.status === 'disabled' && step === 'idle' && (_jsxs("div", { className: "space-y-4", children: [_jsx(StatusRow, { status: "warning", label: "Two-factor authentication", value: "Not set up" }), _jsxs("button", { type: "button", onClick: () => {
|
|
107
|
+
setStep('reauth');
|
|
108
|
+
setSetupError(null);
|
|
109
|
+
}, className: "bg-brand text-brand-foreground focus-visible:ring-ring inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 focus-visible:ring-2 focus-visible:outline-none", children: [_jsx(ShieldCheck, { size: 16, "aria-hidden": "true" }), "Set up two-factor"] })] })), mfa.status === 'disabled' && step === 'reauth' && (_jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: "Confirm your current password to begin setting up two-factor authentication." }), _jsxs("div", { children: [_jsx("label", { htmlFor: pwId, className: "text-foreground mb-1 block text-sm font-medium", children: "Current password" }), _jsx("input", { id: pwId, type: "password", autoComplete: "current-password", value: password, onChange: (e) => setPassword(e.target.value), autoFocus: true, "aria-invalid": setupError ? true : undefined, "aria-describedby": setupError ? pwErrId : undefined, onKeyDown: (e) => {
|
|
110
|
+
if (e.key === 'Enter' && password && !mfa.busy)
|
|
111
|
+
void handleBeginSetup();
|
|
112
|
+
}, className: "border-border bg-input-background text-foreground focus-visible:ring-ring w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none" }), _jsx(FieldError, { id: pwErrId, message: setupError })] }), _jsxs("div", { className: "flex items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: resetSetup, className: "text-muted-foreground hover:text-foreground rounded-md px-3 py-2 text-sm transition-colors", children: "Cancel" }), _jsxs("button", { type: "button", onClick: () => void handleBeginSetup(), disabled: mfa.busy || !password, className: "bg-brand text-brand-foreground inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50", children: [mfa.busy && _jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" }), "Continue"] })] })] })), mfa.status === 'disabled' && step === 'enroll' && mfa.enrollment && (_jsxs("div", { className: "space-y-5", children: [_jsxs("ol", { className: "text-foreground list-decimal space-y-4 pl-5 text-sm", children: [_jsxs("li", { children: [_jsx("p", { className: "font-medium", children: "Scan this QR code with your authenticator app." }), _jsx("div", { className: "border-border mt-2 inline-flex rounded-lg border bg-white p-3", children: _jsx(QRCodeSVG, { value: mfa.enrollment.uri, size: 160, role: "img", "aria-label": "Two-factor setup QR code" }) }), _jsx("p", { className: "text-muted-foreground mt-2", children: "Can't scan? Enter this key manually:" }), _jsx("code", { className: "border-border bg-muted text-foreground mt-1 inline-block rounded border px-2 py-1 font-mono text-xs break-all", children: mfa.enrollment.secret })] }), _jsxs("li", { children: [_jsx("p", { className: "font-medium", children: "Save your backup codes." }), _jsx("p", { className: "text-muted-foreground mt-0.5", children: "Each code works once if you lose your authenticator. They won't be shown again." }), _jsx("ul", { className: "border-border bg-muted/40 mt-2 grid grid-cols-2 gap-x-6 gap-y-1 rounded-md border p-3 font-mono text-xs sm:grid-cols-4", children: mfa.enrollment.backupCodes.map((code) => (_jsx("li", { className: "text-foreground", children: code }, code))) }), _jsxs("div", { className: "mt-2 flex flex-wrap gap-2", children: [_jsxs("button", { type: "button", onClick: copyBackupCodes, className: "border-border text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs transition-colors", children: [_jsx(Copy, { size: 14, "aria-hidden": "true" }), "Copy codes"] }), _jsxs("button", { type: "button", onClick: downloadBackupCodes, className: "border-border text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs transition-colors", children: [_jsx(Download, { size: 14, "aria-hidden": "true" }), "Download"] })] }), _jsxs("label", { className: "text-foreground mt-2 flex items-center gap-2 text-sm", children: [_jsx("input", { type: "checkbox", checked: savedAcknowledged, onChange: (e) => setSavedAcknowledged(e.target.checked), className: "accent-brand h-4 w-4" }), "I've saved my backup codes somewhere safe."] })] }), _jsxs("li", { children: [_jsx("p", { className: "font-medium", children: "Enter the 6-digit code from your app to finish." }), _jsxs("div", { className: "mt-2", children: [_jsx("label", { htmlFor: codeId, className: "sr-only", children: "Authentication code" }), _jsx("input", { id: codeId, ref: codeInputRef, inputMode: "numeric", autoComplete: "one-time-code", maxLength: 6, placeholder: "123456", value: verifyCode, onChange: (e) => setVerifyCode(e.target.value.replace(/\D/g, '')), "aria-invalid": codeError ? true : undefined, "aria-describedby": codeError ? codeErrId : undefined, onKeyDown: (e) => {
|
|
113
|
+
if (e.key === 'Enter' && savedAcknowledged && !mfa.busy)
|
|
114
|
+
void handleConfirmSetup();
|
|
115
|
+
}, className: "border-border bg-input-background text-foreground focus-visible:ring-ring w-40 rounded-md border px-3 py-2 text-center font-mono text-lg tracking-[0.3em] focus-visible:ring-2 focus-visible:outline-none" }), _jsx(FieldError, { id: codeErrId, message: codeError })] })] })] }), _jsxs("div", { className: "flex items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: resetSetup, className: "text-muted-foreground hover:text-foreground rounded-md px-3 py-2 text-sm transition-colors", children: "Cancel" }), _jsxs("button", { type: "button", onClick: () => void handleConfirmSetup(), disabled: mfa.busy || !savedAcknowledged || verifyCode.length !== 6, className: "bg-brand text-brand-foreground inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50", children: [mfa.busy ? (_jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" })) : (_jsx(Check, { size: 16, "aria-hidden": "true" })), "Verify & enable"] })] })] }))] }));
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=AccountSecurity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountSecurity.js","sourceRoot":"","sources":["../../../src/views/profile/AccountSecurity.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type MfaStatus = 'loading' | 'enabled' | 'disabled' | 'error';
|
|
2
|
+
export interface MfaEnrollment {
|
|
3
|
+
/** otpauth:// URI to render as a QR code. */
|
|
4
|
+
uri: string;
|
|
5
|
+
/** Base32 secret for manual entry when a camera isn't available. */
|
|
6
|
+
secret: string;
|
|
7
|
+
/** One-time recovery codes — shown once, never retrievable again. */
|
|
8
|
+
backupCodes: string[];
|
|
9
|
+
}
|
|
10
|
+
interface ActionResult {
|
|
11
|
+
ok: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Drives the per-user MFA (TOTP) enrollment loop against the real auth API:
|
|
16
|
+
* 1. `beginSetup(password)` — password reauth → POST /auth/totp/setup, which
|
|
17
|
+
* returns the provisioning URI + one-time backup codes.
|
|
18
|
+
* 2. `confirmSetup(code)` — POST /auth/totp/verify to flip totpEnabled on.
|
|
19
|
+
* 3. `disable(password)` — password reauth → POST /auth/totp/disable.
|
|
20
|
+
*
|
|
21
|
+
* The hook never holds the user's password and never persists the secret or
|
|
22
|
+
* backup codes beyond the in-memory enrollment object (cleared on cancel/finish).
|
|
23
|
+
*/
|
|
24
|
+
export declare function useMfaEnrollment(): {
|
|
25
|
+
status: MfaStatus;
|
|
26
|
+
enrollment: MfaEnrollment | null;
|
|
27
|
+
busy: boolean;
|
|
28
|
+
refresh: () => Promise<void>;
|
|
29
|
+
beginSetup: (password: string) => Promise<ActionResult>;
|
|
30
|
+
confirmSetup: (code: string) => Promise<ActionResult>;
|
|
31
|
+
cancelSetup: () => void;
|
|
32
|
+
disable: (password: string) => Promise<ActionResult>;
|
|
33
|
+
};
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=useMfaEnrollment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMfaEnrollment.d.ts","sourceRoot":"","sources":["../../../src/views/profile/useMfaEnrollment.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAA;AAEpE,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAA;IACX,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,OAAO,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB;;;;;2BAkBkB,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC;yBAmBhC,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC;;wBAwB/B,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC;EA2B5E"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { cmsApi } from '../../lib/api.js';
|
|
4
|
+
/**
|
|
5
|
+
* Drives the per-user MFA (TOTP) enrollment loop against the real auth API:
|
|
6
|
+
* 1. `beginSetup(password)` — password reauth → POST /auth/totp/setup, which
|
|
7
|
+
* returns the provisioning URI + one-time backup codes.
|
|
8
|
+
* 2. `confirmSetup(code)` — POST /auth/totp/verify to flip totpEnabled on.
|
|
9
|
+
* 3. `disable(password)` — password reauth → POST /auth/totp/disable.
|
|
10
|
+
*
|
|
11
|
+
* The hook never holds the user's password and never persists the secret or
|
|
12
|
+
* backup codes beyond the in-memory enrollment object (cleared on cancel/finish).
|
|
13
|
+
*/
|
|
14
|
+
export function useMfaEnrollment() {
|
|
15
|
+
const [status, setStatus] = useState('loading');
|
|
16
|
+
const [enrollment, setEnrollment] = useState(null);
|
|
17
|
+
const [busy, setBusy] = useState(false);
|
|
18
|
+
const refresh = useCallback(async () => {
|
|
19
|
+
const res = await cmsApi('/auth/me');
|
|
20
|
+
if (res.error || !res.data) {
|
|
21
|
+
setStatus('error');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
setStatus(res.data.totpEnabled ? 'enabled' : 'disabled');
|
|
25
|
+
}, []);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
void refresh();
|
|
28
|
+
}, [refresh]);
|
|
29
|
+
const beginSetup = useCallback(async (password) => {
|
|
30
|
+
if (!password)
|
|
31
|
+
return { ok: false, error: 'Enter your current password to continue.' };
|
|
32
|
+
setBusy(true);
|
|
33
|
+
try {
|
|
34
|
+
const res = await cmsApi('/auth/totp/setup', {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: { 'x-reauth-password': password },
|
|
37
|
+
body: JSON.stringify({}),
|
|
38
|
+
});
|
|
39
|
+
if (res.error || !res.data) {
|
|
40
|
+
return { ok: false, error: res.error ?? 'Could not start MFA setup.' };
|
|
41
|
+
}
|
|
42
|
+
setEnrollment(res.data);
|
|
43
|
+
return { ok: true };
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
setBusy(false);
|
|
47
|
+
}
|
|
48
|
+
}, []);
|
|
49
|
+
const confirmSetup = useCallback(async (code) => {
|
|
50
|
+
const trimmed = code.trim();
|
|
51
|
+
if (!/^\d{6}$/.test(trimmed)) {
|
|
52
|
+
return { ok: false, error: 'Enter the 6-digit code from your authenticator app.' };
|
|
53
|
+
}
|
|
54
|
+
setBusy(true);
|
|
55
|
+
try {
|
|
56
|
+
const res = await cmsApi('/auth/totp/verify', {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
body: JSON.stringify({ code: trimmed }),
|
|
59
|
+
});
|
|
60
|
+
if (res.error)
|
|
61
|
+
return { ok: false, error: res.error };
|
|
62
|
+
setEnrollment(null);
|
|
63
|
+
setStatus('enabled');
|
|
64
|
+
return { ok: true };
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
setBusy(false);
|
|
68
|
+
}
|
|
69
|
+
}, []);
|
|
70
|
+
const cancelSetup = useCallback(() => {
|
|
71
|
+
setEnrollment(null);
|
|
72
|
+
}, []);
|
|
73
|
+
const disable = useCallback(async (password) => {
|
|
74
|
+
if (!password)
|
|
75
|
+
return { ok: false, error: 'Enter your current password to continue.' };
|
|
76
|
+
setBusy(true);
|
|
77
|
+
try {
|
|
78
|
+
const res = await cmsApi('/auth/totp/disable', {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers: { 'x-reauth-password': password },
|
|
81
|
+
body: JSON.stringify({}),
|
|
82
|
+
});
|
|
83
|
+
if (res.error)
|
|
84
|
+
return { ok: false, error: res.error };
|
|
85
|
+
setStatus('disabled');
|
|
86
|
+
return { ok: true };
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
setBusy(false);
|
|
90
|
+
}
|
|
91
|
+
}, []);
|
|
92
|
+
return {
|
|
93
|
+
status,
|
|
94
|
+
enrollment,
|
|
95
|
+
busy,
|
|
96
|
+
refresh,
|
|
97
|
+
beginSetup,
|
|
98
|
+
confirmSetup,
|
|
99
|
+
cancelSetup,
|
|
100
|
+
disable,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=useMfaEnrollment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMfaEnrollment.js","sourceRoot":"","sources":["../../../src/views/profile/useMfaEnrollment.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { SecurityForm } from './useSecuritySettings.js';
|
|
2
|
-
export declare function AuthMfaCard({ form, setField, canEdit, viewerHasMfa, withMfa, totalAdmins, }: {
|
|
2
|
+
export declare function AuthMfaCard({ form, setField, canEdit, viewerHasMfa, withMfa, totalAdmins, onNavigate, }: {
|
|
3
3
|
form: SecurityForm;
|
|
4
4
|
setField: <K extends keyof SecurityForm>(key: K, value: SecurityForm[K]) => void;
|
|
5
5
|
canEdit: boolean;
|
|
6
6
|
viewerHasMfa: boolean;
|
|
7
7
|
withMfa: number;
|
|
8
8
|
totalAdmins: number;
|
|
9
|
+
onNavigate?: (path: string) => void;
|
|
9
10
|
}): import("react/jsx-runtime").JSX.Element;
|
|
10
11
|
//# sourceMappingURL=AuthMfaCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthMfaCard.d.ts","sourceRoot":"","sources":["../../../src/views/settings/AuthMfaCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AuthMfaCard.d.ts","sourceRoot":"","sources":["../../../src/views/settings/AuthMfaCard.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAQ5D,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,OAAO,EACP,WAAW,EACX,UAAU,GACX,EAAE;IACD,IAAI,EAAE,YAAY,CAAA;IAClB,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAChF,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC,2CAqGA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useId, useState } from 'react';
|
|
4
|
+
import { ShieldCheck } from 'lucide-react';
|
|
4
5
|
import { MFA_GRACE_PERIOD_OPTIONS } from '@actuate-media/cms-core/security-center';
|
|
5
6
|
import { ConfirmDangerousSettingDialog, SettingsToggleRow } from './components.js';
|
|
6
7
|
import { SecurityCard, StatusRow } from './securityPrimitives.js';
|
|
@@ -11,7 +12,7 @@ function graceLabel(days) {
|
|
|
11
12
|
return '1 day';
|
|
12
13
|
return `${days} days`;
|
|
13
14
|
}
|
|
14
|
-
export function AuthMfaCard({ form, setField, canEdit, viewerHasMfa, withMfa, totalAdmins, }) {
|
|
15
|
+
export function AuthMfaCard({ form, setField, canEdit, viewerHasMfa, withMfa, totalAdmins, onNavigate, }) {
|
|
15
16
|
const headingId = useId();
|
|
16
17
|
const graceId = useId();
|
|
17
18
|
const [confirmEnable, setConfirmEnable] = useState(false);
|
|
@@ -25,7 +26,7 @@ export function AuthMfaCard({ form, setField, canEdit, viewerHasMfa, withMfa, to
|
|
|
25
26
|
// Lockout-safe: the toggle can't be turned on until the acting admin has
|
|
26
27
|
// their own MFA configured (the server enforces this too).
|
|
27
28
|
const mfaToggleDisabled = !canEdit || (!form.mfaRequired && !viewerHasMfa);
|
|
28
|
-
return (_jsxs(SecurityCard, { headingId: headingId, title: "Authentication & MFA", description: "Require multi-factor authentication for admin accounts and control the enrollment window.", children: [_jsxs("div", { className: "space-y-4", children: [_jsx(SettingsToggleRow, { label: "Require MFA for admin users", description: "Admins must set up a TOTP authenticator app. Existing admins are prompted to enroll within the grace period.", checked: form.mfaRequired, disabled: mfaToggleDisabled, onChange: requestMfaToggle }), _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("label", { htmlFor: graceId, className: "flex-1", children: [_jsx("span", { className: "text-foreground text-base font-medium", children: "Enrollment grace period" }), _jsx("p", { className: "text-muted-foreground mt-0.5 text-sm", children: "How long existing admins have to set up MFA before it is enforced." })] }), _jsx("select", { id: graceId, value: form.mfaGracePeriodDays, disabled: !canEdit || !form.mfaRequired, onChange: (e) => setField('mfaGracePeriodDays', Number(e.target.value)), className: "border-border bg-input-background text-foreground focus-visible:ring-ring rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", children: MFA_GRACE_PERIOD_OPTIONS.map((d) => (_jsx("option", { value: d, children: graceLabel(d) }, d))) })] })] }), _jsxs("div", { className: "border-border mt-4 space-y-2 border-t pt-4", children: [_jsx(StatusRow, { status: viewerHasMfa ? 'pass' : 'warning', label: "Your account", value: viewerHasMfa ? 'MFA enabled' : 'MFA not set up' }), !viewerHasMfa && (_jsx("p", { className: "text-muted-foreground text-sm", children: "Set up MFA on your own account before requiring it for everyone, or you may lock yourself out." })), _jsx(StatusRow, { status: totalAdmins === 0 ? 'unknown' : withMfa === totalAdmins ? 'pass' : 'warning', label: "Admin MFA coverage", value: totalAdmins === 0 ? 'No admins' : `${withMfa} of ${totalAdmins} admins` })] }), _jsx(ConfirmDangerousSettingDialog, { open: confirmEnable, title: "Require MFA for all admin users?", description: `Admins without MFA will be prompted to enroll and must complete setup within the grace period (${graceLabel(form.mfaGracePeriodDays)}). Make sure your own account has MFA configured first.`, confirmLabel: "Require MFA", onConfirm: () => {
|
|
29
|
+
return (_jsxs(SecurityCard, { headingId: headingId, title: "Authentication & MFA", description: "Require multi-factor authentication for admin accounts and control the enrollment window.", children: [_jsxs("div", { className: "space-y-4", children: [_jsx(SettingsToggleRow, { label: "Require MFA for admin users", description: "Admins must set up a TOTP authenticator app. Existing admins are prompted to enroll within the grace period.", checked: form.mfaRequired, disabled: mfaToggleDisabled, onChange: requestMfaToggle }), _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("label", { htmlFor: graceId, className: "flex-1", children: [_jsx("span", { className: "text-foreground text-base font-medium", children: "Enrollment grace period" }), _jsx("p", { className: "text-muted-foreground mt-0.5 text-sm", children: "How long existing admins have to set up MFA before it is enforced." })] }), _jsx("select", { id: graceId, value: form.mfaGracePeriodDays, disabled: !canEdit || !form.mfaRequired, onChange: (e) => setField('mfaGracePeriodDays', Number(e.target.value)), className: "border-border bg-input-background text-foreground focus-visible:ring-ring rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", children: MFA_GRACE_PERIOD_OPTIONS.map((d) => (_jsx("option", { value: d, children: graceLabel(d) }, d))) })] })] }), _jsxs("div", { className: "border-border mt-4 space-y-2 border-t pt-4", children: [_jsx(StatusRow, { status: viewerHasMfa ? 'pass' : 'warning', label: "Your account", value: viewerHasMfa ? 'MFA enabled' : 'MFA not set up' }), !viewerHasMfa && (_jsxs("div", { className: "space-y-2", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: "Set up MFA on your own account before requiring it for everyone, or you may lock yourself out." }), onNavigate && (_jsxs("button", { type: "button", onClick: () => onNavigate('/profile'), className: "border-border text-foreground hover:bg-accent inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm transition-colors", children: [_jsx(ShieldCheck, { size: 15, "aria-hidden": "true" }), "Set up MFA"] }))] })), _jsx(StatusRow, { status: totalAdmins === 0 ? 'unknown' : withMfa === totalAdmins ? 'pass' : 'warning', label: "Admin MFA coverage", value: totalAdmins === 0 ? 'No admins' : `${withMfa} of ${totalAdmins} admins` })] }), _jsx(ConfirmDangerousSettingDialog, { open: confirmEnable, title: "Require MFA for all admin users?", description: `Admins without MFA will be prompted to enroll and must complete setup within the grace period (${graceLabel(form.mfaGracePeriodDays)}). Make sure your own account has MFA configured first.`, confirmLabel: "Require MFA", onConfirm: () => {
|
|
29
30
|
setField('mfaRequired', true);
|
|
30
31
|
setConfirmEnable(false);
|
|
31
32
|
}, onCancel: () => setConfirmEnable(false) })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthMfaCard.js","sourceRoot":"","sources":["../../../src/views/settings/AuthMfaCard.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAA;AAClF,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGjE,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,aAAa,CAAA;IACpC,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,OAAO,CAAA;IAC9B,OAAO,GAAG,IAAI,OAAO,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,OAAO,EACP,WAAW,
|
|
1
|
+
{"version":3,"file":"AuthMfaCard.js","sourceRoot":"","sources":["../../../src/views/settings/AuthMfaCard.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAA;AAClF,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGjE,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,aAAa,CAAA;IACpC,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,OAAO,CAAA;IAC9B,OAAO,GAAG,IAAI,OAAO,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,OAAO,EACP,WAAW,EACX,UAAU,GASX;IACC,MAAM,SAAS,GAAG,KAAK,EAAE,CAAA;IACzB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAA;IACvB,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEzD,SAAS,gBAAgB,CAAC,KAAc;QACtC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/B,gBAAgB,CAAC,IAAI,CAAC,CAAA;YACtB,OAAM;QACR,CAAC;QACD,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IAChC,CAAC;IAED,yEAAyE;IACzE,2DAA2D;IAC3D,MAAM,iBAAiB,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,CAAA;IAE1E,OAAO,CACL,MAAC,YAAY,IACX,SAAS,EAAE,SAAS,EACpB,KAAK,EAAC,sBAAsB,EAC5B,WAAW,EAAC,2FAA2F,aAEvG,eAAK,SAAS,EAAC,WAAW,aACxB,KAAC,iBAAiB,IAChB,KAAK,EAAC,6BAA6B,EACnC,WAAW,EAAC,8GAA8G,EAC1H,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,gBAAgB,GAC1B,EAEF,eAAK,SAAS,EAAC,yCAAyC,aACtD,iBAAO,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,QAAQ,aACzC,eAAM,SAAS,EAAC,uCAAuC,wCAA+B,EACtF,YAAG,SAAS,EAAC,sCAAsC,mFAE/C,IACE,EACR,iBACE,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAC9B,QAAQ,EAAE,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EACvC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EACvE,SAAS,EAAC,+MAA+M,YAExN,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACnC,iBAAgB,KAAK,EAAE,CAAC,YACrB,UAAU,CAAC,CAAC,CAAC,IADH,CAAC,CAEL,CACV,CAAC,GACK,IACL,IACF,EAEN,eAAK,SAAS,EAAC,4CAA4C,aACzD,KAAC,SAAS,IACR,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACzC,KAAK,EAAC,cAAc,EACpB,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,GACtD,EACD,CAAC,YAAY,IAAI,CAChB,eAAK,SAAS,EAAC,WAAW,aACxB,YAAG,SAAS,EAAC,+BAA+B,+GAGxC,EACH,UAAU,IAAI,CACb,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EACrC,SAAS,EAAC,sIAAsI,aAEhJ,KAAC,WAAW,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,kBAErC,CACV,IACG,CACP,EACD,KAAC,SAAS,IACR,MAAM,EAAE,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACpF,KAAK,EAAC,oBAAoB,EAC1B,KAAK,EAAE,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,OAAO,WAAW,SAAS,GAC9E,IACE,EAEN,KAAC,6BAA6B,IAC5B,IAAI,EAAE,aAAa,EACnB,KAAK,EAAC,kCAAkC,EACxC,WAAW,EAAE,kGAAkG,UAAU,CACvH,IAAI,CAAC,kBAAkB,CACxB,yDAAyD,EAC1D,YAAY,EAAC,aAAa,EAC1B,SAAS,EAAE,GAAG,EAAE;oBACd,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;oBAC7B,gBAAgB,CAAC,KAAK,CAAC,CAAA;gBACzB,CAAC,EACD,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,GACvC,IACW,CAChB,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityTab.d.ts","sourceRoot":"","sources":["../../../src/views/settings/SecurityTab.tsx"],"names":[],"mappings":"AAyBA,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,UAAU,GACX,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC,
|
|
1
|
+
{"version":3,"file":"SecurityTab.d.ts","sourceRoot":"","sources":["../../../src/views/settings/SecurityTab.tsx"],"names":[],"mappings":"AAyBA,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,UAAU,GACX,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC,2CAmIA"}
|
|
@@ -36,6 +36,6 @@ export function SecurityTab({ role, onNavigate, }) {
|
|
|
36
36
|
? 'Ask an administrator to review the Security tab.'
|
|
37
37
|
: (loadError ?? 'The security service could not be reached. Try again shortly.') })] })] }));
|
|
38
38
|
}
|
|
39
|
-
return (_jsxs("div", { className: "space-y-4 pb-4", children: [_jsx(SecurityStatusCard, { status: data.status, onNavigate: onNavigate }), issues.length > 0 && _jsx(SettingsValidationSummary, { issues: issues }), !canEdit && (_jsx("p", { className: "text-muted-foreground text-sm", children: "You have read-only access. Only administrators can change security settings." })), _jsx(AuthMfaCard, { form: form, setField: setField, canEdit: canEdit, viewerHasMfa: data.viewerHasMfa, withMfa: data.users.withMfa, totalAdmins: data.users.totalAdmins }), _jsx("div", { id: "security-sessions", children: _jsx(SessionPolicyCard, { form: form, setField: setField, canEdit: canEdit, sessionMaxAgeHours: data.sessionMaxAgeHours, activeSessions: data.activeSessions, revokeState: revokeState, onRevokeAll: () => void revokeAllOtherSessions() }) }), _jsx("div", { id: "security-ip-allowlist", children: _jsx(AccessProtectionCard, { ipAllowlist: data.ipAllowlist, secrets: data.secrets, csrfEnabled: data.csrfEnabled, uploadValidation: data.uploadValidation, sources: data.sources, onNavigate: onNavigate }) }), _jsx("div", { id: "security-audit", children: _jsx(SecretsAuditCard, { secrets: data.secrets, auditEnabled: data.auditEnabled, failedLogins24h: data.failedLogins24h, users: data.users, apiKeys: data.apiKeys, sources: data.sources, onNavigate: onNavigate }) }), saveState === 'error' && (_jsx("p", { className: "text-destructive text-sm", role: "alert", children: "Failed to save security settings. Please try again." })), _jsx(SettingsSaveBar, { dirty: dirty, canEdit: canEdit, hasErrors: hasErrors, saveState: saveState, onSave: () => void save(), onReset: reset })] }));
|
|
39
|
+
return (_jsxs("div", { className: "space-y-4 pb-4", children: [_jsx(SecurityStatusCard, { status: data.status, onNavigate: onNavigate }), issues.length > 0 && _jsx(SettingsValidationSummary, { issues: issues }), !canEdit && (_jsx("p", { className: "text-muted-foreground text-sm", children: "You have read-only access. Only administrators can change security settings." })), _jsx(AuthMfaCard, { form: form, setField: setField, canEdit: canEdit, viewerHasMfa: data.viewerHasMfa, withMfa: data.users.withMfa, totalAdmins: data.users.totalAdmins, onNavigate: onNavigate }), _jsx("div", { id: "security-sessions", children: _jsx(SessionPolicyCard, { form: form, setField: setField, canEdit: canEdit, sessionMaxAgeHours: data.sessionMaxAgeHours, activeSessions: data.activeSessions, revokeState: revokeState, onRevokeAll: () => void revokeAllOtherSessions() }) }), _jsx("div", { id: "security-ip-allowlist", children: _jsx(AccessProtectionCard, { ipAllowlist: data.ipAllowlist, secrets: data.secrets, csrfEnabled: data.csrfEnabled, uploadValidation: data.uploadValidation, sources: data.sources, onNavigate: onNavigate }) }), _jsx("div", { id: "security-audit", children: _jsx(SecretsAuditCard, { secrets: data.secrets, auditEnabled: data.auditEnabled, failedLogins24h: data.failedLogins24h, users: data.users, apiKeys: data.apiKeys, sources: data.sources, onNavigate: onNavigate }) }), saveState === 'error' && (_jsx("p", { className: "text-destructive text-sm", role: "alert", children: "Failed to save security settings. Please try again." })), _jsx(SettingsSaveBar, { dirty: dirty, canEdit: canEdit, hasErrors: hasErrors, saveState: saveState, onSave: () => void save(), onReset: reset })] }));
|
|
40
40
|
}
|
|
41
41
|
//# sourceMappingURL=SecurityTab.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityTab.js","sourceRoot":"","sources":["../../../src/views/settings/SecurityTab.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SecurityTab.js","sourceRoot":"","sources":["../../../src/views/settings/SecurityTab.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actuate-media/cms-admin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/actuate-media/actuatecms.git",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"cmdk": "^1.1.1",
|
|
59
59
|
"lowlight": "^3.0.0",
|
|
60
60
|
"lucide-react": "^1.7.0",
|
|
61
|
+
"qrcode.react": "^4.2.0",
|
|
61
62
|
"react": "^19.2.0",
|
|
62
63
|
"react-dom": "^19.2.0",
|
|
63
64
|
"recharts": "^3.8.1",
|
|
@@ -87,7 +88,7 @@
|
|
|
87
88
|
"tailwindcss": "^4.0.0",
|
|
88
89
|
"typescript": "^5.7.0",
|
|
89
90
|
"vitest": "^4.1.0",
|
|
90
|
-
"@actuate-media/cms-core": "0.
|
|
91
|
+
"@actuate-media/cms-core": "0.39.0",
|
|
91
92
|
"@actuate-media/component-blocks": "0.2.0"
|
|
92
93
|
},
|
|
93
94
|
"scripts": {
|