strapi-identity 0.2.0 → 0.4.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/README.md +5 -2
- package/dist/admin/{AdminReset-CqHhVBS_.js → AdminReset-BiWQDTRv.js} +3 -4
- package/dist/admin/{AdminReset-B-WGECOX.mjs → AdminReset-DOmsyqwQ.mjs} +1 -2
- package/dist/admin/{ProfileToggle-BRYjt5Lu.js → ProfileToggle-BUqs_hxZ.js} +8 -218
- package/dist/admin/{ProfileToggle-BCtCsOvj.mjs → ProfileToggle-k0d-caPC.mjs} +2 -210
- package/dist/admin/{SettingsPage-DAxGIv_E.js → SettingsPage-DVVkN1xw.js} +3 -6
- package/dist/admin/{SettingsPage-7Ytl01jH.mjs → SettingsPage-Dm_llkYv.mjs} +1 -4
- package/dist/admin/{ar-DwZqj0qM.mjs → ar-B4yBU4m7.mjs} +7 -0
- package/dist/admin/{ar-BYnI7Tsa.js → ar-wjkCnUTi.js} +7 -0
- package/dist/admin/{ca-sBRHuaFU.js → ca-BHz1SCoK.js} +7 -0
- package/dist/admin/{ca-aKVVc8iQ.mjs → ca-DLE8GCgI.mjs} +7 -0
- package/dist/admin/{cs--prflMHS.mjs → cs-3kxvJ5GN.mjs} +7 -0
- package/dist/admin/{cs-gU7KP3Lx.js → cs-Echs10hb.js} +7 -0
- package/dist/admin/{de-BT25lv_6.mjs → de-BTldhzPN.mjs} +7 -0
- package/dist/admin/{de-CrlCAUuf.js → de-p5oK0g4T.js} +7 -0
- package/dist/admin/{dk-Ck3AQYU7.mjs → dk-CCNCrmIK.mjs} +7 -0
- package/dist/admin/{dk-BNC3WUzY.js → dk-Z6BhrTeh.js} +7 -0
- package/dist/admin/{en-9qzlpde0.mjs → en-1anycEwN.mjs} +7 -0
- package/dist/admin/{en-DBj0AD5g.js → en-CLnZaoOA.js} +7 -0
- package/dist/admin/{es-D5Sn41_H.js → es-C-4sXZ_R.js} +7 -0
- package/dist/admin/{es-lh6XoPb7.mjs → es-DMANTUCL.mjs} +7 -0
- package/dist/admin/{eu-Cuz6ijBX.mjs → eu-BITeCOIE.mjs} +7 -0
- package/dist/admin/{eu-Qr3RvDPW.js → eu-CHWReAeU.js} +7 -0
- package/dist/admin/{fr-ChlDcZsG.mjs → fr-C81x3RP3.mjs} +7 -0
- package/dist/admin/{fr-C4pmkPYn.js → fr-DH-kRY27.js} +7 -0
- package/dist/admin/{gu-BMZL76zM.js → gu-CDocz32V.js} +7 -0
- package/dist/admin/{gu-B6zyD1bW.mjs → gu-DDR6O_Dp.mjs} +7 -0
- package/dist/admin/{he-H6iBa45A.js → he-CKFM5685.js} +7 -0
- package/dist/admin/{he-C5V-qZCX.mjs → he-TPBr5x3o.mjs} +7 -0
- package/dist/admin/{hi-Be8rPk7I.js → hi-DqJ11ApQ.js} +7 -0
- package/dist/admin/{hi-czhOWo6-.mjs → hi-Pwt1EMiO.mjs} +7 -0
- package/dist/admin/{hu-NbZ3aiYV.mjs → hu-CTKkJzwl.mjs} +7 -0
- package/dist/admin/{hu-DKp6kOmc.js → hu-DFGcSNo0.js} +7 -0
- package/dist/admin/{id-NH9PvcR5.mjs → id-Bq3jNpUL.mjs} +7 -0
- package/dist/admin/{id-DO0bwFgY.js → id-ChXHR8aw.js} +7 -0
- package/dist/admin/{index-D03zlFnm.js → index-B9P8S4CX.js} +428 -9
- package/dist/admin/{index-BfC6z9N5.mjs → index-DpIJdETG.mjs} +439 -20
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/{it-Cmrey6tg.mjs → it-CgRQVAPr.mjs} +7 -0
- package/dist/admin/{it-Df6-7-M7.js → it-r0rbu0x0.js} +7 -0
- package/dist/admin/{ja-HuAq9ZwT.js → ja-27vNq46V.js} +7 -0
- package/dist/admin/{ja-DH3KMqOL.mjs → ja-2xaH1Qf2.mjs} +7 -0
- package/dist/admin/{ko-DPN28RE8.mjs → ko-CGgmfI4W.mjs} +7 -0
- package/dist/admin/{ko-S9k8KA8K.js → ko-Ci0l5h1b.js} +7 -0
- package/dist/admin/{ml-Bh9GGqcW.js → ml-Augll2or.js} +7 -0
- package/dist/admin/{ml-MsHNacm6.mjs → ml-aXIja392.mjs} +7 -0
- package/dist/admin/{ms-hO5YeEg4.js → ms-B8pBYl9n.js} +7 -0
- package/dist/admin/{ms-TjHAaxTd.mjs → ms-CLGR4CKx.mjs} +7 -0
- package/dist/admin/{nl-BLILZU8-.mjs → nl-CGFOqn_t.mjs} +7 -0
- package/dist/admin/{nl-BF98NBwL.js → nl-Cqn_nYD8.js} +7 -0
- package/dist/admin/{no-BtVZ-siy.mjs → no-BIbR3s2A.mjs} +7 -0
- package/dist/admin/{no-bl1OXlfa.js → no-DPF_xI-b.js} +7 -0
- package/dist/admin/{pl-DCSB6LwZ.mjs → pl-BBEIjPVT.mjs} +7 -0
- package/dist/admin/{pl-DCnOWIDw.js → pl-BjIa9TiI.js} +7 -0
- package/dist/admin/{pt-BR-D2_UrxTp.js → pt-BR-BbPay13q.js} +7 -0
- package/dist/admin/{pt-BR-CeLqmj88.mjs → pt-BR-C0S_4PYn.mjs} +7 -0
- package/dist/admin/{pt-DIu8RT_X.js → pt-DDhcHCz6.js} +7 -0
- package/dist/admin/{pt-fgjdOyW5.mjs → pt-DwDWDT_T.mjs} +7 -0
- package/dist/admin/{ru-BccMCf0l.js → ru-BzQ0SoFG.js} +7 -0
- package/dist/admin/{ru-B_hlpAyP.mjs → ru-DuxM9hFK.mjs} +7 -0
- package/dist/admin/{sa-D3A-fo85.js → sa-Cwsmxq_x.js} +7 -0
- package/dist/admin/{sa-BtuJ_I1t.mjs → sa-DfqNZDgh.mjs} +7 -0
- package/dist/admin/{sk-mmuTFlCK.mjs → sk-BcYzeG4F.mjs} +7 -0
- package/dist/admin/{sk-uSLC6KhO.js → sk-Coqlt4Kq.js} +7 -0
- package/dist/admin/{sv-CuKk5tE-.js → sv-9zwaCIfo.js} +7 -0
- package/dist/admin/{sv-BlaHc5ax.mjs → sv-CkoFHi6o.mjs} +7 -0
- package/dist/admin/{th-BwyhFaeE.mjs → th-C4FBlfLA.mjs} +7 -0
- package/dist/admin/{th-Bv3NKkYO.js → th-CFkjhGd6.js} +7 -0
- package/dist/admin/{tr-Bmvs-Hx-.js → tr-D0g7vqL1.js} +7 -0
- package/dist/admin/{tr-BLocNlbZ.mjs → tr-Djsa55Fh.mjs} +7 -0
- package/dist/admin/{uk-CyZ10xtq.mjs → uk-BDoDjhO2.mjs} +7 -0
- package/dist/admin/{uk-BDxn-EZU.js → uk-Dw1MGmom.js} +7 -0
- package/dist/admin/{vi-Bx_UJ8up.mjs → vi-D977KjlZ.mjs} +7 -0
- package/dist/admin/{vi-F_mqQCme.js → vi-DNZKFaOu.js} +7 -0
- package/dist/admin/{zh-CFZJPG5N.js → zh-C2aozMiZ.js} +7 -0
- package/dist/admin/{zh-CjJdRa3l.mjs → zh-CKYKCaVd.mjs} +7 -0
- package/dist/admin/{zh-Hans-s7G2GUHU.mjs → zh-Hans-DNgRcEC-.mjs} +7 -0
- package/dist/admin/{zh-Hans-4BhSwSQw.js → zh-Hans-ellQkyo7.js} +7 -0
- package/dist/server/index.js +88 -16
- package/dist/server/index.mjs +88 -16
- package/package.json +3 -3
- package/dist/admin/tokenHelpers-DagDzpso.mjs +0 -22
- package/dist/admin/tokenHelpers-jtoRu0q5.js +0 -21
package/README.md
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Detailed Multi-Factor Authentication (MFA) plugin for Strapi v5+. Secure your Strapi Admin panel with TOTP-based 2FA, fully integrated into the Strapi interface.
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
5
7
|
## Features
|
|
6
8
|
|
|
7
9
|
- **MFA Login Interception**: Seamlessly integrates with the default Strapi login flow.
|
|
8
10
|
- **TOTP Compatibility**: Works with all major authenticator apps (Google Authenticator, Authy, 1Password, etc.).
|
|
9
11
|
- **Recovery Codes**: Generates secure recovery codes for emergency access.
|
|
10
12
|
- **Email Passcode**: Option to receive a one-time passcode via email as an alternative MFA method.
|
|
13
|
+
- **Enforced mode**: Prevent a user from accessing the CMS until 2FA is setup on their account.
|
|
11
14
|
- **Native UI Integration**:
|
|
12
15
|
- Matches Strapi's design system.
|
|
13
16
|
- Profile integration for easy setup.
|
|
@@ -62,7 +65,7 @@ Access the global settings via the admin panel:
|
|
|
62
65
|
| Option | Description |
|
|
63
66
|
| ----------- | ------------------------------------------------------------------------------------------ |
|
|
64
67
|
| **Enabled** | Master switch to enable or disable the MFA interception logic globally. |
|
|
65
|
-
| **Enforce** |
|
|
68
|
+
| **Enforce** | Force all users to set up MFA before accessing the dashboard. |
|
|
66
69
|
| **Issuer** | The name that appears in the authenticator app (e.g., "My Project"). Defaults to "Strapi". |
|
|
67
70
|
|
|
68
71
|
### Permissions
|
|
@@ -116,4 +119,4 @@ Below is the implementation status of planned features.
|
|
|
116
119
|
- [x] **Multi-language Support**: i18n ready.
|
|
117
120
|
- [x] **Admin Reset**: Allow super-admins to reset MFA for other users who lost access.
|
|
118
121
|
- [x] **Email Passcode**: Alternative MFA method via Email.
|
|
119
|
-
- [
|
|
122
|
+
- [x] **Enforced Mode**: Mandatory MFA for all users.
|
|
@@ -4,8 +4,7 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const React = require("react");
|
|
5
5
|
const WarningAlert = require("./WarningAlert-DFE5euMk.js");
|
|
6
6
|
const designSystem = require("@strapi/design-system");
|
|
7
|
-
const index = require("./index-
|
|
8
|
-
const tokenHelpers = require("./tokenHelpers-jtoRu0q5.js");
|
|
7
|
+
const index = require("./index-B9P8S4CX.js");
|
|
9
8
|
const reactIntl = require("react-intl");
|
|
10
9
|
const AdminReset = ({ id }) => {
|
|
11
10
|
const { formatMessage } = reactIntl.useIntl();
|
|
@@ -13,7 +12,7 @@ const AdminReset = ({ id }) => {
|
|
|
13
12
|
const [warningOpen, setWarningOpen] = React.useState(false);
|
|
14
13
|
const [loading, setLoading] = React.useState(false);
|
|
15
14
|
const handleReset = async () => {
|
|
16
|
-
const token =
|
|
15
|
+
const token = index.getToken();
|
|
17
16
|
setLoading(true);
|
|
18
17
|
try {
|
|
19
18
|
const response = await fetch(`/strapi-identity/admin/user/${id}`, {
|
|
@@ -32,7 +31,7 @@ const AdminReset = ({ id }) => {
|
|
|
32
31
|
React.useEffect(() => {
|
|
33
32
|
if (!id) return;
|
|
34
33
|
const ac = new AbortController();
|
|
35
|
-
const token =
|
|
34
|
+
const token = index.getToken();
|
|
36
35
|
(async () => {
|
|
37
36
|
try {
|
|
38
37
|
const response = await fetch(`/strapi-identity/admin/user/${id}`, {
|
|
@@ -2,8 +2,7 @@ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useEffect } from "react";
|
|
3
3
|
import { W as WarningAlert } from "./WarningAlert-VU011LVF.mjs";
|
|
4
4
|
import { Box, Flex, Typography, Grid, Button } from "@strapi/design-system";
|
|
5
|
-
import { g as getTranslation } from "./index-
|
|
6
|
-
import { g as getToken } from "./tokenHelpers-DagDzpso.mjs";
|
|
5
|
+
import { g as getToken, a as getTranslation } from "./index-DpIJdETG.mjs";
|
|
7
6
|
import { useIntl } from "react-intl";
|
|
8
7
|
const AdminReset = ({ id }) => {
|
|
9
8
|
const { formatMessage } = useIntl();
|
|
@@ -3,79 +3,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const React = require("react");
|
|
5
5
|
const designSystem = require("@strapi/design-system");
|
|
6
|
-
const
|
|
7
|
-
const index = require("./index-D03zlFnm.js");
|
|
8
|
-
const qrcode_react = require("qrcode.react");
|
|
6
|
+
const index = require("./index-B9P8S4CX.js");
|
|
9
7
|
const reactIntl = require("react-intl");
|
|
10
|
-
const tokenHelpers = require("./tokenHelpers-jtoRu0q5.js");
|
|
11
|
-
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
12
|
-
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
13
|
-
function ConfirmModal({
|
|
14
|
-
open,
|
|
15
|
-
onOpenChange,
|
|
16
|
-
onSubmit,
|
|
17
|
-
qrCodeUri,
|
|
18
|
-
secret,
|
|
19
|
-
passcodes
|
|
20
|
-
}) {
|
|
21
|
-
const { formatMessage } = reactIntl.useIntl();
|
|
22
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit, children: [
|
|
23
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: formatMessage({
|
|
24
|
-
id: index.getTranslation("profile.setup"),
|
|
25
|
-
defaultMessage: "Set up Two-Factor Authentication"
|
|
26
|
-
}) }) }),
|
|
27
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: passcodes ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
28
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
|
|
29
|
-
id: index.getTranslation("profile.recovery_codes"),
|
|
30
|
-
defaultMessage: "Please save the following recovery codes in a safe place. Each code can only be used once to access your account if you lose access to your authenticator app."
|
|
31
|
-
}) }),
|
|
32
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, marginTop: 4, marginBottom: 4, children: passcodes.map((code) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", children: code }) }, code)) }),
|
|
33
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textAlign: "center", children: formatMessage({
|
|
34
|
-
id: index.getTranslation("profile.recovery_codes_warning"),
|
|
35
|
-
defaultMessage: "If you lose both your authenticator app and your recovery codes, you will need to contact an administrator to regain access to your account."
|
|
36
|
-
}) })
|
|
37
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", children: [
|
|
38
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
39
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
|
40
|
-
id: index.getTranslation("profile.scan_qr"),
|
|
41
|
-
defaultMessage: "You will need an authenticator app to scan the QR code below."
|
|
42
|
-
}) }),
|
|
43
|
-
qrCodeUri && /* @__PURE__ */ jsxRuntime.jsx(qrcode_react.QRCodeCanvas, { value: qrCodeUri, size: 256 }),
|
|
44
|
-
secret && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", children: secret || "" })
|
|
45
|
-
] }),
|
|
46
|
-
/* @__PURE__ */ jsxRuntime.jsx(Rule, {}),
|
|
47
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
48
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
|
49
|
-
id: index.getTranslation("profile.enter_otp"),
|
|
50
|
-
defaultMessage: "Enter the 6-digit code from your authenticator app to confirm."
|
|
51
|
-
}) }),
|
|
52
|
-
/* @__PURE__ */ jsxRuntime.jsxs(index.InputOTP, { maxLength: 6, name: "otp", id: "otp", autoFocus: true, children: [
|
|
53
|
-
/* @__PURE__ */ jsxRuntime.jsxs(index.InputOTPGroup, { children: [
|
|
54
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 0 }),
|
|
55
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 1 }),
|
|
56
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 2 })
|
|
57
|
-
] }),
|
|
58
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSeparator, {}),
|
|
59
|
-
/* @__PURE__ */ jsxRuntime.jsxs(index.InputOTPGroup, { children: [
|
|
60
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 3 }),
|
|
61
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 4 }),
|
|
62
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 5 })
|
|
63
|
-
] })
|
|
64
|
-
] })
|
|
65
|
-
] })
|
|
66
|
-
] }) }),
|
|
67
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
|
68
|
-
passcodes && /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
69
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: passcodes ? void 0 : "tertiary", children: passcodes ? formatMessage({ id: "global.close", defaultMessage: "Close" }) : formatMessage({ id: "app.components.Button.cancel", defaultMessage: "Cancel" }) }) }),
|
|
70
|
-
!passcodes && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", children: formatMessage({ id: "app.components.Button.confirm", defaultMessage: "Confirm" }) })
|
|
71
|
-
] })
|
|
72
|
-
] }) }) });
|
|
73
|
-
}
|
|
74
|
-
const Rule = styled__default.default.hr`
|
|
75
|
-
height: 1px;
|
|
76
|
-
border: 0;
|
|
77
|
-
background-color: #e5e5e5;
|
|
78
|
-
`;
|
|
79
8
|
function RemoveModal({ open, onOpenChange, onSubmit }) {
|
|
80
9
|
const { formatMessage } = reactIntl.useIntl();
|
|
81
10
|
const [showRecovery, setShowRecovery] = React.useState(false);
|
|
@@ -124,145 +53,6 @@ function RemoveModal({ open, onOpenChange, onSubmit }) {
|
|
|
124
53
|
] })
|
|
125
54
|
] }) }) });
|
|
126
55
|
}
|
|
127
|
-
function EmailOTPModal({
|
|
128
|
-
mode,
|
|
129
|
-
open,
|
|
130
|
-
email,
|
|
131
|
-
onOpenChange,
|
|
132
|
-
onSuccess
|
|
133
|
-
}) {
|
|
134
|
-
const { formatMessage } = reactIntl.useIntl();
|
|
135
|
-
const [step, setStep] = React.useState("send");
|
|
136
|
-
const [loading, setLoading] = React.useState(false);
|
|
137
|
-
const [error, setError] = React.useState(null);
|
|
138
|
-
const handleOpenChange = (nextOpen) => {
|
|
139
|
-
if (!nextOpen) {
|
|
140
|
-
setStep("send");
|
|
141
|
-
setError(null);
|
|
142
|
-
}
|
|
143
|
-
onOpenChange(nextOpen);
|
|
144
|
-
};
|
|
145
|
-
const handleSend = async () => {
|
|
146
|
-
const token = tokenHelpers.getToken();
|
|
147
|
-
setLoading(true);
|
|
148
|
-
setError(null);
|
|
149
|
-
try {
|
|
150
|
-
const endpoint = mode === "setup" ? "/strapi-identity/enable-email" : "/strapi-identity/disable-email/request";
|
|
151
|
-
const response = await fetch(endpoint, {
|
|
152
|
-
method: "POST",
|
|
153
|
-
headers: { "Content-Type": "application/json", authorization: `Bearer ${token}` }
|
|
154
|
-
});
|
|
155
|
-
const body = await response.json();
|
|
156
|
-
if (!response.ok) {
|
|
157
|
-
throw new Error(body.error || "Failed to send verification email");
|
|
158
|
-
}
|
|
159
|
-
setStep("confirm");
|
|
160
|
-
} catch (err) {
|
|
161
|
-
setError(err.message);
|
|
162
|
-
} finally {
|
|
163
|
-
setLoading(false);
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
const handleConfirm = async (e) => {
|
|
167
|
-
e.preventDefault();
|
|
168
|
-
const token = tokenHelpers.getToken();
|
|
169
|
-
const formData = new FormData(e.target);
|
|
170
|
-
const code = formData.get("otp");
|
|
171
|
-
setLoading(true);
|
|
172
|
-
setError(null);
|
|
173
|
-
try {
|
|
174
|
-
const endpoint = mode === "setup" ? "/strapi-identity/setup-email" : "/strapi-identity/disable";
|
|
175
|
-
const response = await fetch(endpoint, {
|
|
176
|
-
method: "POST",
|
|
177
|
-
headers: { "Content-Type": "application/json", authorization: `Bearer ${token}` },
|
|
178
|
-
body: JSON.stringify({ code })
|
|
179
|
-
});
|
|
180
|
-
const body = await response.json();
|
|
181
|
-
if (!response.ok) {
|
|
182
|
-
throw new Error(body.error || "Invalid or expired code");
|
|
183
|
-
}
|
|
184
|
-
handleOpenChange(false);
|
|
185
|
-
onSuccess();
|
|
186
|
-
} catch (err) {
|
|
187
|
-
setError(err.message);
|
|
188
|
-
} finally {
|
|
189
|
-
setLoading(false);
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
const title = mode === "setup" ? formatMessage({
|
|
193
|
-
id: index.getTranslation("email_otp.setup_title"),
|
|
194
|
-
defaultMessage: "Enable Email OTP"
|
|
195
|
-
}) : formatMessage({
|
|
196
|
-
id: index.getTranslation("email_otp.disable_title"),
|
|
197
|
-
defaultMessage: "Disable Email OTP"
|
|
198
|
-
});
|
|
199
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
|
200
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
|
201
|
-
step === "send" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
202
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
203
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: mode === "setup" ? formatMessage(
|
|
204
|
-
{
|
|
205
|
-
id: index.getTranslation("email_otp.setup_description"),
|
|
206
|
-
defaultMessage: "We'll send a 6-digit verification code to {email}. Enter it to enable Email OTP."
|
|
207
|
-
},
|
|
208
|
-
{ email: /* @__PURE__ */ jsxRuntime.jsx("strong", { children: email }) }
|
|
209
|
-
) : formatMessage(
|
|
210
|
-
{
|
|
211
|
-
id: index.getTranslation("email_otp.disable_description"),
|
|
212
|
-
defaultMessage: "We'll send a 6-digit verification code to {email}. Enter it to disable Email OTP."
|
|
213
|
-
},
|
|
214
|
-
{ email: /* @__PURE__ */ jsxRuntime.jsx("strong", { children: email }) }
|
|
215
|
-
) }),
|
|
216
|
-
error ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { role: "alert", textColor: "danger600", textAlign: "center", children: error }) : null
|
|
217
|
-
] }) }),
|
|
218
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
|
219
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({ id: "app.components.Button.cancel", defaultMessage: "Cancel" }) }) }),
|
|
220
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleSend, loading, children: formatMessage({
|
|
221
|
-
id: index.getTranslation("email_otp.send_code"),
|
|
222
|
-
defaultMessage: "Send verification email"
|
|
223
|
-
}) })
|
|
224
|
-
] })
|
|
225
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleConfirm, children: [
|
|
226
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
227
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage(
|
|
228
|
-
{
|
|
229
|
-
id: index.getTranslation("email_otp.confirm_description"),
|
|
230
|
-
defaultMessage: "Enter the 6-digit code sent to {email}."
|
|
231
|
-
},
|
|
232
|
-
{ email: /* @__PURE__ */ jsxRuntime.jsx("strong", { children: email }) }
|
|
233
|
-
) }),
|
|
234
|
-
/* @__PURE__ */ jsxRuntime.jsxs(index.InputOTP, { maxLength: 6, name: "otp", id: "otp", autoFocus: true, children: [
|
|
235
|
-
/* @__PURE__ */ jsxRuntime.jsxs(index.InputOTPGroup, { children: [
|
|
236
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 0 }),
|
|
237
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 1 }),
|
|
238
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 2 })
|
|
239
|
-
] }),
|
|
240
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSeparator, {}),
|
|
241
|
-
/* @__PURE__ */ jsxRuntime.jsxs(index.InputOTPGroup, { children: [
|
|
242
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 3 }),
|
|
243
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 4 }),
|
|
244
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.InputOTPSlot, { index: 5 })
|
|
245
|
-
] })
|
|
246
|
-
] }),
|
|
247
|
-
error ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { role: "alert", textColor: "danger600", textAlign: "center", children: error }) : null,
|
|
248
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "ghost", type: "button", onClick: () => handleSend(), children: formatMessage({
|
|
249
|
-
id: index.getTranslation("email_otp.resend_code"),
|
|
250
|
-
defaultMessage: "Resend code"
|
|
251
|
-
}) })
|
|
252
|
-
] }) }),
|
|
253
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
|
254
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
|
255
|
-
id: "app.components.Button.cancel",
|
|
256
|
-
defaultMessage: "Cancel"
|
|
257
|
-
}) }) }),
|
|
258
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", loading, children: formatMessage({
|
|
259
|
-
id: "app.components.Button.confirm",
|
|
260
|
-
defaultMessage: "Confirm"
|
|
261
|
-
}) })
|
|
262
|
-
] })
|
|
263
|
-
] })
|
|
264
|
-
] }) });
|
|
265
|
-
}
|
|
266
56
|
const ProfileToggle = () => {
|
|
267
57
|
const { formatMessage } = reactIntl.useIntl();
|
|
268
58
|
const [enabled, setEnabled] = React.useState(null);
|
|
@@ -278,7 +68,7 @@ const ProfileToggle = () => {
|
|
|
278
68
|
const [secret, setSecret] = React.useState(null);
|
|
279
69
|
const [passcodes, setPasscodes] = React.useState(null);
|
|
280
70
|
const handleToggle = async ({ target }) => {
|
|
281
|
-
const token =
|
|
71
|
+
const token = index.getToken();
|
|
282
72
|
const enable = target?.checked || false;
|
|
283
73
|
if (!enable && enabled === "full") {
|
|
284
74
|
setDisableDialogOpen(true);
|
|
@@ -329,7 +119,7 @@ const ProfileToggle = () => {
|
|
|
329
119
|
const form = e.target;
|
|
330
120
|
const formData = new FormData(form);
|
|
331
121
|
const code = formData.get("otp");
|
|
332
|
-
const token =
|
|
122
|
+
const token = index.getToken();
|
|
333
123
|
try {
|
|
334
124
|
const response = await fetch("/strapi-identity/setup", {
|
|
335
125
|
method: "POST",
|
|
@@ -365,7 +155,7 @@ const ProfileToggle = () => {
|
|
|
365
155
|
const form = e.target;
|
|
366
156
|
const formData = new FormData(form);
|
|
367
157
|
const code = formData.get("otp");
|
|
368
|
-
const token =
|
|
158
|
+
const token = index.getToken();
|
|
369
159
|
try {
|
|
370
160
|
const response = await fetch("/strapi-identity/disable", {
|
|
371
161
|
method: "POST",
|
|
@@ -388,7 +178,7 @@ const ProfileToggle = () => {
|
|
|
388
178
|
React.useEffect(() => {
|
|
389
179
|
const ac = new AbortController();
|
|
390
180
|
(async () => {
|
|
391
|
-
const token =
|
|
181
|
+
const token = index.getToken();
|
|
392
182
|
try {
|
|
393
183
|
const [statusRes, enabledRes, meRes] = await Promise.all([
|
|
394
184
|
fetch("/strapi-identity/status", {
|
|
@@ -541,7 +331,7 @@ const ProfileToggle = () => {
|
|
|
541
331
|
}
|
|
542
332
|
),
|
|
543
333
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
544
|
-
ConfirmModal,
|
|
334
|
+
index.ConfirmModal,
|
|
545
335
|
{
|
|
546
336
|
open: modalOpen,
|
|
547
337
|
onOpenChange: handleClose,
|
|
@@ -560,7 +350,7 @@ const ProfileToggle = () => {
|
|
|
560
350
|
}
|
|
561
351
|
),
|
|
562
352
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
563
|
-
EmailOTPModal,
|
|
353
|
+
index.EmailOTPModal,
|
|
564
354
|
{
|
|
565
355
|
mode: "setup",
|
|
566
356
|
open: emailSetupOpen,
|
|
@@ -576,7 +366,7 @@ const ProfileToggle = () => {
|
|
|
576
366
|
}
|
|
577
367
|
),
|
|
578
368
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
579
|
-
EmailOTPModal,
|
|
369
|
+
index.EmailOTPModal,
|
|
580
370
|
{
|
|
581
371
|
mode: "disable",
|
|
582
372
|
open: emailDisableOpen,
|
|
@@ -1,77 +1,8 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect } from "react";
|
|
3
|
-
import { Modal, Flex, Typography,
|
|
4
|
-
import
|
|
5
|
-
import { g as getTranslation, I as InputOTP, a as InputOTPGroup, b as InputOTPSlot, c as InputOTPSeparator } from "./index-BfC6z9N5.mjs";
|
|
6
|
-
import { QRCodeCanvas } from "qrcode.react";
|
|
3
|
+
import { Modal, Flex, Typography, TextInput, Button, Box, Grid, Field, Toggle } from "@strapi/design-system";
|
|
4
|
+
import { a as getTranslation, I as InputOTP, b as InputOTPGroup, c as InputOTPSlot, d as InputOTPSeparator, g as getToken, C as ConfirmModal, E as EmailOTPModal } from "./index-DpIJdETG.mjs";
|
|
7
5
|
import { useIntl } from "react-intl";
|
|
8
|
-
import { g as getToken } from "./tokenHelpers-DagDzpso.mjs";
|
|
9
|
-
function ConfirmModal({
|
|
10
|
-
open,
|
|
11
|
-
onOpenChange,
|
|
12
|
-
onSubmit,
|
|
13
|
-
qrCodeUri,
|
|
14
|
-
secret,
|
|
15
|
-
passcodes
|
|
16
|
-
}) {
|
|
17
|
-
const { formatMessage } = useIntl();
|
|
18
|
-
return /* @__PURE__ */ jsx(Modal.Root, { open, onOpenChange, children: /* @__PURE__ */ jsx(Modal.Content, { children: /* @__PURE__ */ jsxs("form", { onSubmit, children: [
|
|
19
|
-
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: formatMessage({
|
|
20
|
-
id: getTranslation("profile.setup"),
|
|
21
|
-
defaultMessage: "Set up Two-Factor Authentication"
|
|
22
|
-
}) }) }),
|
|
23
|
-
/* @__PURE__ */ jsx(Modal.Body, { children: passcodes ? /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
24
|
-
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
|
25
|
-
id: getTranslation("profile.recovery_codes"),
|
|
26
|
-
defaultMessage: "Please save the following recovery codes in a safe place. Each code can only be used once to access your account if you lose access to your authenticator app."
|
|
27
|
-
}) }),
|
|
28
|
-
/* @__PURE__ */ jsx(Grid.Root, { gap: 4, marginTop: 4, marginBottom: 4, children: passcodes.map((code) => /* @__PURE__ */ jsx(Grid.Item, { col: 6, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", children: code }) }, code)) }),
|
|
29
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textAlign: "center", children: formatMessage({
|
|
30
|
-
id: getTranslation("profile.recovery_codes_warning"),
|
|
31
|
-
defaultMessage: "If you lose both your authenticator app and your recovery codes, you will need to contact an administrator to regain access to your account."
|
|
32
|
-
}) })
|
|
33
|
-
] }) : /* @__PURE__ */ jsxs(Flex, { direction: "column", children: [
|
|
34
|
-
/* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
35
|
-
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
|
36
|
-
id: getTranslation("profile.scan_qr"),
|
|
37
|
-
defaultMessage: "You will need an authenticator app to scan the QR code below."
|
|
38
|
-
}) }),
|
|
39
|
-
qrCodeUri && /* @__PURE__ */ jsx(QRCodeCanvas, { value: qrCodeUri, size: 256 }),
|
|
40
|
-
secret && /* @__PURE__ */ jsx(Typography, { variant: "pi", children: secret || "" })
|
|
41
|
-
] }),
|
|
42
|
-
/* @__PURE__ */ jsx(Rule, {}),
|
|
43
|
-
/* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
44
|
-
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
|
45
|
-
id: getTranslation("profile.enter_otp"),
|
|
46
|
-
defaultMessage: "Enter the 6-digit code from your authenticator app to confirm."
|
|
47
|
-
}) }),
|
|
48
|
-
/* @__PURE__ */ jsxs(InputOTP, { maxLength: 6, name: "otp", id: "otp", autoFocus: true, children: [
|
|
49
|
-
/* @__PURE__ */ jsxs(InputOTPGroup, { children: [
|
|
50
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 0 }),
|
|
51
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 1 }),
|
|
52
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 2 })
|
|
53
|
-
] }),
|
|
54
|
-
/* @__PURE__ */ jsx(InputOTPSeparator, {}),
|
|
55
|
-
/* @__PURE__ */ jsxs(InputOTPGroup, { children: [
|
|
56
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 3 }),
|
|
57
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 4 }),
|
|
58
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 5 })
|
|
59
|
-
] })
|
|
60
|
-
] })
|
|
61
|
-
] })
|
|
62
|
-
] }) }),
|
|
63
|
-
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
64
|
-
passcodes && /* @__PURE__ */ jsx("span", {}),
|
|
65
|
-
/* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(Button, { variant: passcodes ? void 0 : "tertiary", children: passcodes ? formatMessage({ id: "global.close", defaultMessage: "Close" }) : formatMessage({ id: "app.components.Button.cancel", defaultMessage: "Cancel" }) }) }),
|
|
66
|
-
!passcodes && /* @__PURE__ */ jsx(Button, { type: "submit", children: formatMessage({ id: "app.components.Button.confirm", defaultMessage: "Confirm" }) })
|
|
67
|
-
] })
|
|
68
|
-
] }) }) });
|
|
69
|
-
}
|
|
70
|
-
const Rule = styled.hr`
|
|
71
|
-
height: 1px;
|
|
72
|
-
border: 0;
|
|
73
|
-
background-color: #e5e5e5;
|
|
74
|
-
`;
|
|
75
6
|
function RemoveModal({ open, onOpenChange, onSubmit }) {
|
|
76
7
|
const { formatMessage } = useIntl();
|
|
77
8
|
const [showRecovery, setShowRecovery] = useState(false);
|
|
@@ -120,145 +51,6 @@ function RemoveModal({ open, onOpenChange, onSubmit }) {
|
|
|
120
51
|
] })
|
|
121
52
|
] }) }) });
|
|
122
53
|
}
|
|
123
|
-
function EmailOTPModal({
|
|
124
|
-
mode,
|
|
125
|
-
open,
|
|
126
|
-
email,
|
|
127
|
-
onOpenChange,
|
|
128
|
-
onSuccess
|
|
129
|
-
}) {
|
|
130
|
-
const { formatMessage } = useIntl();
|
|
131
|
-
const [step, setStep] = useState("send");
|
|
132
|
-
const [loading, setLoading] = useState(false);
|
|
133
|
-
const [error, setError] = useState(null);
|
|
134
|
-
const handleOpenChange = (nextOpen) => {
|
|
135
|
-
if (!nextOpen) {
|
|
136
|
-
setStep("send");
|
|
137
|
-
setError(null);
|
|
138
|
-
}
|
|
139
|
-
onOpenChange(nextOpen);
|
|
140
|
-
};
|
|
141
|
-
const handleSend = async () => {
|
|
142
|
-
const token = getToken();
|
|
143
|
-
setLoading(true);
|
|
144
|
-
setError(null);
|
|
145
|
-
try {
|
|
146
|
-
const endpoint = mode === "setup" ? "/strapi-identity/enable-email" : "/strapi-identity/disable-email/request";
|
|
147
|
-
const response = await fetch(endpoint, {
|
|
148
|
-
method: "POST",
|
|
149
|
-
headers: { "Content-Type": "application/json", authorization: `Bearer ${token}` }
|
|
150
|
-
});
|
|
151
|
-
const body = await response.json();
|
|
152
|
-
if (!response.ok) {
|
|
153
|
-
throw new Error(body.error || "Failed to send verification email");
|
|
154
|
-
}
|
|
155
|
-
setStep("confirm");
|
|
156
|
-
} catch (err) {
|
|
157
|
-
setError(err.message);
|
|
158
|
-
} finally {
|
|
159
|
-
setLoading(false);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
const handleConfirm = async (e) => {
|
|
163
|
-
e.preventDefault();
|
|
164
|
-
const token = getToken();
|
|
165
|
-
const formData = new FormData(e.target);
|
|
166
|
-
const code = formData.get("otp");
|
|
167
|
-
setLoading(true);
|
|
168
|
-
setError(null);
|
|
169
|
-
try {
|
|
170
|
-
const endpoint = mode === "setup" ? "/strapi-identity/setup-email" : "/strapi-identity/disable";
|
|
171
|
-
const response = await fetch(endpoint, {
|
|
172
|
-
method: "POST",
|
|
173
|
-
headers: { "Content-Type": "application/json", authorization: `Bearer ${token}` },
|
|
174
|
-
body: JSON.stringify({ code })
|
|
175
|
-
});
|
|
176
|
-
const body = await response.json();
|
|
177
|
-
if (!response.ok) {
|
|
178
|
-
throw new Error(body.error || "Invalid or expired code");
|
|
179
|
-
}
|
|
180
|
-
handleOpenChange(false);
|
|
181
|
-
onSuccess();
|
|
182
|
-
} catch (err) {
|
|
183
|
-
setError(err.message);
|
|
184
|
-
} finally {
|
|
185
|
-
setLoading(false);
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
const title = mode === "setup" ? formatMessage({
|
|
189
|
-
id: getTranslation("email_otp.setup_title"),
|
|
190
|
-
defaultMessage: "Enable Email OTP"
|
|
191
|
-
}) : formatMessage({
|
|
192
|
-
id: getTranslation("email_otp.disable_title"),
|
|
193
|
-
defaultMessage: "Disable Email OTP"
|
|
194
|
-
});
|
|
195
|
-
return /* @__PURE__ */ jsx(Modal.Root, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
|
196
|
-
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
|
197
|
-
step === "send" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
198
|
-
/* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
199
|
-
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: mode === "setup" ? formatMessage(
|
|
200
|
-
{
|
|
201
|
-
id: getTranslation("email_otp.setup_description"),
|
|
202
|
-
defaultMessage: "We'll send a 6-digit verification code to {email}. Enter it to enable Email OTP."
|
|
203
|
-
},
|
|
204
|
-
{ email: /* @__PURE__ */ jsx("strong", { children: email }) }
|
|
205
|
-
) : formatMessage(
|
|
206
|
-
{
|
|
207
|
-
id: getTranslation("email_otp.disable_description"),
|
|
208
|
-
defaultMessage: "We'll send a 6-digit verification code to {email}. Enter it to disable Email OTP."
|
|
209
|
-
},
|
|
210
|
-
{ email: /* @__PURE__ */ jsx("strong", { children: email }) }
|
|
211
|
-
) }),
|
|
212
|
-
error ? /* @__PURE__ */ jsx(Typography, { role: "alert", textColor: "danger600", textAlign: "center", children: error }) : null
|
|
213
|
-
] }) }),
|
|
214
|
-
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
215
|
-
/* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({ id: "app.components.Button.cancel", defaultMessage: "Cancel" }) }) }),
|
|
216
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleSend, loading, children: formatMessage({
|
|
217
|
-
id: getTranslation("email_otp.send_code"),
|
|
218
|
-
defaultMessage: "Send verification email"
|
|
219
|
-
}) })
|
|
220
|
-
] })
|
|
221
|
-
] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleConfirm, children: [
|
|
222
|
-
/* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 4, marginTop: 4, marginBottom: 4, children: [
|
|
223
|
-
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage(
|
|
224
|
-
{
|
|
225
|
-
id: getTranslation("email_otp.confirm_description"),
|
|
226
|
-
defaultMessage: "Enter the 6-digit code sent to {email}."
|
|
227
|
-
},
|
|
228
|
-
{ email: /* @__PURE__ */ jsx("strong", { children: email }) }
|
|
229
|
-
) }),
|
|
230
|
-
/* @__PURE__ */ jsxs(InputOTP, { maxLength: 6, name: "otp", id: "otp", autoFocus: true, children: [
|
|
231
|
-
/* @__PURE__ */ jsxs(InputOTPGroup, { children: [
|
|
232
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 0 }),
|
|
233
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 1 }),
|
|
234
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 2 })
|
|
235
|
-
] }),
|
|
236
|
-
/* @__PURE__ */ jsx(InputOTPSeparator, {}),
|
|
237
|
-
/* @__PURE__ */ jsxs(InputOTPGroup, { children: [
|
|
238
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 3 }),
|
|
239
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 4 }),
|
|
240
|
-
/* @__PURE__ */ jsx(InputOTPSlot, { index: 5 })
|
|
241
|
-
] })
|
|
242
|
-
] }),
|
|
243
|
-
error ? /* @__PURE__ */ jsx(Typography, { role: "alert", textColor: "danger600", textAlign: "center", children: error }) : null,
|
|
244
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", type: "button", onClick: () => handleSend(), children: formatMessage({
|
|
245
|
-
id: getTranslation("email_otp.resend_code"),
|
|
246
|
-
defaultMessage: "Resend code"
|
|
247
|
-
}) })
|
|
248
|
-
] }) }),
|
|
249
|
-
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
250
|
-
/* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
|
251
|
-
id: "app.components.Button.cancel",
|
|
252
|
-
defaultMessage: "Cancel"
|
|
253
|
-
}) }) }),
|
|
254
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", loading, children: formatMessage({
|
|
255
|
-
id: "app.components.Button.confirm",
|
|
256
|
-
defaultMessage: "Confirm"
|
|
257
|
-
}) })
|
|
258
|
-
] })
|
|
259
|
-
] })
|
|
260
|
-
] }) });
|
|
261
|
-
}
|
|
262
54
|
const ProfileToggle = () => {
|
|
263
55
|
const { formatMessage } = useIntl();
|
|
264
56
|
const [enabled, setEnabled] = useState(null);
|
|
@@ -6,8 +6,7 @@ const WarningAlert = require("./WarningAlert-DFE5euMk.js");
|
|
|
6
6
|
const admin = require("@strapi/strapi/admin");
|
|
7
7
|
const designSystem = require("@strapi/design-system");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
|
-
const index = require("./index-
|
|
10
|
-
const tokenHelpers = require("./tokenHelpers-jtoRu0q5.js");
|
|
9
|
+
const index = require("./index-B9P8S4CX.js");
|
|
11
10
|
const reactIntl = require("react-intl");
|
|
12
11
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
13
12
|
var lodash$1 = { exports: {} };
|
|
@@ -5611,7 +5610,6 @@ function SettingsPage() {
|
|
|
5611
5610
|
setSaving(true);
|
|
5612
5611
|
const formData = new FormData(event.currentTarget);
|
|
5613
5612
|
const values = getConfigFromForm(formData);
|
|
5614
|
-
console.log(formData, values);
|
|
5615
5613
|
if (initialConfig?.enabled && !values.enabled && !confirmed) {
|
|
5616
5614
|
setShowWarning(true);
|
|
5617
5615
|
setSaving(false);
|
|
@@ -5623,7 +5621,7 @@ function SettingsPage() {
|
|
|
5623
5621
|
return;
|
|
5624
5622
|
}
|
|
5625
5623
|
try {
|
|
5626
|
-
const token =
|
|
5624
|
+
const token = index.getToken();
|
|
5627
5625
|
const response = await fetch("/strapi-identity/config", {
|
|
5628
5626
|
method: "PUT",
|
|
5629
5627
|
headers: {
|
|
@@ -5659,7 +5657,7 @@ function SettingsPage() {
|
|
|
5659
5657
|
};
|
|
5660
5658
|
React.useEffect(() => {
|
|
5661
5659
|
const ac = new AbortController();
|
|
5662
|
-
const token =
|
|
5660
|
+
const token = index.getToken();
|
|
5663
5661
|
(async () => {
|
|
5664
5662
|
try {
|
|
5665
5663
|
const response = await fetch("/strapi-identity/config", {
|
|
@@ -5775,7 +5773,6 @@ function SettingsPage() {
|
|
|
5775
5773
|
designSystem.Toggle,
|
|
5776
5774
|
{
|
|
5777
5775
|
name: "enforce",
|
|
5778
|
-
disabled: true,
|
|
5779
5776
|
checked: enforce,
|
|
5780
5777
|
onChange: ({ target }) => setEnforce(target.checked),
|
|
5781
5778
|
offLabel: formatMessage({
|
|
@@ -4,8 +4,7 @@ import { W as WarningAlert } from "./WarningAlert-VU011LVF.mjs";
|
|
|
4
4
|
import { useNotification, Page, Layouts } from "@strapi/strapi/admin";
|
|
5
5
|
import { Button, Flex, Typography, Grid, Field, Toggle, TextInput, Textarea } from "@strapi/design-system";
|
|
6
6
|
import { Check } from "@strapi/icons";
|
|
7
|
-
import { g as getTranslation } from "./index-
|
|
8
|
-
import { g as getToken } from "./tokenHelpers-DagDzpso.mjs";
|
|
7
|
+
import { g as getToken, a as getTranslation } from "./index-DpIJdETG.mjs";
|
|
9
8
|
import { useIntl } from "react-intl";
|
|
10
9
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
11
10
|
var lodash$1 = { exports: {} };
|
|
@@ -5609,7 +5608,6 @@ function SettingsPage() {
|
|
|
5609
5608
|
setSaving(true);
|
|
5610
5609
|
const formData = new FormData(event.currentTarget);
|
|
5611
5610
|
const values = getConfigFromForm(formData);
|
|
5612
|
-
console.log(formData, values);
|
|
5613
5611
|
if (initialConfig?.enabled && !values.enabled && !confirmed) {
|
|
5614
5612
|
setShowWarning(true);
|
|
5615
5613
|
setSaving(false);
|
|
@@ -5773,7 +5771,6 @@ function SettingsPage() {
|
|
|
5773
5771
|
Toggle,
|
|
5774
5772
|
{
|
|
5775
5773
|
name: "enforce",
|
|
5776
|
-
disabled: true,
|
|
5777
5774
|
checked: enforce,
|
|
5778
5775
|
onChange: ({ target }) => setEnforce(target.checked),
|
|
5779
5776
|
offLabel: formatMessage({
|