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
@@ -407,12 +407,12 @@ const LicenseGuard = ({ children }) => {
407
407
  >
408
408
  <Typography variant="omega" style={{ fontSize: '13px', lineHeight: '1.6' }}>
409
409
  {useExistingKey
410
- ? '🔑 Enter your email and license key to activate.'
410
+ ? 'Enter your email and license key to activate.'
411
411
  : useAutoCreate && adminUser && adminUser.email
412
- ? `✨ Click "Activate" to auto-create a license with your account (${adminUser.email})`
412
+ ? `Click "Activate" to auto-create a license with your account (${adminUser.email})`
413
413
  : useAutoCreate
414
- ? 'Click "Activate" to auto-create a license with your admin account'
415
- : '💡 A license will be created with the details below.'
414
+ ? 'Click "Activate" to auto-create a license with your admin account'
415
+ : 'A license will be created with the details below.'
416
416
  }
417
417
  </Typography>
418
418
  </Box>
@@ -476,10 +476,10 @@ const LicenseGuard = ({ children }) => {
476
476
  Ready to activate with your account:
477
477
  </Typography>
478
478
  <Typography variant="pi" style={{ marginBottom: '4px', display: 'block' }}>
479
- 👤 {adminUser.firstname || 'Admin'} {adminUser.lastname || 'User'}
479
+ {adminUser.firstname || 'Admin'} {adminUser.lastname || 'User'}
480
480
  </Typography>
481
481
  <Typography variant="pi" textColor="neutral600">
482
- 📧 {adminUser.email || 'Loading...'}
482
+ {adminUser.email || 'Loading...'}
483
483
  </Typography>
484
484
  </Box>
485
485
  ) : (
@@ -82,7 +82,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
82
82
  console.error('[SessionDetailModal] Error fetching geolocation:', err);
83
83
  // Fallback to mock data if API fails
84
84
  setGeoData({
85
- country_flag: '🌍',
85
+ country_flag: '',
86
86
  country: 'Unknown',
87
87
  city: 'Unknown',
88
88
  timezone: 'Unknown',
@@ -98,7 +98,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
98
98
 
99
99
  // Use real data if available, otherwise fallback
100
100
  const premiumData = geoData || {
101
- country_flag: '🌍',
101
+ country_flag: '',
102
102
  country: 'Loading...',
103
103
  city: 'Loading...',
104
104
  timezone: 'Loading...',
@@ -207,7 +207,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
207
207
  size="M"
208
208
  style={{ fontSize: '14px', padding: '8px 20px', fontWeight: '600' }}
209
209
  >
210
- {isOnline ? '🟢 ONLINE' : 'OFFLINE'}
210
+ {isOnline ? 'ONLINE' : 'OFFLINE'}
211
211
  </Badge>
212
212
  </Flex>
213
213
 
@@ -220,7 +220,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
220
220
  {/* User Information */}
221
221
  <Section>
222
222
  <SectionTitle>
223
- 👤 User
223
+ User
224
224
  </SectionTitle>
225
225
 
226
226
  <DetailRow compact icon={Check} label="Username" value={session.user?.username || 'N/A'} />
@@ -231,7 +231,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
231
231
  {/* Device Information */}
232
232
  <Section>
233
233
  <SectionTitle>
234
- 💻 Device
234
+ Device
235
235
  </SectionTitle>
236
236
 
237
237
  <DetailRow compact icon={DeviceIcon} label="Device" value={deviceInfo.device} />
@@ -245,7 +245,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
245
245
  <Box>
246
246
  <Section>
247
247
  <SectionTitle>
248
- ⏱️ Timeline
248
+ Timeline
249
249
  </SectionTitle>
250
250
 
251
251
  <DetailRow
@@ -297,7 +297,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
297
297
  {isPremium ? (
298
298
  <Section>
299
299
  <SectionTitle>
300
- 🌍 Location & Security
300
+ Location and Security
301
301
  </SectionTitle>
302
302
 
303
303
  {geoLoading ? (
@@ -313,7 +313,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
313
313
  compact
314
314
  icon={Earth}
315
315
  label="Country"
316
- value={`${premiumData.country_flag || '🌍'} ${premiumData.country}`}
316
+ value={`${premiumData.country_flag || ''} ${premiumData.country}`.trim()}
317
317
  />
318
318
  <DetailRow compact icon={Earth} label="City" value={premiumData.city} />
319
319
  <DetailRow compact icon={Clock} label="Timezone" value={premiumData.timezone} />
@@ -329,13 +329,13 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
329
329
  compact
330
330
  icon={Shield}
331
331
  label="VPN"
332
- value={premiumData.isVpn ? '⚠️ Yes' : 'No'}
332
+ value={premiumData.isVpn ? '[WARNING] Yes' : 'No'}
333
333
  />
334
334
  <DetailRow
335
335
  compact
336
336
  icon={Shield}
337
337
  label="Proxy"
338
- value={premiumData.isProxy ? '⚠️ Yes' : 'No'}
338
+ value={premiumData.isProxy ? '[WARNING] Yes' : 'No'}
339
339
  />
340
340
  </Box>
341
341
  </TwoColumnGrid>
@@ -355,7 +355,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
355
355
  <Flex direction="column" alignItems="center" gap={3}>
356
356
  <Crown style={{ width: '40px', height: '40px', color: '#d97706' }} />
357
357
  <Typography variant="beta" style={{ color: '#92400e', fontWeight: '700' }}>
358
- 🌍 Location & Security Analysis
358
+ Location and Security Analysis
359
359
  </Typography>
360
360
  <Typography variant="omega" style={{ color: '#78350f', fontSize: '14px', lineHeight: '1.6' }}>
361
361
  Unlock premium features to get IP geolocation, security scoring, and VPN/Proxy detection for every session
@@ -384,7 +384,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
384
384
  <Section>
385
385
  <Flex justifyContent="space-between" alignItems="center" style={{ marginBottom: '12px' }}>
386
386
  <SectionTitle style={{ marginBottom: 0, paddingBottom: 0, border: 'none' }}>
387
- 🔧 Technical Details
387
+ Technical Details
388
388
  </SectionTitle>
389
389
  <Button
390
390
  variant="tertiary"
@@ -76,11 +76,11 @@ const SessionInfoCard = ({ id, model }) => {
76
76
  </Typography>
77
77
  {isOnline ? (
78
78
  <Badge active backgroundColor="success500">
79
- 🟢 Online
79
+ Online
80
80
  </Badge>
81
81
  ) : (
82
82
  <Badge backgroundColor="neutral150">
83
- Offline
83
+ Offline
84
84
  </Badge>
85
85
  )}
86
86
  </Flex>
@@ -110,7 +110,7 @@ const SessionInfoCard = ({ id, model }) => {
110
110
  marginBottom={2}
111
111
  >
112
112
  <Typography variant="pi" textColor="neutral800">
113
- 📱 {session.ipAddress}
113
+ IP: {session.ipAddress}
114
114
  </Typography>
115
115
  <Typography variant="pi" textColor="neutral600" fontSize="11px">
116
116
  {new Date(session.loginTime).toLocaleString()}
@@ -16,7 +16,8 @@ const SessionInfoPanel = ({ documentId, model, document }) => {
16
16
  const { get, post: postRequest } = useFetchClient();
17
17
  const { toggleNotification } = useNotification();
18
18
 
19
- const userId = document?.id || documentId;
19
+ // Strapi v5: Use documentId (string UUID) instead of numeric id
20
+ const userId = document?.documentId || documentId;
20
21
 
21
22
  useEffect(() => {
22
23
  if (model !== 'plugin::users-permissions.user' || !userId) {
@@ -144,7 +145,7 @@ const SessionInfoPanel = ({ documentId, model, document }) => {
144
145
  size="M"
145
146
  style={{ fontSize: '14px', padding: '6px 12px' }}
146
147
  >
147
- {isOnline ? '🟢 ACTIVE' : 'OFFLINE'}
148
+ {isOnline ? 'ACTIVE' : 'OFFLINE'}
148
149
  </Badge>
149
150
  <Typography variant="omega" fontWeight="semiBold" textColor={isOnline ? 'success700' : 'neutral700'}>
150
151
  {sessions.length} active session{sessions.length !== 1 ? 's' : ''}
@@ -506,7 +506,7 @@ const AnalyticsPage = () => {
506
506
  textShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
507
507
  }}
508
508
  >
509
- 📊 Analytics Dashboard
509
+ Analytics Dashboard
510
510
  </Typography>
511
511
 
512
512
  <Typography
@@ -547,7 +547,7 @@ const AnalyticsPage = () => {
547
547
  e.currentTarget.style.boxShadow = '0 6px 16px rgba(245, 158, 11, 0.4)';
548
548
  }}
549
549
  >
550
- Upgrade to Premium
550
+ Upgrade to Premium
551
551
  </button>
552
552
  </div>
553
553
  </Box>
@@ -531,7 +531,7 @@ const HomePage = () => {
531
531
  };
532
532
 
533
533
  const handleDeleteSession = async (sessionId) => {
534
- if (!confirm('⚠️ WARNING: This will PERMANENTLY delete this session from the database!\n\nThis action cannot be undone.\n\nAre you sure?')) {
534
+ if (!confirm('[WARNING] This will PERMANENTLY delete this session from the database!\n\nThis action cannot be undone.\n\nAre you sure?')) {
535
535
  return;
536
536
  }
537
537
 
@@ -838,7 +838,7 @@ const HomePage = () => {
838
838
  <Box>
839
839
  <Box style={{ marginBottom: theme.spacing.md }}>
840
840
  <Typography variant="delta" style={{ marginBottom: theme.spacing.md, color: theme.colors.neutral[700] }}>
841
- 📊 All Sessions
841
+ All Sessions
842
842
  </Typography>
843
843
  </Box>
844
844
 
@@ -864,10 +864,10 @@ const HomePage = () => {
864
864
  size="S"
865
865
  >
866
866
  <SingleSelectOption value="all">All Sessions</SingleSelectOption>
867
- <SingleSelectOption value="active">🟢 Active (&lt; 15 min)</SingleSelectOption>
868
- <SingleSelectOption value="idle">🟡 Idle (&gt; 15 min)</SingleSelectOption>
869
- <SingleSelectOption value="loggedout">🔴 Logged Out</SingleSelectOption>
870
- <SingleSelectOption value="terminated">⚫ Terminated</SingleSelectOption>
867
+ <SingleSelectOption value="active">Active (less than 15 min)</SingleSelectOption>
868
+ <SingleSelectOption value="idle">Idle (more than 15 min)</SingleSelectOption>
869
+ <SingleSelectOption value="loggedout">Logged Out</SingleSelectOption>
870
+ <SingleSelectOption value="terminated">Terminated</SingleSelectOption>
871
871
  </SingleSelect>
872
872
  </Box>
873
873
 
@@ -921,26 +921,26 @@ const HomePage = () => {
921
921
  active: {
922
922
  bg: theme.colors.success[50],
923
923
  badgeColor: 'success600',
924
- label: '🟢 Active',
924
+ label: 'Active',
925
925
  indicator: true
926
926
  },
927
927
  idle: {
928
928
  bg: theme.colors.warning[50],
929
929
  badgeColor: 'warning600',
930
- label: '🟡 Idle',
930
+ label: 'Idle',
931
931
  indicator: false
932
932
  },
933
933
  loggedout: {
934
934
  bg: theme.colors.danger[50],
935
935
  badgeColor: 'danger600',
936
- label: '🔴 Logged Out',
936
+ label: 'Logged Out',
937
937
  indicator: false,
938
938
  opacity: 0.7
939
939
  },
940
940
  terminated: {
941
941
  bg: theme.colors.neutral[100],
942
942
  badgeColor: 'neutral600',
943
- label: 'Terminated',
943
+ label: 'Terminated',
944
944
  indicator: false,
945
945
  opacity: 0.6
946
946
  },
@@ -1185,10 +1185,7 @@ const HomePage = () => {
1185
1185
  }}
1186
1186
  />
1187
1187
 
1188
- {/* Floating Emoji */}
1189
- <FloatingEmoji>
1190
- 💻
1191
- </FloatingEmoji>
1188
+ {/* Floating Icon (removed emoji) */}
1192
1189
 
1193
1190
  <Flex direction="column" alignItems="center" gap={6} style={{ position: 'relative', zIndex: 1 }}>
1194
1191
  <Box
@@ -465,7 +465,7 @@ Generated: ${new Date().toLocaleString()}
465
465
  {data.features?.premium && (
466
466
  <Box marginBottom={5} padding={5} background="success50" hasRadius style={{ border: '2px solid #dcfce7' }}>
467
467
  <Typography variant="delta" fontWeight="bold" textColor="success700" style={{ marginBottom: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>
468
- Premium Features Active
468
+ Premium Features Active
469
469
  </Typography>
470
470
  <Flex direction="column" gap={2}>
471
471
  <Typography variant="omega" textColor="success700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
@@ -494,7 +494,7 @@ Generated: ${new Date().toLocaleString()}
494
494
  {data.features?.advanced && (
495
495
  <Box marginBottom={5} padding={5} background="primary50" hasRadius style={{ border: '2px solid #bae6fd' }}>
496
496
  <Typography variant="delta" fontWeight="bold" textColor="primary700" style={{ marginBottom: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>
497
- 🚀 Advanced Features Active
497
+ Advanced Features Active
498
498
  </Typography>
499
499
  <Flex direction="column" gap={2}>
500
500
  <Typography variant="omega" textColor="primary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
@@ -223,12 +223,12 @@ const validateTemplate = (template, templateType) => {
223
223
  // Get default email templates
224
224
  const getDefaultTemplates = () => ({
225
225
  suspiciousLogin: {
226
- subject: '🚨 Suspicious Login Alert - Session Manager',
226
+ subject: '[ALERT] Suspicious Login Alert - Session Manager',
227
227
  html: `
228
228
  <html>
229
229
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
230
230
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9fafb; border-radius: 10px;">
231
- <h2 style="color: #dc2626;">🚨 Suspicious Login Detected</h2>
231
+ <h2 style="color: #dc2626;">[ALERT] Suspicious Login Detected</h2>
232
232
  <p>A potentially suspicious login was detected for your account.</p>
233
233
 
234
234
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -263,7 +263,7 @@ const getDefaultTemplates = () => ({
263
263
  </div>
264
264
  </body>
265
265
  </html>`,
266
- text: `🚨 Suspicious Login Detected
266
+ text: `[ALERT] Suspicious Login Detected
267
267
 
268
268
  A potentially suspicious login was detected for your account.
269
269
 
@@ -278,12 +278,12 @@ Login Details:
278
278
  Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThreat}}, Score={{reason.securityScore}}/100`,
279
279
  },
280
280
  newLocation: {
281
- subject: '📍 New Location Login Detected',
281
+ subject: '[LOCATION] New Location Login Detected',
282
282
  html: `
283
283
  <html>
284
284
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
285
285
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f0f9ff; border-radius: 10px;">
286
- <h2 style="color: #0284c7;">📍 Login from New Location</h2>
286
+ <h2 style="color: #0284c7;">[LOCATION] Login from New Location</h2>
287
287
  <p>Your account was accessed from a new location.</p>
288
288
 
289
289
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -306,7 +306,7 @@ Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThre
306
306
  </div>
307
307
  </body>
308
308
  </html>`,
309
- text: `📍 Login from New Location
309
+ text: `[LOCATION] Login from New Location
310
310
 
311
311
  Your account was accessed from a new location.
312
312
 
@@ -321,12 +321,12 @@ New Location Details:
321
321
  If this was you, no action is needed.`,
322
322
  },
323
323
  vpnProxy: {
324
- subject: '⚠️ VPN/Proxy Login Detected',
324
+ subject: '[WARNING] VPN/Proxy Login Detected',
325
325
  html: `
326
326
  <html>
327
327
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
328
328
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #fffbeb; border-radius: 10px;">
329
- <h2 style="color: #d97706;">⚠️ VPN/Proxy Detected</h2>
329
+ <h2 style="color: #d97706;">[WARNING] VPN/Proxy Detected</h2>
330
330
  <p>A login from a VPN or proxy service was detected on your account.</p>
331
331
 
332
332
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -351,7 +351,7 @@ If this was you, no action is needed.`,
351
351
  </div>
352
352
  </body>
353
353
  </html>`,
354
- text: `⚠️ VPN/Proxy Detected
354
+ text: `[WARNING] VPN/Proxy Detected
355
355
 
356
356
  A login from a VPN or proxy service was detected on your account.
357
357
 
@@ -517,7 +517,7 @@ const SettingsPage = () => {
517
517
  };
518
518
 
519
519
  const handleCleanInactive = async () => {
520
- if (!confirm('⚠️ WARNING: This will permanently delete ALL inactive sessions.\n\nContinue?')) {
520
+ if (!confirm('[WARNING] This will permanently delete ALL inactive sessions.\n\nContinue?')) {
521
521
  return;
522
522
  }
523
523
 
@@ -644,7 +644,7 @@ const SettingsPage = () => {
644
644
 
645
645
  {/* Session Timeout */}
646
646
  <Typography variant="sigma" fontWeight="bold" style={{ marginBottom: '16px', display: 'block', color: theme.colors.neutral[700] }}>
647
- ⏱️ SESSION TIMEOUT
647
+ SESSION TIMEOUT
648
648
  </Typography>
649
649
  <Grid.Root gap={6} style={{ marginBottom: '32px' }}>
650
650
  <Grid.Item col={6} s={12}>
@@ -785,7 +785,7 @@ const SettingsPage = () => {
785
785
  <Box padding={6}>
786
786
 
787
787
  <Typography variant="sigma" fontWeight="bold" style={{ marginBottom: '16px', display: 'block', color: theme.colors.neutral[700] }}>
788
- 🔒 SECURITY OPTIONS
788
+ SECURITY OPTIONS
789
789
  </Typography>
790
790
 
791
791
  {/* Encryption Key Generator */}
@@ -1118,7 +1118,7 @@ const SettingsPage = () => {
1118
1118
  onChange={() => handleChange('alertOnSuspiciousLogin', !settings.alertOnSuspiciousLogin)}
1119
1119
  >
1120
1120
  <Typography variant="omega" fontWeight="semiBold" style={{ fontSize: '14px' }}>
1121
- 🚨 Suspicious Login
1121
+ Suspicious Login
1122
1122
  </Typography>
1123
1123
  </Checkbox>
1124
1124
  </Box>
@@ -1140,7 +1140,7 @@ const SettingsPage = () => {
1140
1140
  onChange={() => handleChange('alertOnNewLocation', !settings.alertOnNewLocation)}
1141
1141
  >
1142
1142
  <Typography variant="omega" fontWeight="semiBold" style={{ fontSize: '14px' }}>
1143
- 📍 New Location
1143
+ New Location
1144
1144
  </Typography>
1145
1145
  </Checkbox>
1146
1146
  </Box>
@@ -1162,7 +1162,7 @@ const SettingsPage = () => {
1162
1162
  onChange={() => handleChange('alertOnVpnProxy', !settings.alertOnVpnProxy)}
1163
1163
  >
1164
1164
  <Typography variant="omega" fontWeight="semiBold" style={{ fontSize: '14px' }}>
1165
- ⚠️ VPN/Proxy
1165
+ VPN/Proxy
1166
1166
  </Typography>
1167
1167
  </Checkbox>
1168
1168
  </Box>
@@ -1172,7 +1172,7 @@ const SettingsPage = () => {
1172
1172
  {/* Email Templates */}
1173
1173
  <Divider style={{ marginBottom: '24px' }} />
1174
1174
  <Typography variant="sigma" fontWeight="bold" style={{ marginBottom: '8px', display: 'block', color: theme.colors.neutral[700] }}>
1175
- 📝 EMAIL TEMPLATES
1175
+ EMAIL TEMPLATES
1176
1176
  </Typography>
1177
1177
  <Typography variant="pi" textColor="neutral600" style={{ marginBottom: '20px', display: 'block', fontSize: '12px' }}>
1178
1178
  Customize email notification templates with dynamic variables
@@ -1181,9 +1181,9 @@ const SettingsPage = () => {
1181
1181
  {/* Template Tabs */}
1182
1182
  <Tabs.Root value={activeTemplateTab} onValueChange={setActiveTemplateTab}>
1183
1183
  <Tabs.List aria-label="Email Templates">
1184
- <Tabs.Trigger value="suspiciousLogin">🚨 Suspicious Login</Tabs.Trigger>
1185
- <Tabs.Trigger value="newLocation">📍 New Location</Tabs.Trigger>
1186
- <Tabs.Trigger value="vpnProxy">⚠️ VPN/Proxy</Tabs.Trigger>
1184
+ <Tabs.Trigger value="suspiciousLogin">Suspicious Login</Tabs.Trigger>
1185
+ <Tabs.Trigger value="newLocation">New Location</Tabs.Trigger>
1186
+ <Tabs.Trigger value="vpnProxy">VPN/Proxy</Tabs.Trigger>
1187
1187
  </Tabs.List>
1188
1188
 
1189
1189
  {Object.keys(settings.emailTemplates).map((templateKey) => (
@@ -1192,7 +1192,7 @@ const SettingsPage = () => {
1192
1192
  {/* Subject */}
1193
1193
  <Box style={{ marginBottom: '24px' }}>
1194
1194
  <Typography variant="pi" fontWeight="bold" style={{ marginBottom: '8px', display: 'block' }}>
1195
- ✉️ Email Subject
1195
+ Email Subject
1196
1196
  </Typography>
1197
1197
  <TextInput
1198
1198
  value={settings.emailTemplates[templateKey].subject}
@@ -1339,7 +1339,7 @@ const SettingsPage = () => {
1339
1339
  type: validation.isValid ? 'success' : 'warning',
1340
1340
  message: validation.isValid
1341
1341
  ? `✓ Template valid! Found ${validation.foundVars.length}/${validation.totalAvailable} variables.`
1342
- : '⚠️ No variables found. Add at least one variable.',
1342
+ : '[WARNING] No variables found. Add at least one variable.',
1343
1343
  });
1344
1344
  }}
1345
1345
  >
@@ -1550,7 +1550,7 @@ const SettingsPage = () => {
1550
1550
  </Box>
1551
1551
  <Flex justifyContent="space-between" alignItems="center" style={{ marginTop: '10px' }}>
1552
1552
  <Typography variant="pi" textColor="neutral600" style={{ fontSize: '12px' }}>
1553
- 💡 Optional: Post session alerts to your Discord channel
1553
+ Optional: Post session alerts to your Discord channel
1554
1554
  </Typography>
1555
1555
  {settings.discordWebhookUrl && (
1556
1556
  <Typography variant="pi" textColor="primary600" style={{ fontSize: '11px', fontFamily: 'monospace' }}>
@@ -1596,7 +1596,7 @@ const SettingsPage = () => {
1596
1596
  </Box>
1597
1597
  <Flex justifyContent="space-between" alignItems="center" style={{ marginTop: '10px' }}>
1598
1598
  <Typography variant="pi" textColor="neutral600" style={{ fontSize: '12px' }}>
1599
- 💡 Optional: Post session alerts to your Slack workspace
1599
+ Optional: Post session alerts to your Slack workspace
1600
1600
  </Typography>
1601
1601
  {settings.slackWebhookUrl && (
1602
1602
  <Typography variant="pi" textColor="primary600" style={{ fontSize: '11px', fontFamily: 'monospace' }}>
@@ -1622,7 +1622,7 @@ const SettingsPage = () => {
1622
1622
  <Check style={{ width: '20px', height: '20px', color: theme.colors.success[600], flexShrink: 0, marginTop: '2px' }} />
1623
1623
  <Box style={{ flex: 1 }}>
1624
1624
  <Typography variant="omega" fontWeight="bold" style={{ marginBottom: '8px', display: 'block', color: theme.colors.primary[700] }}>
1625
- Database-Backed Settings
1625
+ Database-Backed Settings
1626
1626
  </Typography>
1627
1627
  <Typography variant="pi" textColor="primary700" style={{ fontSize: '13px', lineHeight: '1.8' }}>
1628
1628
  All settings are stored in your Strapi database and shared across all admin users.
@@ -206,12 +206,12 @@ const validateTemplate = (template, templateType) => {
206
206
  // Get default email templates
207
207
  const getDefaultTemplates = () => ({
208
208
  suspiciousLogin: {
209
- subject: '🚨 Suspicious Login Alert - Session Manager',
209
+ subject: '[ALERT] Suspicious Login Alert - Session Manager',
210
210
  html: `
211
211
  <html>
212
212
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
213
213
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9fafb; border-radius: 10px;">
214
- <h2 style="color: #dc2626;">🚨 Suspicious Login Detected</h2>
214
+ <h2 style="color: #dc2626;">[ALERT] Suspicious Login Detected</h2>
215
215
  <p>A potentially suspicious login was detected for your account.</p>
216
216
 
217
217
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -246,7 +246,7 @@ const getDefaultTemplates = () => ({
246
246
  </div>
247
247
  </body>
248
248
  </html>`,
249
- text: `🚨 Suspicious Login Detected
249
+ text: `[ALERT] Suspicious Login Detected
250
250
 
251
251
  A potentially suspicious login was detected for your account.
252
252
 
@@ -261,12 +261,12 @@ Login Details:
261
261
  Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThreat}}, Score={{reason.securityScore}}/100`,
262
262
  },
263
263
  newLocation: {
264
- subject: '📍 New Location Login Detected',
264
+ subject: '[LOCATION] New Location Login Detected',
265
265
  html: `
266
266
  <html>
267
267
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
268
268
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f0f9ff; border-radius: 10px;">
269
- <h2 style="color: #0284c7;">📍 Login from New Location</h2>
269
+ <h2 style="color: #0284c7;">[LOCATION] Login from New Location</h2>
270
270
  <p>Your account was accessed from a new location.</p>
271
271
 
272
272
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -289,7 +289,7 @@ Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThre
289
289
  </div>
290
290
  </body>
291
291
  </html>`,
292
- text: `📍 Login from New Location
292
+ text: `[LOCATION] Login from New Location
293
293
 
294
294
  Your account was accessed from a new location.
295
295
 
@@ -304,12 +304,12 @@ New Location Details:
304
304
  If this was you, no action is needed.`,
305
305
  },
306
306
  vpnProxy: {
307
- subject: '⚠️ VPN/Proxy Login Detected',
307
+ subject: '[WARNING] VPN/Proxy Login Detected',
308
308
  html: `
309
309
  <html>
310
310
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
311
311
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #fffbeb; border-radius: 10px;">
312
- <h2 style="color: #d97706;">⚠️ VPN/Proxy Detected</h2>
312
+ <h2 style="color: #d97706;">[WARNING] VPN/Proxy Detected</h2>
313
313
  <p>A login from a VPN or proxy service was detected on your account.</p>
314
314
 
315
315
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -334,7 +334,7 @@ If this was you, no action is needed.`,
334
334
  </div>
335
335
  </body>
336
336
  </html>`,
337
- text: `⚠️ VPN/Proxy Detected
337
+ text: `[WARNING] VPN/Proxy Detected
338
338
 
339
339
  A login from a VPN or proxy service was detected on your account.
340
340
 
@@ -444,7 +444,7 @@ const SettingsPage = () => {
444
444
  };
445
445
 
446
446
  const handleCleanInactive = async () => {
447
- if (!confirm('⚠️ WARNING: This will permanently delete ALL inactive sessions.\n\nContinue?')) {
447
+ if (!confirm('[WARNING] This will permanently delete ALL inactive sessions.\n\nContinue?')) {
448
448
  return;
449
449
  }
450
450
 
@@ -553,7 +553,7 @@ const SettingsPage = () => {
553
553
 
554
554
  {/* Session Timeout */}
555
555
  <Typography variant="sigma" fontWeight="bold" style={{ marginBottom: '16px', display: 'block', color: theme.colors.neutral[700] }}>
556
- ⏱️ SESSION TIMEOUT
556
+ SESSION TIMEOUT
557
557
  </Typography>
558
558
  <Grid.Root gap={6} style={{ marginBottom: '32px' }}>
559
559
  <Grid.Item col={6} s={12}>
@@ -694,7 +694,7 @@ const SettingsPage = () => {
694
694
  <Box padding={6}>
695
695
 
696
696
  <Typography variant="sigma" fontWeight="bold" style={{ marginBottom: '16px', display: 'block', color: theme.colors.neutral[700] }}>
697
- 🔒 SECURITY OPTIONS
697
+ SECURITY OPTIONS
698
698
  </Typography>
699
699
 
700
700
  {/* Feature Toggles */}
@@ -866,7 +866,7 @@ const SettingsPage = () => {
866
866
  checked={settings.alertOnSuspiciousLogin}
867
867
  onChange={() => handleChange('alertOnSuspiciousLogin', !settings.alertOnSuspiciousLogin)}
868
868
  >
869
- 🚨 Suspicious Login
869
+ Suspicious Login
870
870
  </Checkbox>
871
871
  </Box>
872
872
  </Grid.Item>
@@ -876,7 +876,7 @@ const SettingsPage = () => {
876
876
  checked={settings.alertOnNewLocation}
877
877
  onChange={() => handleChange('alertOnNewLocation', !settings.alertOnNewLocation)}
878
878
  >
879
- 📍 New Location
879
+ New Location
880
880
  </Checkbox>
881
881
  </Box>
882
882
  </Grid.Item>
@@ -886,7 +886,7 @@ const SettingsPage = () => {
886
886
  checked={settings.alertOnVpnProxy}
887
887
  onChange={() => handleChange('alertOnVpnProxy', !settings.alertOnVpnProxy)}
888
888
  >
889
- ⚠️ VPN/Proxy
889
+ VPN/Proxy
890
890
  </Checkbox>
891
891
  </Box>
892
892
  </Grid.Item>
@@ -895,7 +895,7 @@ const SettingsPage = () => {
895
895
  {/* Email Templates */}
896
896
  <Divider style={{ marginBottom: '24px' }} />
897
897
  <Typography variant="sigma" fontWeight="bold" style={{ marginBottom: '8px', display: 'block', color: theme.colors.neutral[700] }}>
898
- 📝 EMAIL TEMPLATES
898
+ EMAIL TEMPLATES
899
899
  </Typography>
900
900
  <Typography variant="pi" textColor="neutral600" style={{ marginBottom: '20px', display: 'block', fontSize: '12px' }}>
901
901
  Customize email notification templates with dynamic variables
@@ -904,9 +904,9 @@ const SettingsPage = () => {
904
904
  {/* Template Tabs */}
905
905
  <Tabs.Root value={activeTemplateTab} onValueChange={setActiveTemplateTab}>
906
906
  <Tabs.List aria-label="Email Templates">
907
- <Tabs.Trigger value="suspiciousLogin">🚨 Suspicious Login</Tabs.Trigger>
908
- <Tabs.Trigger value="newLocation">📍 New Location</Tabs.Trigger>
909
- <Tabs.Trigger value="vpnProxy">⚠️ VPN/Proxy</Tabs.Trigger>
907
+ <Tabs.Trigger value="suspiciousLogin">Suspicious Login</Tabs.Trigger>
908
+ <Tabs.Trigger value="newLocation">New Location</Tabs.Trigger>
909
+ <Tabs.Trigger value="vpnProxy">VPN/Proxy</Tabs.Trigger>
910
910
  </Tabs.List>
911
911
 
912
912
  {Object.keys(settings.emailTemplates).map((templateKey) => (
@@ -915,7 +915,7 @@ const SettingsPage = () => {
915
915
  {/* Subject */}
916
916
  <Box style={{ marginBottom: '24px' }}>
917
917
  <Typography variant="pi" fontWeight="bold" style={{ marginBottom: '8px', display: 'block' }}>
918
- ✉️ Email Subject
918
+ Email Subject
919
919
  </Typography>
920
920
  <TextInput
921
921
  value={settings.emailTemplates[templateKey].subject}
@@ -1151,7 +1151,7 @@ const SettingsPage = () => {
1151
1151
  <Information style={{ width: '20px', height: '20px', color: theme.colors.neutral[600], flexShrink: 0, marginTop: '2px' }} />
1152
1152
  <Box style={{ flex: 1 }}>
1153
1153
  <Typography variant="omega" fontWeight="bold" style={{ marginBottom: '8px', display: 'block' }}>
1154
- 💡 How to Apply These Settings
1154
+ How to Apply These Settings
1155
1155
  </Typography>
1156
1156
  <Typography variant="pi" textColor="neutral600" style={{ fontSize: '13px', lineHeight: '1.8' }}>
1157
1157
  Settings are saved in your browser. To apply permanently, copy the config below and paste it into{' '}