strapi-plugin-magic-sessionmanager 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/admin/src/components/LicenseGuard.jsx +6 -6
  2. package/admin/src/components/SessionDetailModal.jsx +12 -12
  3. package/admin/src/components/SessionInfoCard.jsx +3 -3
  4. package/admin/src/components/SessionInfoPanel.jsx +3 -2
  5. package/admin/src/pages/Analytics.jsx +2 -2
  6. package/admin/src/pages/HomePage.jsx +11 -14
  7. package/admin/src/pages/License.jsx +2 -2
  8. package/admin/src/pages/Settings.jsx +24 -24
  9. package/admin/src/pages/SettingsNew.jsx +21 -21
  10. package/admin/src/utils/parseUserAgent.js +6 -6
  11. package/dist/_chunks/{Analytics-ioaeEh-E.js → Analytics-BBdv1I5y.js} +4 -4
  12. package/dist/_chunks/{Analytics-mYu_uGwU.mjs → Analytics-Dv9f_0eZ.mjs} +4 -4
  13. package/dist/_chunks/{App-BXpIS12l.mjs → App-CIQ-7sa7.mjs} +26 -31
  14. package/dist/_chunks/{App-DdnUYWbC.js → App-CJaZPNjt.js} +26 -31
  15. package/dist/_chunks/{License-DZYrOgcx.js → License-D24rgaZQ.js} +3 -3
  16. package/dist/_chunks/{License-C03C2j9P.mjs → License-nrmFxoBm.mjs} +3 -3
  17. package/dist/_chunks/{Settings-C6_CqpCC.js → Settings-CqxgjU0y.js} +26 -26
  18. package/dist/_chunks/{Settings-0ocB3qHk.mjs → Settings-D5dLEGc_.mjs} +26 -26
  19. package/dist/_chunks/{index-DBRS3kt5.mjs → index-Duk1_Wrz.mjs} +12 -12
  20. package/dist/_chunks/{index-DC8Y0qxx.js → index-WH04CS1c.js} +12 -12
  21. package/dist/_chunks/{useLicense-qgGfMvse.js → useLicense-BwOlCyhc.js} +1 -1
  22. package/dist/_chunks/{useLicense-DSLL9n3Y.mjs → useLicense-Ce8GaxB0.mjs} +1 -1
  23. package/dist/admin/index.js +1 -1
  24. package/dist/admin/index.mjs +1 -1
  25. package/dist/server/index.js +142 -33
  26. package/dist/server/index.mjs +142 -33
  27. package/package.json +1 -1
  28. package/server/src/bootstrap.js +76 -4
  29. package/server/src/controllers/session.js +59 -9
  30. package/server/src/middlewares/last-seen.js +5 -4
  31. package/server/src/routes/content-api.js +11 -2
  32. package/server/src/services/notifications.js +10 -10
  33. package/server/src/services/session.js +24 -4
@@ -6,8 +6,8 @@ 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-DC8Y0qxx.js");
10
- const useLicense = require("./useLicense-qgGfMvse.js");
9
+ const index = require("./index-WH04CS1c.js");
10
+ const useLicense = require("./useLicense-BwOlCyhc.js");
11
11
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
12
12
  const styled__default = /* @__PURE__ */ _interopDefault(styled);
13
13
  const theme = {
@@ -185,12 +185,12 @@ const validateTemplate = (template, templateType) => {
185
185
  };
186
186
  const getDefaultTemplates = () => ({
187
187
  suspiciousLogin: {
188
- subject: "🚨 Suspicious Login Alert - Session Manager",
188
+ subject: "[ALERT] Suspicious Login Alert - Session Manager",
189
189
  html: `
190
190
  <html>
191
191
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
192
192
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9fafb; border-radius: 10px;">
193
- <h2 style="color: #dc2626;">🚨 Suspicious Login Detected</h2>
193
+ <h2 style="color: #dc2626;">[ALERT] Suspicious Login Detected</h2>
194
194
  <p>A potentially suspicious login was detected for your account.</p>
195
195
 
196
196
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -225,7 +225,7 @@ const getDefaultTemplates = () => ({
225
225
  </div>
226
226
  </body>
227
227
  </html>`,
228
- text: `🚨 Suspicious Login Detected
228
+ text: `[ALERT] Suspicious Login Detected
229
229
 
230
230
  A potentially suspicious login was detected for your account.
231
231
 
@@ -240,12 +240,12 @@ Login Details:
240
240
  Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThreat}}, Score={{reason.securityScore}}/100`
241
241
  },
242
242
  newLocation: {
243
- subject: "📍 New Location Login Detected",
243
+ subject: "[LOCATION] New Location Login Detected",
244
244
  html: `
245
245
  <html>
246
246
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
247
247
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f0f9ff; border-radius: 10px;">
248
- <h2 style="color: #0284c7;">📍 Login from New Location</h2>
248
+ <h2 style="color: #0284c7;">[LOCATION] Login from New Location</h2>
249
249
  <p>Your account was accessed from a new location.</p>
250
250
 
251
251
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -268,7 +268,7 @@ Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThre
268
268
  </div>
269
269
  </body>
270
270
  </html>`,
271
- text: `📍 Login from New Location
271
+ text: `[LOCATION] Login from New Location
272
272
 
273
273
  Your account was accessed from a new location.
274
274
 
@@ -283,12 +283,12 @@ New Location Details:
283
283
  If this was you, no action is needed.`
284
284
  },
285
285
  vpnProxy: {
286
- subject: "⚠️ VPN/Proxy Login Detected",
286
+ subject: "[WARNING] VPN/Proxy Login Detected",
287
287
  html: `
288
288
  <html>
289
289
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
290
290
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #fffbeb; border-radius: 10px;">
291
- <h2 style="color: #d97706;">⚠️ VPN/Proxy Detected</h2>
291
+ <h2 style="color: #d97706;">[WARNING] VPN/Proxy Detected</h2>
292
292
  <p>A login from a VPN or proxy service was detected on your account.</p>
293
293
 
294
294
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -313,7 +313,7 @@ If this was you, no action is needed.`
313
313
  </div>
314
314
  </body>
315
315
  </html>`,
316
- text: `⚠️ VPN/Proxy Detected
316
+ text: `[WARNING] VPN/Proxy Detected
317
317
 
318
318
  A login from a VPN or proxy service was detected on your account.
319
319
 
@@ -449,7 +449,7 @@ const SettingsPage = () => {
449
449
  setHasChanges(false);
450
450
  };
451
451
  const handleCleanInactive = async () => {
452
- if (!confirm("⚠️ WARNING: This will permanently delete ALL inactive sessions.\n\nContinue?")) {
452
+ if (!confirm("[WARNING] This will permanently delete ALL inactive sessions.\n\nContinue?")) {
453
453
  return;
454
454
  }
455
455
  setCleaning(true);
@@ -543,7 +543,7 @@ const SettingsPage = () => {
543
543
  }
544
544
  ) }),
545
545
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, children: [
546
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "⏱️ SESSION TIMEOUT" }),
546
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "SESSION TIMEOUT" }),
547
547
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 6, style: { marginBottom: "32px" }, children: [
548
548
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
549
549
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "Inactivity Timeout" }),
@@ -673,7 +673,7 @@ const SettingsPage = () => {
673
673
  }
674
674
  ) }),
675
675
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, children: [
676
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "🔒 SECURITY OPTIONS" }),
676
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "SECURITY OPTIONS" }),
677
677
  /* @__PURE__ */ jsxRuntime.jsx(
678
678
  designSystem.Box,
679
679
  {
@@ -983,7 +983,7 @@ const SettingsPage = () => {
983
983
  {
984
984
  checked: settings.alertOnSuspiciousLogin,
985
985
  onChange: () => handleChange("alertOnSuspiciousLogin", !settings.alertOnSuspiciousLogin),
986
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "🚨 Suspicious Login" })
986
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "Suspicious Login" })
987
987
  }
988
988
  )
989
989
  }
@@ -1005,7 +1005,7 @@ const SettingsPage = () => {
1005
1005
  {
1006
1006
  checked: settings.alertOnNewLocation,
1007
1007
  onChange: () => handleChange("alertOnNewLocation", !settings.alertOnNewLocation),
1008
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "📍 New Location" })
1008
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "New Location" })
1009
1009
  }
1010
1010
  )
1011
1011
  }
@@ -1027,24 +1027,24 @@ const SettingsPage = () => {
1027
1027
  {
1028
1028
  checked: settings.alertOnVpnProxy,
1029
1029
  onChange: () => handleChange("alertOnVpnProxy", !settings.alertOnVpnProxy),
1030
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "⚠️ VPN/Proxy" })
1030
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "VPN/Proxy" })
1031
1031
  }
1032
1032
  )
1033
1033
  }
1034
1034
  ) })
1035
1035
  ] }),
1036
1036
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, { style: { marginBottom: "24px" } }),
1037
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.neutral[700] }, children: "📝 EMAIL TEMPLATES" }),
1037
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.neutral[700] }, children: "EMAIL TEMPLATES" }),
1038
1038
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { marginBottom: "20px", display: "block", fontSize: "12px" }, children: "Customize email notification templates with dynamic variables" }),
1039
1039
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs.Root, { value: activeTemplateTab, onValueChange: setActiveTemplateTab, children: [
1040
1040
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs.List, { "aria-label": "Email Templates", children: [
1041
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "suspiciousLogin", children: "🚨 Suspicious Login" }),
1042
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "newLocation", children: "📍 New Location" }),
1043
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "vpnProxy", children: "⚠️ VPN/Proxy" })
1041
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "suspiciousLogin", children: "Suspicious Login" }),
1042
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "newLocation", children: "New Location" }),
1043
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "vpnProxy", children: "VPN/Proxy" })
1044
1044
  ] }),
1045
1045
  Object.keys(settings.emailTemplates).map((templateKey) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Content, { value: templateKey, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingTop: 4, children: [
1046
1046
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { marginBottom: "24px" }, children: [
1047
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "✉️ Email Subject" }),
1047
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "Email Subject" }),
1048
1048
  /* @__PURE__ */ jsxRuntime.jsx(
1049
1049
  designSystem.TextInput,
1050
1050
  {
@@ -1200,7 +1200,7 @@ const SettingsPage = () => {
1200
1200
  const validation = validateTemplate(settings.emailTemplates[templateKey].html, templateKey);
1201
1201
  toggleNotification({
1202
1202
  type: validation.isValid ? "success" : "warning",
1203
- message: validation.isValid ? `✓ Template valid! Found ${validation.foundVars.length}/${validation.totalAvailable} variables.` : "⚠️ No variables found. Add at least one variable."
1203
+ message: validation.isValid ? `✓ Template valid! Found ${validation.foundVars.length}/${validation.totalAvailable} variables.` : "[WARNING] No variables found. Add at least one variable."
1204
1204
  });
1205
1205
  },
1206
1206
  children: "✓ Validate"
@@ -1405,7 +1405,7 @@ const SettingsPage = () => {
1405
1405
  }
1406
1406
  ),
1407
1407
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", style: { marginTop: "10px" }, children: [
1408
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "💡 Optional: Post session alerts to your Discord channel" }),
1408
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "Optional: Post session alerts to your Discord channel" }),
1409
1409
  settings.discordWebhookUrl && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "primary600", style: { fontSize: "11px", fontFamily: "monospace" }, children: [
1410
1410
  settings.discordWebhookUrl.length,
1411
1411
  " characters"
@@ -1448,7 +1448,7 @@ const SettingsPage = () => {
1448
1448
  }
1449
1449
  ),
1450
1450
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", style: { marginTop: "10px" }, children: [
1451
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "💡 Optional: Post session alerts to your Slack workspace" }),
1451
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "Optional: Post session alerts to your Slack workspace" }),
1452
1452
  settings.slackWebhookUrl && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "primary600", style: { fontSize: "11px", fontFamily: "monospace" }, children: [
1453
1453
  settings.slackWebhookUrl.length,
1454
1454
  " characters"
@@ -1462,7 +1462,7 @@ const SettingsPage = () => {
1462
1462
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 5, background: "primary100", style: { borderRadius: theme.borderRadius.md, marginTop: "32px", border: "2px solid #BAE6FD" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "flex-start", children: [
1463
1463
  /* @__PURE__ */ jsxRuntime.jsx(icons.Check, { style: { width: "20px", height: "20px", color: theme.colors.success[600], flexShrink: 0, marginTop: "2px" } }),
1464
1464
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: 1 }, children: [
1465
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.primary[700] }, children: "Database-Backed Settings" }),
1465
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.primary[700] }, children: "Database-Backed Settings" }),
1466
1466
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "primary700", style: { fontSize: "13px", lineHeight: "1.8" }, children: "All settings are stored in your Strapi database and shared across all admin users. Changes take effect immediately - no server restart required! Email templates, webhooks, and security options are all managed from this interface." })
1467
1467
  ] })
1468
1468
  ] }) })
@@ -4,8 +4,8 @@ import { Flex, Loader, Typography, Button, Box, Badge, Accordion, Grid, SingleSe
4
4
  import { useFetchClient, useNotification } from "@strapi/strapi/admin";
5
5
  import { Check, Information, Cog, Trash, Shield, Code, Duplicate, Mail } from "@strapi/icons";
6
6
  import styled, { css, keyframes } from "styled-components";
7
- import { a as pluginId } from "./index-DBRS3kt5.mjs";
8
- import { u as useLicense } from "./useLicense-DSLL9n3Y.mjs";
7
+ import { a as pluginId } from "./index-Duk1_Wrz.mjs";
8
+ import { u as useLicense } from "./useLicense-Ce8GaxB0.mjs";
9
9
  const theme = {
10
10
  colors: {
11
11
  primary: { 600: "#0284C7", 700: "#075985", 100: "#E0F2FE", 50: "#F0F9FF" },
@@ -181,12 +181,12 @@ const validateTemplate = (template, templateType) => {
181
181
  };
182
182
  const getDefaultTemplates = () => ({
183
183
  suspiciousLogin: {
184
- subject: "🚨 Suspicious Login Alert - Session Manager",
184
+ subject: "[ALERT] Suspicious Login Alert - Session Manager",
185
185
  html: `
186
186
  <html>
187
187
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
188
188
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9fafb; border-radius: 10px;">
189
- <h2 style="color: #dc2626;">🚨 Suspicious Login Detected</h2>
189
+ <h2 style="color: #dc2626;">[ALERT] Suspicious Login Detected</h2>
190
190
  <p>A potentially suspicious login was detected for your account.</p>
191
191
 
192
192
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -221,7 +221,7 @@ const getDefaultTemplates = () => ({
221
221
  </div>
222
222
  </body>
223
223
  </html>`,
224
- text: `🚨 Suspicious Login Detected
224
+ text: `[ALERT] Suspicious Login Detected
225
225
 
226
226
  A potentially suspicious login was detected for your account.
227
227
 
@@ -236,12 +236,12 @@ Login Details:
236
236
  Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThreat}}, Score={{reason.securityScore}}/100`
237
237
  },
238
238
  newLocation: {
239
- subject: "📍 New Location Login Detected",
239
+ subject: "[LOCATION] New Location Login Detected",
240
240
  html: `
241
241
  <html>
242
242
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
243
243
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f0f9ff; border-radius: 10px;">
244
- <h2 style="color: #0284c7;">📍 Login from New Location</h2>
244
+ <h2 style="color: #0284c7;">[LOCATION] Login from New Location</h2>
245
245
  <p>Your account was accessed from a new location.</p>
246
246
 
247
247
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -264,7 +264,7 @@ Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThre
264
264
  </div>
265
265
  </body>
266
266
  </html>`,
267
- text: `📍 Login from New Location
267
+ text: `[LOCATION] Login from New Location
268
268
 
269
269
  Your account was accessed from a new location.
270
270
 
@@ -279,12 +279,12 @@ New Location Details:
279
279
  If this was you, no action is needed.`
280
280
  },
281
281
  vpnProxy: {
282
- subject: "⚠️ VPN/Proxy Login Detected",
282
+ subject: "[WARNING] VPN/Proxy Login Detected",
283
283
  html: `
284
284
  <html>
285
285
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
286
286
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #fffbeb; border-radius: 10px;">
287
- <h2 style="color: #d97706;">⚠️ VPN/Proxy Detected</h2>
287
+ <h2 style="color: #d97706;">[WARNING] VPN/Proxy Detected</h2>
288
288
  <p>A login from a VPN or proxy service was detected on your account.</p>
289
289
 
290
290
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -309,7 +309,7 @@ If this was you, no action is needed.`
309
309
  </div>
310
310
  </body>
311
311
  </html>`,
312
- text: `⚠️ VPN/Proxy Detected
312
+ text: `[WARNING] VPN/Proxy Detected
313
313
 
314
314
  A login from a VPN or proxy service was detected on your account.
315
315
 
@@ -445,7 +445,7 @@ const SettingsPage = () => {
445
445
  setHasChanges(false);
446
446
  };
447
447
  const handleCleanInactive = async () => {
448
- if (!confirm("⚠️ WARNING: This will permanently delete ALL inactive sessions.\n\nContinue?")) {
448
+ if (!confirm("[WARNING] This will permanently delete ALL inactive sessions.\n\nContinue?")) {
449
449
  return;
450
450
  }
451
451
  setCleaning(true);
@@ -539,7 +539,7 @@ const SettingsPage = () => {
539
539
  }
540
540
  ) }),
541
541
  /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsxs(Box, { padding: 6, children: [
542
- /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "⏱️ SESSION TIMEOUT" }),
542
+ /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "SESSION TIMEOUT" }),
543
543
  /* @__PURE__ */ jsxs(Grid.Root, { gap: 6, style: { marginBottom: "32px" }, children: [
544
544
  /* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(Box, { children: [
545
545
  /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "Inactivity Timeout" }),
@@ -669,7 +669,7 @@ const SettingsPage = () => {
669
669
  }
670
670
  ) }),
671
671
  /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsxs(Box, { padding: 6, children: [
672
- /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "🔒 SECURITY OPTIONS" }),
672
+ /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "SECURITY OPTIONS" }),
673
673
  /* @__PURE__ */ jsx(
674
674
  Box,
675
675
  {
@@ -979,7 +979,7 @@ const SettingsPage = () => {
979
979
  {
980
980
  checked: settings.alertOnSuspiciousLogin,
981
981
  onChange: () => handleChange("alertOnSuspiciousLogin", !settings.alertOnSuspiciousLogin),
982
- children: /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "🚨 Suspicious Login" })
982
+ children: /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "Suspicious Login" })
983
983
  }
984
984
  )
985
985
  }
@@ -1001,7 +1001,7 @@ const SettingsPage = () => {
1001
1001
  {
1002
1002
  checked: settings.alertOnNewLocation,
1003
1003
  onChange: () => handleChange("alertOnNewLocation", !settings.alertOnNewLocation),
1004
- children: /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "📍 New Location" })
1004
+ children: /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "New Location" })
1005
1005
  }
1006
1006
  )
1007
1007
  }
@@ -1023,24 +1023,24 @@ const SettingsPage = () => {
1023
1023
  {
1024
1024
  checked: settings.alertOnVpnProxy,
1025
1025
  onChange: () => handleChange("alertOnVpnProxy", !settings.alertOnVpnProxy),
1026
- children: /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "⚠️ VPN/Proxy" })
1026
+ children: /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "VPN/Proxy" })
1027
1027
  }
1028
1028
  )
1029
1029
  }
1030
1030
  ) })
1031
1031
  ] }),
1032
1032
  /* @__PURE__ */ jsx(Divider, { style: { marginBottom: "24px" } }),
1033
- /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.neutral[700] }, children: "📝 EMAIL TEMPLATES" }),
1033
+ /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.neutral[700] }, children: "EMAIL TEMPLATES" }),
1034
1034
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { marginBottom: "20px", display: "block", fontSize: "12px" }, children: "Customize email notification templates with dynamic variables" }),
1035
1035
  /* @__PURE__ */ jsxs(Tabs.Root, { value: activeTemplateTab, onValueChange: setActiveTemplateTab, children: [
1036
1036
  /* @__PURE__ */ jsxs(Tabs.List, { "aria-label": "Email Templates", children: [
1037
- /* @__PURE__ */ jsx(Tabs.Trigger, { value: "suspiciousLogin", children: "🚨 Suspicious Login" }),
1038
- /* @__PURE__ */ jsx(Tabs.Trigger, { value: "newLocation", children: "📍 New Location" }),
1039
- /* @__PURE__ */ jsx(Tabs.Trigger, { value: "vpnProxy", children: "⚠️ VPN/Proxy" })
1037
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "suspiciousLogin", children: "Suspicious Login" }),
1038
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "newLocation", children: "New Location" }),
1039
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "vpnProxy", children: "VPN/Proxy" })
1040
1040
  ] }),
1041
1041
  Object.keys(settings.emailTemplates).map((templateKey) => /* @__PURE__ */ jsx(Tabs.Content, { value: templateKey, children: /* @__PURE__ */ jsxs(Box, { paddingTop: 4, children: [
1042
1042
  /* @__PURE__ */ jsxs(Box, { style: { marginBottom: "24px" }, children: [
1043
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "✉️ Email Subject" }),
1043
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "Email Subject" }),
1044
1044
  /* @__PURE__ */ jsx(
1045
1045
  TextInput,
1046
1046
  {
@@ -1196,7 +1196,7 @@ const SettingsPage = () => {
1196
1196
  const validation = validateTemplate(settings.emailTemplates[templateKey].html, templateKey);
1197
1197
  toggleNotification({
1198
1198
  type: validation.isValid ? "success" : "warning",
1199
- message: validation.isValid ? `✓ Template valid! Found ${validation.foundVars.length}/${validation.totalAvailable} variables.` : "⚠️ No variables found. Add at least one variable."
1199
+ message: validation.isValid ? `✓ Template valid! Found ${validation.foundVars.length}/${validation.totalAvailable} variables.` : "[WARNING] No variables found. Add at least one variable."
1200
1200
  });
1201
1201
  },
1202
1202
  children: "✓ Validate"
@@ -1401,7 +1401,7 @@ const SettingsPage = () => {
1401
1401
  }
1402
1402
  ),
1403
1403
  /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", style: { marginTop: "10px" }, children: [
1404
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "💡 Optional: Post session alerts to your Discord channel" }),
1404
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "Optional: Post session alerts to your Discord channel" }),
1405
1405
  settings.discordWebhookUrl && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "primary600", style: { fontSize: "11px", fontFamily: "monospace" }, children: [
1406
1406
  settings.discordWebhookUrl.length,
1407
1407
  " characters"
@@ -1444,7 +1444,7 @@ const SettingsPage = () => {
1444
1444
  }
1445
1445
  ),
1446
1446
  /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", style: { marginTop: "10px" }, children: [
1447
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "💡 Optional: Post session alerts to your Slack workspace" }),
1447
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "Optional: Post session alerts to your Slack workspace" }),
1448
1448
  settings.slackWebhookUrl && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "primary600", style: { fontSize: "11px", fontFamily: "monospace" }, children: [
1449
1449
  settings.slackWebhookUrl.length,
1450
1450
  " characters"
@@ -1458,7 +1458,7 @@ const SettingsPage = () => {
1458
1458
  /* @__PURE__ */ jsx(Box, { padding: 5, background: "primary100", style: { borderRadius: theme.borderRadius.md, marginTop: "32px", border: "2px solid #BAE6FD" }, children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "flex-start", children: [
1459
1459
  /* @__PURE__ */ jsx(Check, { style: { width: "20px", height: "20px", color: theme.colors.success[600], flexShrink: 0, marginTop: "2px" } }),
1460
1460
  /* @__PURE__ */ jsxs(Box, { style: { flex: 1 }, children: [
1461
- /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.primary[700] }, children: "Database-Backed Settings" }),
1461
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.primary[700] }, children: "Database-Backed Settings" }),
1462
1462
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "primary700", style: { fontSize: "13px", lineHeight: "1.8" }, children: "All settings are stored in your Strapi database and shared across all admin users. Changes take effect immediately - no server restart required! Email templates, webhooks, and security options are all managed from this interface." })
1463
1463
  ] })
1464
1464
  ] }) })
@@ -22,20 +22,20 @@ const parseUserAgent = (userAgent) => {
22
22
  if (!userAgent) {
23
23
  return {
24
24
  device: "Unknown",
25
- deviceIcon: "",
25
+ deviceIcon: "question",
26
26
  browser: "Unknown",
27
27
  os: "Unknown"
28
28
  };
29
29
  }
30
30
  const ua = userAgent.toLowerCase();
31
31
  let device = "Desktop";
32
- let deviceIcon = "💻";
32
+ let deviceIcon = "desktop";
33
33
  if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(userAgent)) {
34
34
  device = "Tablet";
35
- deviceIcon = "📱";
35
+ deviceIcon = "tablet";
36
36
  } else if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(userAgent)) {
37
37
  device = "Mobile";
38
- deviceIcon = "📱";
38
+ deviceIcon = "mobile";
39
39
  }
40
40
  let browser = "Unknown";
41
41
  if (ua.includes("edg/")) {
@@ -54,11 +54,11 @@ const parseUserAgent = (userAgent) => {
54
54
  device = "API Client";
55
55
  } else if (ua.includes("postman")) {
56
56
  browser = "Postman";
57
- deviceIcon = "📮";
57
+ deviceIcon = "code";
58
58
  device = "API Client";
59
59
  } else if (ua.includes("insomnia")) {
60
60
  browser = "Insomnia";
61
- deviceIcon = "🌙";
61
+ deviceIcon = "code";
62
62
  device = "API Client";
63
63
  }
64
64
  let os = "Unknown";
@@ -87,7 +87,7 @@ const SessionInfoPanel = ({ documentId, model, document }) => {
87
87
  const [actionLoading, setActionLoading] = useState(false);
88
88
  const { get, post: postRequest } = useFetchClient();
89
89
  const { toggleNotification } = useNotification();
90
- const userId = document?.id || documentId;
90
+ const userId = document?.documentId || documentId;
91
91
  useEffect(() => {
92
92
  if (model !== "plugin::users-permissions.user" || !userId) {
93
93
  setLoading(false);
@@ -191,7 +191,7 @@ const SessionInfoPanel = ({ documentId, model, document }) => {
191
191
  textColor: "neutral0",
192
192
  size: "M",
193
193
  style: { fontSize: "14px", padding: "6px 12px" },
194
- children: isOnline ? "🟢 ACTIVE" : "OFFLINE"
194
+ children: isOnline ? "ACTIVE" : "OFFLINE"
195
195
  }
196
196
  ),
197
197
  /* @__PURE__ */ jsxs(Typography, { variant: "omega", fontWeight: "semiBold", textColor: isOnline ? "success700" : "neutral700", children: [
@@ -403,7 +403,7 @@ const index = {
403
403
  id: `${pluginId}.plugin.name`,
404
404
  defaultMessage: pluginPkg.strapi.displayName
405
405
  },
406
- Component: () => import("./App-BXpIS12l.mjs")
406
+ Component: () => import("./App-CIQ-7sa7.mjs")
407
407
  });
408
408
  app.createSettingSection(
409
409
  {
@@ -419,7 +419,7 @@ const index = {
419
419
  },
420
420
  id: "general",
421
421
  to: `/settings/${pluginId}/general`,
422
- Component: () => import("./Settings-0ocB3qHk.mjs")
422
+ Component: () => import("./Settings-D5dLEGc_.mjs")
423
423
  },
424
424
  {
425
425
  intlLabel: {
@@ -428,7 +428,7 @@ const index = {
428
428
  },
429
429
  id: "analytics",
430
430
  to: `/settings/${pluginId}/analytics`,
431
- Component: () => import("./Analytics-mYu_uGwU.mjs")
431
+ Component: () => import("./Analytics-Dv9f_0eZ.mjs")
432
432
  },
433
433
  {
434
434
  intlLabel: {
@@ -437,7 +437,7 @@ const index = {
437
437
  },
438
438
  id: "license",
439
439
  to: `/settings/${pluginId}/license`,
440
- Component: () => import("./License-C03C2j9P.mjs")
440
+ Component: () => import("./License-nrmFxoBm.mjs")
441
441
  }
442
442
  ]
443
443
  );
@@ -23,20 +23,20 @@ const parseUserAgent = (userAgent) => {
23
23
  if (!userAgent) {
24
24
  return {
25
25
  device: "Unknown",
26
- deviceIcon: "",
26
+ deviceIcon: "question",
27
27
  browser: "Unknown",
28
28
  os: "Unknown"
29
29
  };
30
30
  }
31
31
  const ua = userAgent.toLowerCase();
32
32
  let device = "Desktop";
33
- let deviceIcon = "💻";
33
+ let deviceIcon = "desktop";
34
34
  if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(userAgent)) {
35
35
  device = "Tablet";
36
- deviceIcon = "📱";
36
+ deviceIcon = "tablet";
37
37
  } else if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(userAgent)) {
38
38
  device = "Mobile";
39
- deviceIcon = "📱";
39
+ deviceIcon = "mobile";
40
40
  }
41
41
  let browser = "Unknown";
42
42
  if (ua.includes("edg/")) {
@@ -55,11 +55,11 @@ const parseUserAgent = (userAgent) => {
55
55
  device = "API Client";
56
56
  } else if (ua.includes("postman")) {
57
57
  browser = "Postman";
58
- deviceIcon = "📮";
58
+ deviceIcon = "code";
59
59
  device = "API Client";
60
60
  } else if (ua.includes("insomnia")) {
61
61
  browser = "Insomnia";
62
- deviceIcon = "🌙";
62
+ deviceIcon = "code";
63
63
  device = "API Client";
64
64
  }
65
65
  let os = "Unknown";
@@ -88,7 +88,7 @@ const SessionInfoPanel = ({ documentId, model, document }) => {
88
88
  const [actionLoading, setActionLoading] = react.useState(false);
89
89
  const { get, post: postRequest } = admin.useFetchClient();
90
90
  const { toggleNotification } = admin.useNotification();
91
- const userId = document?.id || documentId;
91
+ const userId = document?.documentId || documentId;
92
92
  react.useEffect(() => {
93
93
  if (model !== "plugin::users-permissions.user" || !userId) {
94
94
  setLoading(false);
@@ -192,7 +192,7 @@ const SessionInfoPanel = ({ documentId, model, document }) => {
192
192
  textColor: "neutral0",
193
193
  size: "M",
194
194
  style: { fontSize: "14px", padding: "6px 12px" },
195
- children: isOnline ? "🟢 ACTIVE" : "OFFLINE"
195
+ children: isOnline ? "ACTIVE" : "OFFLINE"
196
196
  }
197
197
  ),
198
198
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", textColor: isOnline ? "success700" : "neutral700", children: [
@@ -404,7 +404,7 @@ const index = {
404
404
  id: `${pluginId}.plugin.name`,
405
405
  defaultMessage: pluginPkg.strapi.displayName
406
406
  },
407
- Component: () => Promise.resolve().then(() => require("./App-DdnUYWbC.js"))
407
+ Component: () => Promise.resolve().then(() => require("./App-CJaZPNjt.js"))
408
408
  });
409
409
  app.createSettingSection(
410
410
  {
@@ -420,7 +420,7 @@ const index = {
420
420
  },
421
421
  id: "general",
422
422
  to: `/settings/${pluginId}/general`,
423
- Component: () => Promise.resolve().then(() => require("./Settings-C6_CqpCC.js"))
423
+ Component: () => Promise.resolve().then(() => require("./Settings-CqxgjU0y.js"))
424
424
  },
425
425
  {
426
426
  intlLabel: {
@@ -429,7 +429,7 @@ const index = {
429
429
  },
430
430
  id: "analytics",
431
431
  to: `/settings/${pluginId}/analytics`,
432
- Component: () => Promise.resolve().then(() => require("./Analytics-ioaeEh-E.js"))
432
+ Component: () => Promise.resolve().then(() => require("./Analytics-BBdv1I5y.js"))
433
433
  },
434
434
  {
435
435
  intlLabel: {
@@ -438,7 +438,7 @@ const index = {
438
438
  },
439
439
  id: "license",
440
440
  to: `/settings/${pluginId}/license`,
441
- Component: () => Promise.resolve().then(() => require("./License-DZYrOgcx.js"))
441
+ Component: () => Promise.resolve().then(() => require("./License-D24rgaZQ.js"))
442
442
  }
443
443
  ]
444
444
  );
@@ -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-DC8Y0qxx.js");
4
+ const index = require("./index-WH04CS1c.js");
5
5
  const useLicense = () => {
6
6
  const { get } = admin.useFetchClient();
7
7
  const [isPremium, setIsPremium] = react.useState(false);
@@ -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-DBRS3kt5.mjs";
3
+ import { a as pluginId } from "./index-Duk1_Wrz.mjs";
4
4
  const useLicense = () => {
5
5
  const { get } = useFetchClient();
6
6
  const [isPremium, setIsPremium] = useState(false);
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-DC8Y0qxx.js");
2
+ const index = require("../_chunks/index-WH04CS1c.js");
3
3
  module.exports = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "../_chunks/index-DBRS3kt5.mjs";
1
+ import { i } from "../_chunks/index-Duk1_Wrz.mjs";
2
2
  export {
3
3
  i as default
4
4
  };