strapi-plugin-magic-sessionmanager 4.5.0 → 4.5.2

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.
@@ -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-DuVZXuJh.mjs";
9
- import { u as useLicense } from "./useLicense-Xzo6nyh3.mjs";
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();
@@ -346,6 +581,14 @@ const SettingsPage = () => {
346
581
  lastSeenRateLimit: 30,
347
582
  retentionDays: 90,
348
583
  maxSessionAgeDays: 30,
584
+ // Grace window (ms) during which a freshly-issued JWT is accepted
585
+ // without a matching session row. Prevents strict-session enforcement
586
+ // from blocking the very first request after login. 0 disables.
587
+ sessionCreationGraceMs: 5e3,
588
+ // Opt-in fast path for the periodic idle-session cleanup: single
589
+ // SQL UPDATE instead of batched Document-Service writes. Bypasses
590
+ // lifecycle hooks; required for very large installations.
591
+ cleanupUseDbDirect: false,
349
592
  strictSessionEnforcement: false,
350
593
  trustedProxies: false,
351
594
  enableGeolocation: true,
@@ -393,7 +636,7 @@ const SettingsPage = () => {
393
636
  }
394
637
  });
395
638
  }
396
- setSettings(loadedSettings);
639
+ setSettings((prev) => ({ ...prev, ...loadedSettings }));
397
640
  } else {
398
641
  setSettings((prev) => ({ ...prev, emailTemplates: getDefaultTemplates() }));
399
642
  }
@@ -628,6 +871,45 @@ const SettingsPage = () => {
628
871
  ),
629
872
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: settings.retentionDays === -1 ? t("settings.general.retention.hintNever", "Old sessions deleted after never") : t("settings.general.retention.hint", "Old sessions deleted after {days}", { days: `${settings.retentionDays} days` }) })
630
873
  ] }) }),
874
+ /* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(Box, { children: [
875
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: t("settings.general.grace.title", "Post-Login Grace Period") }),
876
+ /* @__PURE__ */ jsxs(
877
+ SingleSelect,
878
+ {
879
+ value: String(settings.sessionCreationGraceMs ?? 5e3),
880
+ onChange: (value) => handleChange("sessionCreationGraceMs", parseInt(value)),
881
+ children: [
882
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "0", children: t("settings.general.grace.off", "Off (strict from first request)") }),
883
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "2000", children: t("settings.general.grace.2s", "2 seconds") }),
884
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "5000", children: t("settings.general.grace.5s", "5 seconds (Recommended)") }),
885
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "10000", children: t("settings.general.grace.10s", "10 seconds") }),
886
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "30000", children: t("settings.general.grace.30s", "30 seconds") })
887
+ ]
888
+ }
889
+ ),
890
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: t(
891
+ "settings.general.grace.hint",
892
+ "Accepts a freshly-issued JWT without a matching session row for this window, preventing strict-enforcement races right after login."
893
+ ) })
894
+ ] }) }),
895
+ /* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(Box, { children: [
896
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: t("settings.general.cleanupMode.title", "Cleanup Strategy") }),
897
+ /* @__PURE__ */ jsxs(
898
+ SingleSelect,
899
+ {
900
+ value: settings.cleanupUseDbDirect ? "db" : "document-service",
901
+ onChange: (value) => handleChange("cleanupUseDbDirect", value === "db"),
902
+ children: [
903
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "document-service", children: t("settings.general.cleanupMode.ds", "Document Service (Recommended, safe)") }),
904
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "db", children: t("settings.general.cleanupMode.db", "Direct SQL UPDATE (large-scale)") })
905
+ ]
906
+ }
907
+ ),
908
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: t(
909
+ "settings.general.cleanupMode.hint",
910
+ "Direct SQL drains the entire idle-session backlog in one statement but bypasses lifecycle hooks. Only switch if you run >50 k active sessions."
911
+ ) })
912
+ ] }) }),
631
913
  /* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsx(Box, { padding: 4, background: "danger100", style: { borderRadius: theme.borderRadius.md, border: `2px solid rgba(220, 38, 38, 0.2)` }, children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "flex-start", children: [
632
914
  /* @__PURE__ */ jsx(Trash, { style: { width: "18px", height: "18px", color: "var(--colors-danger600, #DC2626)", flexShrink: 0, marginTop: "2px" } }),
633
915
  /* @__PURE__ */ jsxs(Box, { style: { flex: 1 }, children: [
@@ -1008,6 +1290,24 @@ const SettingsPage = () => {
1008
1290
  ] }) }) })
1009
1291
  ] }) })
1010
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
+ ] }),
1011
1311
  isAdvanced && /* @__PURE__ */ jsxs(Accordion.Item, { value: "email", children: [
1012
1312
  /* @__PURE__ */ jsx(Accordion.Header, { children: /* @__PURE__ */ jsx(
1013
1313
  Accordion.Trigger,
@@ -4,7 +4,7 @@ import { useFetchClient, useNotification } from "@strapi/strapi/admin";
4
4
  import styled from "styled-components";
5
5
  import { Flex, Typography, Box, Badge, Button } from "@strapi/design-system";
6
6
  import { Check, Cross, Sparkle, Lightning, Rocket } from "@strapi/icons";
7
- import { a as pluginId } from "./index-DuVZXuJh.mjs";
7
+ import { a as pluginId } from "./index-CwxKazpc.mjs";
8
8
  const Container = styled(Box)`
9
9
  padding: 32px;
10
10
  max-width: 1400px;
@@ -6,7 +6,7 @@ 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-CKrO7KSQ.js");
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 Container = styled__default.default(designSystem.Box)`
@@ -444,7 +444,7 @@ const index = {
444
444
  id: `${pluginId}.plugin.name`,
445
445
  defaultMessage: pluginPkg.strapi.displayName
446
446
  },
447
- Component: () => Promise.resolve().then(() => require("./App-Bir8yK_r.js")),
447
+ Component: () => Promise.resolve().then(() => require("./App-DF-VsbDW.js")),
448
448
  permissions: pluginPermissions
449
449
  });
450
450
  app.createSettingSection(
@@ -461,7 +461,7 @@ const index = {
461
461
  },
462
462
  id: "upgrade",
463
463
  to: `${pluginId}/upgrade`,
464
- Component: () => Promise.resolve().then(() => require("./UpgradePage-KqUN7mDh.js")),
464
+ Component: () => Promise.resolve().then(() => require("./UpgradePage-Dwrv7g8L.js")),
465
465
  permissions: pluginPermissions
466
466
  },
467
467
  {
@@ -471,7 +471,7 @@ const index = {
471
471
  },
472
472
  id: "general",
473
473
  to: `${pluginId}/general`,
474
- Component: () => Promise.resolve().then(() => require("./Settings-CO3-iggu.js")),
474
+ Component: () => Promise.resolve().then(() => require("./Settings-CUNaxDWk.js")),
475
475
  permissions: pluginPermissions
476
476
  },
477
477
  {
@@ -481,7 +481,7 @@ const index = {
481
481
  },
482
482
  id: "analytics",
483
483
  to: `${pluginId}/analytics`,
484
- Component: () => Promise.resolve().then(() => require("./Analytics-B7t0WvG7.js")),
484
+ Component: () => Promise.resolve().then(() => require("./Analytics-DM4_UffY.js")),
485
485
  permissions: pluginPermissions
486
486
  },
487
487
  {
@@ -491,7 +491,7 @@ const index = {
491
491
  },
492
492
  id: "license",
493
493
  to: `${pluginId}/license`,
494
- Component: () => Promise.resolve().then(() => require("./License-B56Xklj2.js")),
494
+ Component: () => Promise.resolve().then(() => require("./License-Dmm1d3fQ.js")),
495
495
  permissions: pluginPermissions
496
496
  }
497
497
  ]
@@ -510,7 +510,7 @@ const index = {
510
510
  defaultMessage: "Online Users"
511
511
  },
512
512
  component: async () => {
513
- const component = await Promise.resolve().then(() => require("./OnlineUsersWidget-DTEzguhS.js"));
513
+ const component = await Promise.resolve().then(() => require("./OnlineUsersWidget-KchZ_ScS.js"));
514
514
  return component.default;
515
515
  },
516
516
  id: "online-users-widget",
@@ -441,7 +441,7 @@ const index = {
441
441
  id: `${pluginId}.plugin.name`,
442
442
  defaultMessage: pluginPkg.strapi.displayName
443
443
  },
444
- Component: () => import("./App-LfsjcXXp.mjs"),
444
+ Component: () => import("./App-CL5q29Mi.mjs"),
445
445
  permissions: pluginPermissions
446
446
  });
447
447
  app.createSettingSection(
@@ -458,7 +458,7 @@ const index = {
458
458
  },
459
459
  id: "upgrade",
460
460
  to: `${pluginId}/upgrade`,
461
- Component: () => import("./UpgradePage-TBx1l2mQ.mjs"),
461
+ Component: () => import("./UpgradePage-D697BVWo.mjs"),
462
462
  permissions: pluginPermissions
463
463
  },
464
464
  {
@@ -468,7 +468,7 @@ const index = {
468
468
  },
469
469
  id: "general",
470
470
  to: `${pluginId}/general`,
471
- Component: () => import("./Settings-Bz3lPBJ6.mjs"),
471
+ Component: () => import("./Settings-D6ILgR9X.mjs"),
472
472
  permissions: pluginPermissions
473
473
  },
474
474
  {
@@ -478,7 +478,7 @@ const index = {
478
478
  },
479
479
  id: "analytics",
480
480
  to: `${pluginId}/analytics`,
481
- Component: () => import("./Analytics-DmlZwyVu.mjs"),
481
+ Component: () => import("./Analytics--qB2cKuD.mjs"),
482
482
  permissions: pluginPermissions
483
483
  },
484
484
  {
@@ -488,7 +488,7 @@ const index = {
488
488
  },
489
489
  id: "license",
490
490
  to: `${pluginId}/license`,
491
- Component: () => import("./License-OToijT0s.mjs"),
491
+ Component: () => import("./License-D9piCp34.mjs"),
492
492
  permissions: pluginPermissions
493
493
  }
494
494
  ]
@@ -507,7 +507,7 @@ const index = {
507
507
  defaultMessage: "Online Users"
508
508
  },
509
509
  component: async () => {
510
- const component = await import("./OnlineUsersWidget-Fpc0aH2z.mjs");
510
+ const component = await import("./OnlineUsersWidget-DHsthkt0.mjs");
511
511
  return component.default;
512
512
  },
513
513
  id: "online-users-widget",
@@ -1,6 +1,6 @@
1
1
  import { useState, useEffect } from "react";
2
2
  import { useFetchClient } from "@strapi/strapi/admin";
3
- import { a as pluginId } from "./index-DuVZXuJh.mjs";
3
+ import { a as pluginId } from "./index-CwxKazpc.mjs";
4
4
  const useLicense = () => {
5
5
  const { get } = useFetchClient();
6
6
  const [isPremium, setIsPremium] = useState(false);
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const react = require("react");
3
3
  const admin = require("@strapi/strapi/admin");
4
- const index = require("./index-CKrO7KSQ.js");
4
+ const index = require("./index-CTxGMDHr.js");
5
5
  const useLicense = () => {
6
6
  const { get } = admin.useFetchClient();
7
7
  const [isPremium, setIsPremium] = react.useState(false);
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-CKrO7KSQ.js");
2
+ const index = require("../_chunks/index-CTxGMDHr.js");
3
3
  module.exports = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "../_chunks/index-DuVZXuJh.mjs";
1
+ import { i } from "../_chunks/index-CwxKazpc.mjs";
2
2
  export {
3
3
  i as default
4
4
  };