strapi-plugin-magic-sessionmanager 4.5.1 → 4.5.3
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/_chunks/{Analytics-DQyamHg6.mjs → Analytics--qB2cKuD.mjs} +2 -2
- package/dist/_chunks/{Analytics-Cp-WjeV3.js → Analytics-DM4_UffY.js} +2 -2
- package/dist/_chunks/{App-CN4bKWV9.mjs → App-CL5q29Mi.mjs} +2 -2
- package/dist/_chunks/{App-BvYLeEbF.js → App-DF-VsbDW.js} +2 -2
- package/dist/_chunks/{License-Bgcm630d.mjs → License-D9piCp34.mjs} +1 -1
- package/dist/_chunks/{License-DPyeZQWz.js → License-Dmm1d3fQ.js} +1 -1
- package/dist/_chunks/{OnlineUsersWidget-E2FA7rGi.mjs → OnlineUsersWidget-DHsthkt0.mjs} +1 -1
- package/dist/_chunks/{OnlineUsersWidget-BYnqhN3O.js → OnlineUsersWidget-KchZ_ScS.js} +1 -1
- package/dist/_chunks/{Settings-Bt6wy131.js → Settings-CUNaxDWk.js} +255 -2
- package/dist/_chunks/{Settings-D9N7m11p.mjs → Settings-D6ILgR9X.mjs} +255 -2
- package/dist/_chunks/{UpgradePage-DM23ZYVa.mjs → UpgradePage-D697BVWo.mjs} +1 -1
- package/dist/_chunks/{UpgradePage-Bh21Lg-G.js → UpgradePage-Dwrv7g8L.js} +1 -1
- package/dist/_chunks/{index-BRESWp1b.js → index-CTxGMDHr.js} +6 -6
- package/dist/_chunks/{index-BbbrBv3t.mjs → index-CwxKazpc.mjs} +6 -6
- package/dist/_chunks/{useLicense-Bszkymz3.mjs → useLicense-B9WW9s_d.mjs} +1 -1
- package/dist/_chunks/{useLicense-D_wQcoMn.js → useLicense-BEbtA_Zo.js} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +526 -200
- package/dist/server/index.mjs +526 -200
- package/package.json +1 -1
|
@@ -4,8 +4,8 @@ import { useFetchClient } from "@strapi/strapi/admin";
|
|
|
4
4
|
import styled, { css, keyframes } from "styled-components";
|
|
5
5
|
import { Loader, Typography, Box, Flex, Badge } from "@strapi/design-system";
|
|
6
6
|
import { ChartBubble, Crown, User, Clock, Monitor } from "@strapi/icons";
|
|
7
|
-
import { a as pluginId } from "./index-
|
|
8
|
-
import { u as useLicense } from "./useLicense-
|
|
7
|
+
import { a as pluginId } from "./index-CwxKazpc.mjs";
|
|
8
|
+
import { u as useLicense } from "./useLicense-B9WW9s_d.mjs";
|
|
9
9
|
const theme = {
|
|
10
10
|
shadows: {
|
|
11
11
|
sm: "0 1px 3px 0 rgba(0, 0, 0, 0.1)",
|
|
@@ -6,8 +6,8 @@ const admin = require("@strapi/strapi/admin");
|
|
|
6
6
|
const styled = require("styled-components");
|
|
7
7
|
const designSystem = require("@strapi/design-system");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
|
-
const index = require("./index-
|
|
10
|
-
const useLicense = require("./useLicense-
|
|
9
|
+
const index = require("./index-CTxGMDHr.js");
|
|
10
|
+
const useLicense = require("./useLicense-BEbtA_Zo.js");
|
|
11
11
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
12
12
|
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
13
13
|
const theme = {
|
|
@@ -3,10 +3,10 @@ import { useState, useEffect } from "react";
|
|
|
3
3
|
import { useIntl } from "react-intl";
|
|
4
4
|
import { useFetchClient, useNotification, Page } from "@strapi/strapi/admin";
|
|
5
5
|
import styled, { css, keyframes } from "styled-components";
|
|
6
|
-
import { p as parseUserAgent, a as pluginId$1, g as getTranslation } from "./index-
|
|
6
|
+
import { p as parseUserAgent, a as pluginId$1, g as getTranslation } from "./index-CwxKazpc.mjs";
|
|
7
7
|
import { Modal, Flex, Box, Typography, Divider, Button, Loader, SingleSelect, SingleSelectOption, Thead, Tr, Th, Tbody, Td, Table, TextInput } from "@strapi/design-system";
|
|
8
8
|
import { Check, Information, Monitor, Server, Clock, Cross, Earth, Shield, Crown, Phone, Download, User, Eye, Trash, Search, Key } from "@strapi/icons";
|
|
9
|
-
import { u as useLicense } from "./useLicense-
|
|
9
|
+
import { u as useLicense } from "./useLicense-B9WW9s_d.mjs";
|
|
10
10
|
import { S as ShowHideButton, T as TertiaryButton, D as DangerButton, I as IconButtonPrimary, a as IconButtonWarning, b as IconButtonDanger } from "./StyledButtons-Cz8oYhmc.mjs";
|
|
11
11
|
import { useNavigate } from "react-router-dom";
|
|
12
12
|
const theme = {
|
|
@@ -5,10 +5,10 @@ const react = require("react");
|
|
|
5
5
|
const reactIntl = require("react-intl");
|
|
6
6
|
const admin = require("@strapi/strapi/admin");
|
|
7
7
|
const styled = require("styled-components");
|
|
8
|
-
const index = require("./index-
|
|
8
|
+
const index = require("./index-CTxGMDHr.js");
|
|
9
9
|
const designSystem = require("@strapi/design-system");
|
|
10
10
|
const icons = require("@strapi/icons");
|
|
11
|
-
const useLicense = require("./useLicense-
|
|
11
|
+
const useLicense = require("./useLicense-BEbtA_Zo.js");
|
|
12
12
|
const StyledButtons = require("./StyledButtons-DDuxnYz8.js");
|
|
13
13
|
const reactRouterDom = require("react-router-dom");
|
|
14
14
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
@@ -4,7 +4,7 @@ import { Loader, Box, Alert, Flex, Typography, Button, Badge, Accordion } from "
|
|
|
4
4
|
import { useFetchClient, useNotification } from "@strapi/strapi/admin";
|
|
5
5
|
import { ArrowClockwise, Duplicate, Download, User, Shield, Sparkle, ChartBubble } from "@strapi/icons";
|
|
6
6
|
import styled, { css, keyframes } from "styled-components";
|
|
7
|
-
import { a as pluginId } from "./index-
|
|
7
|
+
import { a as pluginId } from "./index-CwxKazpc.mjs";
|
|
8
8
|
const theme = {
|
|
9
9
|
borderRadius: { lg: "12px" }
|
|
10
10
|
};
|
|
@@ -6,7 +6,7 @@ const designSystem = require("@strapi/design-system");
|
|
|
6
6
|
const admin = require("@strapi/strapi/admin");
|
|
7
7
|
const icons = require("@strapi/icons");
|
|
8
8
|
const styled = require("styled-components");
|
|
9
|
-
const index = require("./index-
|
|
9
|
+
const index = require("./index-CTxGMDHr.js");
|
|
10
10
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
11
11
|
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
12
12
|
const theme = {
|
|
@@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
|
|
|
4
4
|
import { Box, Typography, Flex, Grid } from "@strapi/design-system";
|
|
5
5
|
import { Check, Cross, Clock, User } from "@strapi/icons";
|
|
6
6
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
7
|
-
import { g as getTranslation } from "./index-
|
|
7
|
+
import { g as getTranslation } from "./index-CwxKazpc.mjs";
|
|
8
8
|
const OnlineUsersWidget = () => {
|
|
9
9
|
const { formatMessage } = useIntl();
|
|
10
10
|
const { get } = useFetchClient();
|
|
@@ -6,7 +6,7 @@ const reactIntl = require("react-intl");
|
|
|
6
6
|
const designSystem = require("@strapi/design-system");
|
|
7
7
|
const icons = require("@strapi/icons");
|
|
8
8
|
const admin = require("@strapi/strapi/admin");
|
|
9
|
-
const index = require("./index-
|
|
9
|
+
const index = require("./index-CTxGMDHr.js");
|
|
10
10
|
const OnlineUsersWidget = () => {
|
|
11
11
|
const { formatMessage } = reactIntl.useIntl();
|
|
12
12
|
const { get } = admin.useFetchClient();
|
|
@@ -7,11 +7,85 @@ const designSystem = require("@strapi/design-system");
|
|
|
7
7
|
const admin = require("@strapi/strapi/admin");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
const styled = require("styled-components");
|
|
10
|
-
const index = require("./index-
|
|
11
|
-
const useLicense = require("./useLicense-
|
|
10
|
+
const index = require("./index-CTxGMDHr.js");
|
|
11
|
+
const useLicense = require("./useLicense-BEbtA_Zo.js");
|
|
12
12
|
const StyledButtons = require("./StyledButtons-DDuxnYz8.js");
|
|
13
13
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
14
14
|
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
15
|
+
const COUNTRIES = [
|
|
16
|
+
{ code: "DE", name: "Germany", flag: "🇩🇪" },
|
|
17
|
+
{ code: "AT", name: "Austria", flag: "🇦🇹" },
|
|
18
|
+
{ code: "CH", name: "Switzerland", flag: "🇨🇭" },
|
|
19
|
+
{ code: "US", name: "United States", flag: "🇺🇸" },
|
|
20
|
+
{ code: "CA", name: "Canada", flag: "🇨🇦" },
|
|
21
|
+
{ code: "MX", name: "Mexico", flag: "🇲🇽" },
|
|
22
|
+
{ code: "GB", name: "United Kingdom", flag: "🇬🇧" },
|
|
23
|
+
{ code: "IE", name: "Ireland", flag: "🇮🇪" },
|
|
24
|
+
{ code: "FR", name: "France", flag: "🇫🇷" },
|
|
25
|
+
{ code: "IT", name: "Italy", flag: "🇮🇹" },
|
|
26
|
+
{ code: "ES", name: "Spain", flag: "🇪🇸" },
|
|
27
|
+
{ code: "PT", name: "Portugal", flag: "🇵🇹" },
|
|
28
|
+
{ code: "NL", name: "Netherlands", flag: "🇳🇱" },
|
|
29
|
+
{ code: "BE", name: "Belgium", flag: "🇧🇪" },
|
|
30
|
+
{ code: "LU", name: "Luxembourg", flag: "🇱🇺" },
|
|
31
|
+
{ code: "SE", name: "Sweden", flag: "🇸🇪" },
|
|
32
|
+
{ code: "NO", name: "Norway", flag: "🇳🇴" },
|
|
33
|
+
{ code: "DK", name: "Denmark", flag: "🇩🇰" },
|
|
34
|
+
{ code: "FI", name: "Finland", flag: "🇫🇮" },
|
|
35
|
+
{ code: "PL", name: "Poland", flag: "🇵🇱" },
|
|
36
|
+
{ code: "CZ", name: "Czech Republic", flag: "🇨🇿" },
|
|
37
|
+
{ code: "SK", name: "Slovakia", flag: "🇸🇰" },
|
|
38
|
+
{ code: "HU", name: "Hungary", flag: "🇭🇺" },
|
|
39
|
+
{ code: "RO", name: "Romania", flag: "🇷🇴" },
|
|
40
|
+
{ code: "BG", name: "Bulgaria", flag: "🇧🇬" },
|
|
41
|
+
{ code: "GR", name: "Greece", flag: "🇬🇷" },
|
|
42
|
+
{ code: "HR", name: "Croatia", flag: "🇭🇷" },
|
|
43
|
+
{ code: "SI", name: "Slovenia", flag: "🇸🇮" },
|
|
44
|
+
{ code: "EE", name: "Estonia", flag: "🇪🇪" },
|
|
45
|
+
{ code: "LV", name: "Latvia", flag: "🇱🇻" },
|
|
46
|
+
{ code: "LT", name: "Lithuania", flag: "🇱🇹" },
|
|
47
|
+
{ code: "IS", name: "Iceland", flag: "🇮🇸" },
|
|
48
|
+
{ code: "TR", name: "Turkey", flag: "🇹🇷" },
|
|
49
|
+
{ code: "RU", name: "Russia", flag: "🇷🇺" },
|
|
50
|
+
{ code: "UA", name: "Ukraine", flag: "🇺🇦" },
|
|
51
|
+
{ code: "BR", name: "Brazil", flag: "🇧🇷" },
|
|
52
|
+
{ code: "AR", name: "Argentina", flag: "🇦🇷" },
|
|
53
|
+
{ code: "CL", name: "Chile", flag: "🇨🇱" },
|
|
54
|
+
{ code: "CO", name: "Colombia", flag: "🇨🇴" },
|
|
55
|
+
{ code: "AU", name: "Australia", flag: "🇦🇺" },
|
|
56
|
+
{ code: "NZ", name: "New Zealand", flag: "🇳🇿" },
|
|
57
|
+
{ code: "JP", name: "Japan", flag: "🇯🇵" },
|
|
58
|
+
{ code: "KR", name: "South Korea", flag: "🇰🇷" },
|
|
59
|
+
{ code: "CN", name: "China", flag: "🇨🇳" },
|
|
60
|
+
{ code: "HK", name: "Hong Kong", flag: "🇭🇰" },
|
|
61
|
+
{ code: "TW", name: "Taiwan", flag: "🇹🇼" },
|
|
62
|
+
{ code: "SG", name: "Singapore", flag: "🇸🇬" },
|
|
63
|
+
{ code: "IN", name: "India", flag: "🇮🇳" },
|
|
64
|
+
{ code: "ID", name: "Indonesia", flag: "🇮🇩" },
|
|
65
|
+
{ code: "TH", name: "Thailand", flag: "🇹🇭" },
|
|
66
|
+
{ code: "VN", name: "Vietnam", flag: "🇻🇳" },
|
|
67
|
+
{ code: "PH", name: "Philippines", flag: "🇵🇭" },
|
|
68
|
+
{ code: "MY", name: "Malaysia", flag: "🇲🇾" },
|
|
69
|
+
{ code: "AE", name: "United Arab Emirates", flag: "🇦🇪" },
|
|
70
|
+
{ code: "SA", name: "Saudi Arabia", flag: "🇸🇦" },
|
|
71
|
+
{ code: "IL", name: "Israel", flag: "🇮🇱" },
|
|
72
|
+
{ code: "EG", name: "Egypt", flag: "🇪🇬" },
|
|
73
|
+
{ code: "ZA", name: "South Africa", flag: "🇿🇦" },
|
|
74
|
+
{ code: "NG", name: "Nigeria", flag: "🇳🇬" },
|
|
75
|
+
{ code: "KE", name: "Kenya", flag: "🇰🇪" },
|
|
76
|
+
{ code: "MA", name: "Morocco", flag: "🇲🇦" }
|
|
77
|
+
];
|
|
78
|
+
const normalizeCountryCode = (raw) => {
|
|
79
|
+
if (typeof raw !== "string") return null;
|
|
80
|
+
const up = raw.trim().toUpperCase();
|
|
81
|
+
if (!/^[A-Z]{2}$/.test(up)) return null;
|
|
82
|
+
return up;
|
|
83
|
+
};
|
|
84
|
+
const formatCountry = (code) => {
|
|
85
|
+
if (!code) return "";
|
|
86
|
+
const match = COUNTRIES.find((c) => c.code === code);
|
|
87
|
+
return match ? `${match.flag} ${match.name} (${match.code})` : code;
|
|
88
|
+
};
|
|
15
89
|
const theme = {
|
|
16
90
|
borderRadius: { md: "8px", lg: "12px" }
|
|
17
91
|
};
|
|
@@ -331,6 +405,167 @@ const generateSecureKey = () => {
|
|
|
331
405
|
}
|
|
332
406
|
return key;
|
|
333
407
|
};
|
|
408
|
+
const GeofencingPanel = ({ settings, handleChange, t }) => {
|
|
409
|
+
const [pendingCode, setPendingCode] = react.useState("");
|
|
410
|
+
const mode = (() => {
|
|
411
|
+
if (Array.isArray(settings.allowedCountries) && settings.allowedCountries.length > 0) {
|
|
412
|
+
return "allowlist";
|
|
413
|
+
}
|
|
414
|
+
if (Array.isArray(settings.blockedCountries) && settings.blockedCountries.length > 0) {
|
|
415
|
+
return "blocklist";
|
|
416
|
+
}
|
|
417
|
+
return "allowlist";
|
|
418
|
+
})();
|
|
419
|
+
const activeField = mode === "allowlist" ? "allowedCountries" : "blockedCountries";
|
|
420
|
+
const activeList = Array.isArray(settings[activeField]) ? settings[activeField] : [];
|
|
421
|
+
const setMode = (newMode) => {
|
|
422
|
+
if (newMode === mode) return;
|
|
423
|
+
if (newMode === "allowlist") {
|
|
424
|
+
handleChange("blockedCountries", []);
|
|
425
|
+
} else {
|
|
426
|
+
handleChange("allowedCountries", []);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
const addCode = (raw) => {
|
|
430
|
+
const code = normalizeCountryCode(raw);
|
|
431
|
+
if (!code) return;
|
|
432
|
+
if (activeList.includes(code)) return;
|
|
433
|
+
handleChange(activeField, [...activeList, code]);
|
|
434
|
+
setPendingCode("");
|
|
435
|
+
};
|
|
436
|
+
const removeCode = (code) => {
|
|
437
|
+
handleChange(activeField, activeList.filter((c) => c !== code));
|
|
438
|
+
};
|
|
439
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 5, children: [
|
|
440
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
441
|
+
designSystem.Box,
|
|
442
|
+
{
|
|
443
|
+
padding: 3,
|
|
444
|
+
background: settings.enableGeofencing ? "success100" : "neutral100",
|
|
445
|
+
hasRadius: true,
|
|
446
|
+
style: { borderLeft: `4px solid ${settings.enableGeofencing ? "#16A34A" : "#9CA3AF"}` },
|
|
447
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
448
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
|
|
449
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", style: { display: "block", marginBottom: "4px" }, children: t("settings.geofencing.enable.title", "Enable Geofencing") }),
|
|
450
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: t(
|
|
451
|
+
"settings.geofencing.enable.description",
|
|
452
|
+
"When enabled, the pre-login guard compares the caller's country against the configured list and rejects logins that do not match."
|
|
453
|
+
) })
|
|
454
|
+
] }),
|
|
455
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
456
|
+
designSystem.Toggle,
|
|
457
|
+
{
|
|
458
|
+
onLabel: "On",
|
|
459
|
+
offLabel: "Off",
|
|
460
|
+
checked: !!settings.enableGeofencing,
|
|
461
|
+
onChange: () => handleChange("enableGeofencing", !settings.enableGeofencing)
|
|
462
|
+
}
|
|
463
|
+
)
|
|
464
|
+
] })
|
|
465
|
+
}
|
|
466
|
+
) }),
|
|
467
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
|
|
468
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: t("settings.geofencing.mode.title", "Mode") }),
|
|
469
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
|
470
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
471
|
+
designSystem.Button,
|
|
472
|
+
{
|
|
473
|
+
variant: mode === "allowlist" ? "default" : "tertiary",
|
|
474
|
+
onClick: () => setMode("allowlist"),
|
|
475
|
+
disabled: !settings.enableGeofencing,
|
|
476
|
+
children: t("settings.geofencing.mode.allowlist", "Allowlist (only selected countries)")
|
|
477
|
+
}
|
|
478
|
+
),
|
|
479
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
480
|
+
designSystem.Button,
|
|
481
|
+
{
|
|
482
|
+
variant: mode === "blocklist" ? "default" : "tertiary",
|
|
483
|
+
onClick: () => setMode("blocklist"),
|
|
484
|
+
disabled: !settings.enableGeofencing,
|
|
485
|
+
children: t("settings.geofencing.mode.blocklist", "Blocklist (block selected countries)")
|
|
486
|
+
}
|
|
487
|
+
)
|
|
488
|
+
] }),
|
|
489
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: mode === "allowlist" ? t(
|
|
490
|
+
"settings.geofencing.mode.allowlist.hint",
|
|
491
|
+
"Only countries in the list may authenticate. Empty list = no geo restriction."
|
|
492
|
+
) : t(
|
|
493
|
+
"settings.geofencing.mode.blocklist.hint",
|
|
494
|
+
"Every country EXCEPT those in the list may authenticate."
|
|
495
|
+
) })
|
|
496
|
+
] }) }),
|
|
497
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
|
|
498
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: mode === "allowlist" ? t("settings.geofencing.allowed.title", "Allowed Countries") : t("settings.geofencing.blocked.title", "Blocked Countries") }),
|
|
499
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, wrap: "wrap", style: { marginBottom: "12px", minHeight: "36px" }, children: activeList.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: t("settings.geofencing.empty", "No countries configured.") }) : activeList.map((code) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
500
|
+
designSystem.Badge,
|
|
501
|
+
{
|
|
502
|
+
onClick: settings.enableGeofencing ? () => removeCode(code) : void 0,
|
|
503
|
+
style: {
|
|
504
|
+
cursor: settings.enableGeofencing ? "pointer" : "not-allowed",
|
|
505
|
+
padding: "6px 10px",
|
|
506
|
+
background: mode === "allowlist" ? "#DCFCE7" : "#FEE2E2",
|
|
507
|
+
color: mode === "allowlist" ? "#15803D" : "#B91C1C"
|
|
508
|
+
},
|
|
509
|
+
children: [
|
|
510
|
+
formatCountry(code),
|
|
511
|
+
settings.enableGeofencing ? " ✕" : ""
|
|
512
|
+
]
|
|
513
|
+
},
|
|
514
|
+
code
|
|
515
|
+
)) }),
|
|
516
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
|
517
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
518
|
+
designSystem.SingleSelect,
|
|
519
|
+
{
|
|
520
|
+
disabled: !settings.enableGeofencing,
|
|
521
|
+
value: pendingCode || "",
|
|
522
|
+
onChange: (value) => {
|
|
523
|
+
setPendingCode(value);
|
|
524
|
+
if (value) addCode(value);
|
|
525
|
+
},
|
|
526
|
+
placeholder: t("settings.geofencing.pick", "Pick a country to add…"),
|
|
527
|
+
children: COUNTRIES.filter((c) => !activeList.includes(c.code)).map((c) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.SingleSelectOption, { value: c.code, children: [
|
|
528
|
+
c.flag,
|
|
529
|
+
" ",
|
|
530
|
+
c.name,
|
|
531
|
+
" (",
|
|
532
|
+
c.code,
|
|
533
|
+
")"
|
|
534
|
+
] }, c.code))
|
|
535
|
+
}
|
|
536
|
+
) }),
|
|
537
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
538
|
+
designSystem.TextInput,
|
|
539
|
+
{
|
|
540
|
+
disabled: !settings.enableGeofencing,
|
|
541
|
+
placeholder: t("settings.geofencing.manual", "Or type ISO-2 (e.g. JP)"),
|
|
542
|
+
value: pendingCode.length <= 2 ? pendingCode : "",
|
|
543
|
+
onChange: (e) => setPendingCode(e.target.value.toUpperCase().slice(0, 2)),
|
|
544
|
+
style: { width: "180px" }
|
|
545
|
+
}
|
|
546
|
+
),
|
|
547
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
548
|
+
designSystem.Button,
|
|
549
|
+
{
|
|
550
|
+
disabled: !settings.enableGeofencing || !normalizeCountryCode(pendingCode),
|
|
551
|
+
onClick: () => addCode(pendingCode),
|
|
552
|
+
children: t("settings.geofencing.add", "Add")
|
|
553
|
+
}
|
|
554
|
+
)
|
|
555
|
+
] })
|
|
556
|
+
] }) }),
|
|
557
|
+
!settings.enableGeofencing && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "default", closeLabel: "", title: "", onClose: () => {
|
|
558
|
+
}, children: t(
|
|
559
|
+
"settings.geofencing.disabled",
|
|
560
|
+
"Geofencing is currently disabled. Enable it above to enforce the configured country list."
|
|
561
|
+
) }) }),
|
|
562
|
+
settings.enableGeofencing && !settings.enableGeolocation && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "warning", closeLabel: "", title: "", onClose: () => {
|
|
563
|
+
}, children: t(
|
|
564
|
+
"settings.geofencing.needsGeolocation",
|
|
565
|
+
"Geofencing requires Geolocation to be enabled (Security tab)."
|
|
566
|
+
) }) })
|
|
567
|
+
] });
|
|
568
|
+
};
|
|
334
569
|
const SettingsPage = () => {
|
|
335
570
|
const { formatMessage } = reactIntl.useIntl();
|
|
336
571
|
const { get, post, put } = admin.useFetchClient();
|
|
@@ -1059,6 +1294,24 @@ const SettingsPage = () => {
|
|
|
1059
1294
|
] }) }) })
|
|
1060
1295
|
] }) })
|
|
1061
1296
|
] }),
|
|
1297
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "geofencing", children: [
|
|
1298
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1299
|
+
designSystem.Accordion.Trigger,
|
|
1300
|
+
{
|
|
1301
|
+
icon: icons.Shield,
|
|
1302
|
+
description: t("settings.geofencing.description", "Allow or block sign-ins by country"),
|
|
1303
|
+
children: t("settings.geofencing.title", "Geofencing")
|
|
1304
|
+
}
|
|
1305
|
+
) }),
|
|
1306
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1307
|
+
GeofencingPanel,
|
|
1308
|
+
{
|
|
1309
|
+
settings,
|
|
1310
|
+
handleChange,
|
|
1311
|
+
t
|
|
1312
|
+
}
|
|
1313
|
+
) }) })
|
|
1314
|
+
] }),
|
|
1062
1315
|
isAdvanced && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "email", children: [
|
|
1063
1316
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1064
1317
|
designSystem.Accordion.Trigger,
|
|
@@ -5,9 +5,83 @@ import { Flex, Loader, Typography, Button, Box, Badge, Accordion, Grid, SingleSe
|
|
|
5
5
|
import { useFetchClient, useNotification } from "@strapi/strapi/admin";
|
|
6
6
|
import { Check, Information, Cog, Trash, Shield, Code, Duplicate, Clock, Mail } from "@strapi/icons";
|
|
7
7
|
import styled, { css, keyframes } from "styled-components";
|
|
8
|
-
import { a as pluginId, g as getTranslation } from "./index-
|
|
9
|
-
import { u as useLicense } from "./useLicense-
|
|
8
|
+
import { a as pluginId, g as getTranslation } from "./index-CwxKazpc.mjs";
|
|
9
|
+
import { u as useLicense } from "./useLicense-B9WW9s_d.mjs";
|
|
10
10
|
import { D as DangerButton, S as ShowHideButton, G as GradientButton, C as CopyButton, T as TertiaryButton, c as SecondaryButton } from "./StyledButtons-Cz8oYhmc.mjs";
|
|
11
|
+
const COUNTRIES = [
|
|
12
|
+
{ code: "DE", name: "Germany", flag: "🇩🇪" },
|
|
13
|
+
{ code: "AT", name: "Austria", flag: "🇦🇹" },
|
|
14
|
+
{ code: "CH", name: "Switzerland", flag: "🇨🇭" },
|
|
15
|
+
{ code: "US", name: "United States", flag: "🇺🇸" },
|
|
16
|
+
{ code: "CA", name: "Canada", flag: "🇨🇦" },
|
|
17
|
+
{ code: "MX", name: "Mexico", flag: "🇲🇽" },
|
|
18
|
+
{ code: "GB", name: "United Kingdom", flag: "🇬🇧" },
|
|
19
|
+
{ code: "IE", name: "Ireland", flag: "🇮🇪" },
|
|
20
|
+
{ code: "FR", name: "France", flag: "🇫🇷" },
|
|
21
|
+
{ code: "IT", name: "Italy", flag: "🇮🇹" },
|
|
22
|
+
{ code: "ES", name: "Spain", flag: "🇪🇸" },
|
|
23
|
+
{ code: "PT", name: "Portugal", flag: "🇵🇹" },
|
|
24
|
+
{ code: "NL", name: "Netherlands", flag: "🇳🇱" },
|
|
25
|
+
{ code: "BE", name: "Belgium", flag: "🇧🇪" },
|
|
26
|
+
{ code: "LU", name: "Luxembourg", flag: "🇱🇺" },
|
|
27
|
+
{ code: "SE", name: "Sweden", flag: "🇸🇪" },
|
|
28
|
+
{ code: "NO", name: "Norway", flag: "🇳🇴" },
|
|
29
|
+
{ code: "DK", name: "Denmark", flag: "🇩🇰" },
|
|
30
|
+
{ code: "FI", name: "Finland", flag: "🇫🇮" },
|
|
31
|
+
{ code: "PL", name: "Poland", flag: "🇵🇱" },
|
|
32
|
+
{ code: "CZ", name: "Czech Republic", flag: "🇨🇿" },
|
|
33
|
+
{ code: "SK", name: "Slovakia", flag: "🇸🇰" },
|
|
34
|
+
{ code: "HU", name: "Hungary", flag: "🇭🇺" },
|
|
35
|
+
{ code: "RO", name: "Romania", flag: "🇷🇴" },
|
|
36
|
+
{ code: "BG", name: "Bulgaria", flag: "🇧🇬" },
|
|
37
|
+
{ code: "GR", name: "Greece", flag: "🇬🇷" },
|
|
38
|
+
{ code: "HR", name: "Croatia", flag: "🇭🇷" },
|
|
39
|
+
{ code: "SI", name: "Slovenia", flag: "🇸🇮" },
|
|
40
|
+
{ code: "EE", name: "Estonia", flag: "🇪🇪" },
|
|
41
|
+
{ code: "LV", name: "Latvia", flag: "🇱🇻" },
|
|
42
|
+
{ code: "LT", name: "Lithuania", flag: "🇱🇹" },
|
|
43
|
+
{ code: "IS", name: "Iceland", flag: "🇮🇸" },
|
|
44
|
+
{ code: "TR", name: "Turkey", flag: "🇹🇷" },
|
|
45
|
+
{ code: "RU", name: "Russia", flag: "🇷🇺" },
|
|
46
|
+
{ code: "UA", name: "Ukraine", flag: "🇺🇦" },
|
|
47
|
+
{ code: "BR", name: "Brazil", flag: "🇧🇷" },
|
|
48
|
+
{ code: "AR", name: "Argentina", flag: "🇦🇷" },
|
|
49
|
+
{ code: "CL", name: "Chile", flag: "🇨🇱" },
|
|
50
|
+
{ code: "CO", name: "Colombia", flag: "🇨🇴" },
|
|
51
|
+
{ code: "AU", name: "Australia", flag: "🇦🇺" },
|
|
52
|
+
{ code: "NZ", name: "New Zealand", flag: "🇳🇿" },
|
|
53
|
+
{ code: "JP", name: "Japan", flag: "🇯🇵" },
|
|
54
|
+
{ code: "KR", name: "South Korea", flag: "🇰🇷" },
|
|
55
|
+
{ code: "CN", name: "China", flag: "🇨🇳" },
|
|
56
|
+
{ code: "HK", name: "Hong Kong", flag: "🇭🇰" },
|
|
57
|
+
{ code: "TW", name: "Taiwan", flag: "🇹🇼" },
|
|
58
|
+
{ code: "SG", name: "Singapore", flag: "🇸🇬" },
|
|
59
|
+
{ code: "IN", name: "India", flag: "🇮🇳" },
|
|
60
|
+
{ code: "ID", name: "Indonesia", flag: "🇮🇩" },
|
|
61
|
+
{ code: "TH", name: "Thailand", flag: "🇹🇭" },
|
|
62
|
+
{ code: "VN", name: "Vietnam", flag: "🇻🇳" },
|
|
63
|
+
{ code: "PH", name: "Philippines", flag: "🇵🇭" },
|
|
64
|
+
{ code: "MY", name: "Malaysia", flag: "🇲🇾" },
|
|
65
|
+
{ code: "AE", name: "United Arab Emirates", flag: "🇦🇪" },
|
|
66
|
+
{ code: "SA", name: "Saudi Arabia", flag: "🇸🇦" },
|
|
67
|
+
{ code: "IL", name: "Israel", flag: "🇮🇱" },
|
|
68
|
+
{ code: "EG", name: "Egypt", flag: "🇪🇬" },
|
|
69
|
+
{ code: "ZA", name: "South Africa", flag: "🇿🇦" },
|
|
70
|
+
{ code: "NG", name: "Nigeria", flag: "🇳🇬" },
|
|
71
|
+
{ code: "KE", name: "Kenya", flag: "🇰🇪" },
|
|
72
|
+
{ code: "MA", name: "Morocco", flag: "🇲🇦" }
|
|
73
|
+
];
|
|
74
|
+
const normalizeCountryCode = (raw) => {
|
|
75
|
+
if (typeof raw !== "string") return null;
|
|
76
|
+
const up = raw.trim().toUpperCase();
|
|
77
|
+
if (!/^[A-Z]{2}$/.test(up)) return null;
|
|
78
|
+
return up;
|
|
79
|
+
};
|
|
80
|
+
const formatCountry = (code) => {
|
|
81
|
+
if (!code) return "";
|
|
82
|
+
const match = COUNTRIES.find((c) => c.code === code);
|
|
83
|
+
return match ? `${match.flag} ${match.name} (${match.code})` : code;
|
|
84
|
+
};
|
|
11
85
|
const theme = {
|
|
12
86
|
borderRadius: { md: "8px", lg: "12px" }
|
|
13
87
|
};
|
|
@@ -327,6 +401,167 @@ const generateSecureKey = () => {
|
|
|
327
401
|
}
|
|
328
402
|
return key;
|
|
329
403
|
};
|
|
404
|
+
const GeofencingPanel = ({ settings, handleChange, t }) => {
|
|
405
|
+
const [pendingCode, setPendingCode] = useState("");
|
|
406
|
+
const mode = (() => {
|
|
407
|
+
if (Array.isArray(settings.allowedCountries) && settings.allowedCountries.length > 0) {
|
|
408
|
+
return "allowlist";
|
|
409
|
+
}
|
|
410
|
+
if (Array.isArray(settings.blockedCountries) && settings.blockedCountries.length > 0) {
|
|
411
|
+
return "blocklist";
|
|
412
|
+
}
|
|
413
|
+
return "allowlist";
|
|
414
|
+
})();
|
|
415
|
+
const activeField = mode === "allowlist" ? "allowedCountries" : "blockedCountries";
|
|
416
|
+
const activeList = Array.isArray(settings[activeField]) ? settings[activeField] : [];
|
|
417
|
+
const setMode = (newMode) => {
|
|
418
|
+
if (newMode === mode) return;
|
|
419
|
+
if (newMode === "allowlist") {
|
|
420
|
+
handleChange("blockedCountries", []);
|
|
421
|
+
} else {
|
|
422
|
+
handleChange("allowedCountries", []);
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
const addCode = (raw) => {
|
|
426
|
+
const code = normalizeCountryCode(raw);
|
|
427
|
+
if (!code) return;
|
|
428
|
+
if (activeList.includes(code)) return;
|
|
429
|
+
handleChange(activeField, [...activeList, code]);
|
|
430
|
+
setPendingCode("");
|
|
431
|
+
};
|
|
432
|
+
const removeCode = (code) => {
|
|
433
|
+
handleChange(activeField, activeList.filter((c) => c !== code));
|
|
434
|
+
};
|
|
435
|
+
return /* @__PURE__ */ jsxs(Grid.Root, { gap: 5, children: [
|
|
436
|
+
/* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsx(
|
|
437
|
+
Box,
|
|
438
|
+
{
|
|
439
|
+
padding: 3,
|
|
440
|
+
background: settings.enableGeofencing ? "success100" : "neutral100",
|
|
441
|
+
hasRadius: true,
|
|
442
|
+
style: { borderLeft: `4px solid ${settings.enableGeofencing ? "#16A34A" : "#9CA3AF"}` },
|
|
443
|
+
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
444
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
445
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", style: { display: "block", marginBottom: "4px" }, children: t("settings.geofencing.enable.title", "Enable Geofencing") }),
|
|
446
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: t(
|
|
447
|
+
"settings.geofencing.enable.description",
|
|
448
|
+
"When enabled, the pre-login guard compares the caller's country against the configured list and rejects logins that do not match."
|
|
449
|
+
) })
|
|
450
|
+
] }),
|
|
451
|
+
/* @__PURE__ */ jsx(
|
|
452
|
+
Toggle,
|
|
453
|
+
{
|
|
454
|
+
onLabel: "On",
|
|
455
|
+
offLabel: "Off",
|
|
456
|
+
checked: !!settings.enableGeofencing,
|
|
457
|
+
onChange: () => handleChange("enableGeofencing", !settings.enableGeofencing)
|
|
458
|
+
}
|
|
459
|
+
)
|
|
460
|
+
] })
|
|
461
|
+
}
|
|
462
|
+
) }),
|
|
463
|
+
/* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsxs(Box, { children: [
|
|
464
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: t("settings.geofencing.mode.title", "Mode") }),
|
|
465
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
466
|
+
/* @__PURE__ */ jsx(
|
|
467
|
+
Button,
|
|
468
|
+
{
|
|
469
|
+
variant: mode === "allowlist" ? "default" : "tertiary",
|
|
470
|
+
onClick: () => setMode("allowlist"),
|
|
471
|
+
disabled: !settings.enableGeofencing,
|
|
472
|
+
children: t("settings.geofencing.mode.allowlist", "Allowlist (only selected countries)")
|
|
473
|
+
}
|
|
474
|
+
),
|
|
475
|
+
/* @__PURE__ */ jsx(
|
|
476
|
+
Button,
|
|
477
|
+
{
|
|
478
|
+
variant: mode === "blocklist" ? "default" : "tertiary",
|
|
479
|
+
onClick: () => setMode("blocklist"),
|
|
480
|
+
disabled: !settings.enableGeofencing,
|
|
481
|
+
children: t("settings.geofencing.mode.blocklist", "Blocklist (block selected countries)")
|
|
482
|
+
}
|
|
483
|
+
)
|
|
484
|
+
] }),
|
|
485
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: mode === "allowlist" ? t(
|
|
486
|
+
"settings.geofencing.mode.allowlist.hint",
|
|
487
|
+
"Only countries in the list may authenticate. Empty list = no geo restriction."
|
|
488
|
+
) : t(
|
|
489
|
+
"settings.geofencing.mode.blocklist.hint",
|
|
490
|
+
"Every country EXCEPT those in the list may authenticate."
|
|
491
|
+
) })
|
|
492
|
+
] }) }),
|
|
493
|
+
/* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsxs(Box, { children: [
|
|
494
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: mode === "allowlist" ? t("settings.geofencing.allowed.title", "Allowed Countries") : t("settings.geofencing.blocked.title", "Blocked Countries") }),
|
|
495
|
+
/* @__PURE__ */ jsx(Flex, { gap: 2, wrap: "wrap", style: { marginBottom: "12px", minHeight: "36px" }, children: activeList.length === 0 ? /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: t("settings.geofencing.empty", "No countries configured.") }) : activeList.map((code) => /* @__PURE__ */ jsxs(
|
|
496
|
+
Badge,
|
|
497
|
+
{
|
|
498
|
+
onClick: settings.enableGeofencing ? () => removeCode(code) : void 0,
|
|
499
|
+
style: {
|
|
500
|
+
cursor: settings.enableGeofencing ? "pointer" : "not-allowed",
|
|
501
|
+
padding: "6px 10px",
|
|
502
|
+
background: mode === "allowlist" ? "#DCFCE7" : "#FEE2E2",
|
|
503
|
+
color: mode === "allowlist" ? "#15803D" : "#B91C1C"
|
|
504
|
+
},
|
|
505
|
+
children: [
|
|
506
|
+
formatCountry(code),
|
|
507
|
+
settings.enableGeofencing ? " ✕" : ""
|
|
508
|
+
]
|
|
509
|
+
},
|
|
510
|
+
code
|
|
511
|
+
)) }),
|
|
512
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
513
|
+
/* @__PURE__ */ jsx(Box, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(
|
|
514
|
+
SingleSelect,
|
|
515
|
+
{
|
|
516
|
+
disabled: !settings.enableGeofencing,
|
|
517
|
+
value: pendingCode || "",
|
|
518
|
+
onChange: (value) => {
|
|
519
|
+
setPendingCode(value);
|
|
520
|
+
if (value) addCode(value);
|
|
521
|
+
},
|
|
522
|
+
placeholder: t("settings.geofencing.pick", "Pick a country to add…"),
|
|
523
|
+
children: COUNTRIES.filter((c) => !activeList.includes(c.code)).map((c) => /* @__PURE__ */ jsxs(SingleSelectOption, { value: c.code, children: [
|
|
524
|
+
c.flag,
|
|
525
|
+
" ",
|
|
526
|
+
c.name,
|
|
527
|
+
" (",
|
|
528
|
+
c.code,
|
|
529
|
+
")"
|
|
530
|
+
] }, c.code))
|
|
531
|
+
}
|
|
532
|
+
) }),
|
|
533
|
+
/* @__PURE__ */ jsx(
|
|
534
|
+
TextInput,
|
|
535
|
+
{
|
|
536
|
+
disabled: !settings.enableGeofencing,
|
|
537
|
+
placeholder: t("settings.geofencing.manual", "Or type ISO-2 (e.g. JP)"),
|
|
538
|
+
value: pendingCode.length <= 2 ? pendingCode : "",
|
|
539
|
+
onChange: (e) => setPendingCode(e.target.value.toUpperCase().slice(0, 2)),
|
|
540
|
+
style: { width: "180px" }
|
|
541
|
+
}
|
|
542
|
+
),
|
|
543
|
+
/* @__PURE__ */ jsx(
|
|
544
|
+
Button,
|
|
545
|
+
{
|
|
546
|
+
disabled: !settings.enableGeofencing || !normalizeCountryCode(pendingCode),
|
|
547
|
+
onClick: () => addCode(pendingCode),
|
|
548
|
+
children: t("settings.geofencing.add", "Add")
|
|
549
|
+
}
|
|
550
|
+
)
|
|
551
|
+
] })
|
|
552
|
+
] }) }),
|
|
553
|
+
!settings.enableGeofencing && /* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsx(Alert, { variant: "default", closeLabel: "", title: "", onClose: () => {
|
|
554
|
+
}, children: t(
|
|
555
|
+
"settings.geofencing.disabled",
|
|
556
|
+
"Geofencing is currently disabled. Enable it above to enforce the configured country list."
|
|
557
|
+
) }) }),
|
|
558
|
+
settings.enableGeofencing && !settings.enableGeolocation && /* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsx(Alert, { variant: "warning", closeLabel: "", title: "", onClose: () => {
|
|
559
|
+
}, children: t(
|
|
560
|
+
"settings.geofencing.needsGeolocation",
|
|
561
|
+
"Geofencing requires Geolocation to be enabled (Security tab)."
|
|
562
|
+
) }) })
|
|
563
|
+
] });
|
|
564
|
+
};
|
|
330
565
|
const SettingsPage = () => {
|
|
331
566
|
const { formatMessage } = useIntl();
|
|
332
567
|
const { get, post, put } = useFetchClient();
|
|
@@ -1055,6 +1290,24 @@ const SettingsPage = () => {
|
|
|
1055
1290
|
] }) }) })
|
|
1056
1291
|
] }) })
|
|
1057
1292
|
] }),
|
|
1293
|
+
/* @__PURE__ */ jsxs(Accordion.Item, { value: "geofencing", children: [
|
|
1294
|
+
/* @__PURE__ */ jsx(Accordion.Header, { children: /* @__PURE__ */ jsx(
|
|
1295
|
+
Accordion.Trigger,
|
|
1296
|
+
{
|
|
1297
|
+
icon: Shield,
|
|
1298
|
+
description: t("settings.geofencing.description", "Allow or block sign-ins by country"),
|
|
1299
|
+
children: t("settings.geofencing.title", "Geofencing")
|
|
1300
|
+
}
|
|
1301
|
+
) }),
|
|
1302
|
+
/* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(Box, { padding: 6, children: /* @__PURE__ */ jsx(
|
|
1303
|
+
GeofencingPanel,
|
|
1304
|
+
{
|
|
1305
|
+
settings,
|
|
1306
|
+
handleChange,
|
|
1307
|
+
t
|
|
1308
|
+
}
|
|
1309
|
+
) }) })
|
|
1310
|
+
] }),
|
|
1058
1311
|
isAdvanced && /* @__PURE__ */ jsxs(Accordion.Item, { value: "email", children: [
|
|
1059
1312
|
/* @__PURE__ */ jsx(Accordion.Header, { children: /* @__PURE__ */ jsx(
|
|
1060
1313
|
Accordion.Trigger,
|