strapi-plugin-magic-sessionmanager 3.7.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +90 -0
  2. package/admin/src/hooks/useLicense.js +1 -1
  3. package/admin/src/index.js +2 -2
  4. package/admin/src/pages/Settings.jsx +0 -1
  5. package/admin/src/utils/parseUserAgent.js +1 -1
  6. package/dist/_chunks/{Analytics-Bi-vcT63.js → Analytics-ioaeEh-E.js} +2 -2
  7. package/dist/_chunks/{Analytics-BM9i88xu.mjs → Analytics-mYu_uGwU.mjs} +2 -2
  8. package/dist/_chunks/{App-DcnJOCL9.mjs → App-BXpIS12l.mjs} +2 -2
  9. package/dist/_chunks/{App-BbiNy_cT.js → App-DdnUYWbC.js} +2 -2
  10. package/dist/_chunks/{License-DsxP-MAL.mjs → License-C03C2j9P.mjs} +1 -1
  11. package/dist/_chunks/{License-kYo8j2yl.js → License-DZYrOgcx.js} +1 -1
  12. package/dist/_chunks/{Settings-C3sW9eBD.mjs → Settings-0ocB3qHk.mjs} +2 -2
  13. package/dist/_chunks/{Settings-jW0TOE_d.js → Settings-C6_CqpCC.js} +2 -2
  14. package/dist/_chunks/{index-DG9XeVSg.mjs → index-DBRS3kt5.mjs} +7 -7
  15. package/dist/_chunks/{index-Dr2HT-Dd.js → index-DC8Y0qxx.js} +7 -7
  16. package/dist/_chunks/{useLicense-DOkJX-tk.mjs → useLicense-DSLL9n3Y.mjs} +2 -2
  17. package/dist/_chunks/{useLicense-BL_3bX9O.js → useLicense-qgGfMvse.js} +2 -2
  18. package/dist/admin/index.js +1 -1
  19. package/dist/admin/index.mjs +1 -1
  20. package/dist/server/index.js +117 -95
  21. package/dist/server/index.mjs +117 -95
  22. package/package.json +1 -1
  23. package/server/src/bootstrap.js +32 -26
  24. package/server/src/controllers/license.js +4 -4
  25. package/server/src/controllers/session.js +10 -6
  26. package/server/src/destroy.js +1 -1
  27. package/server/src/middlewares/last-seen.js +8 -3
  28. package/server/src/register.js +4 -4
  29. package/server/src/services/geolocation.js +4 -2
  30. package/server/src/services/license-guard.js +13 -10
  31. package/server/src/services/notifications.js +10 -10
  32. package/server/src/services/service.js +1 -1
  33. package/server/src/services/session.js +41 -31
  34. package/server/src/utils/encryption.js +1 -1
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.7.0",
2
+ "version": "4.0.0",
3
3
  "keywords": [
4
4
  "strapi",
5
5
  "strapi-plugin",
@@ -4,14 +4,19 @@
4
4
  * Bootstrap: Mount middleware for session tracking
5
5
  * Sessions are managed via plugin::magic-sessionmanager.session content type
6
6
  *
7
+ * [SUCCESS] Migrated to strapi.documents() API (Strapi v5 Best Practice)
8
+ *
7
9
  * NOTE: For multi-instance deployments, consider Redis locks or session store
8
10
  */
9
11
 
10
12
  const getClientIp = require('./utils/getClientIp');
11
13
  const { encryptToken, decryptToken } = require('./utils/encryption');
12
14
 
15
+ const SESSION_UID = 'plugin::magic-sessionmanager.session';
16
+ const USER_UID = 'plugin::users-permissions.user';
17
+
13
18
  module.exports = async ({ strapi }) => {
14
- strapi.log.info('[magic-sessionmanager] 🚀 Bootstrap starting...');
19
+ strapi.log.info('[magic-sessionmanager] [START] Bootstrap starting...');
15
20
 
16
21
  try {
17
22
  // Initialize License Guard
@@ -23,7 +28,7 @@ module.exports = async ({ strapi }) => {
23
28
 
24
29
  if (!licenseStatus.valid) {
25
30
  strapi.log.error('╔════════════════════════════════════════════════════════════════╗');
26
- strapi.log.error('║ SESSION MANAGER - NO VALID LICENSE ║');
31
+ strapi.log.error('║ [ERROR] SESSION MANAGER - NO VALID LICENSE ║');
27
32
  strapi.log.error('║ ║');
28
33
  strapi.log.error('║ This plugin requires a valid license to operate. ║');
29
34
  strapi.log.error('║ Please activate your license via Admin UI: ║');
@@ -40,7 +45,7 @@ module.exports = async ({ strapi }) => {
40
45
  const storedKey = await pluginStore.get({ key: 'licenseKey' });
41
46
 
42
47
  strapi.log.info('╔════════════════════════════════════════════════════════════════╗');
43
- strapi.log.info('║ SESSION MANAGER LICENSE ACTIVE ║');
48
+ strapi.log.info('║ [SUCCESS] SESSION MANAGER LICENSE ACTIVE ║');
44
49
  strapi.log.info('║ ║');
45
50
 
46
51
  if (licenseStatus.data) {
@@ -53,7 +58,7 @@ module.exports = async ({ strapi }) => {
53
58
  }
54
59
 
55
60
  strapi.log.info('║ ║');
56
- strapi.log.info('║ 🔄 Auto-pinging every 15 minutes ║');
61
+ strapi.log.info('║ [RELOAD] Auto-pinging every 15 minutes ║');
57
62
  strapi.log.info('╚════════════════════════════════════════════════════════════════╝');
58
63
  }
59
64
  }, 3000); // Wait 3 seconds for API to be ready
@@ -80,7 +85,7 @@ module.exports = async ({ strapi }) => {
80
85
  }
81
86
  }, cleanupInterval);
82
87
 
83
- strapi.log.info('[magic-sessionmanager] Periodic cleanup scheduled (every 30 minutes)');
88
+ strapi.log.info('[magic-sessionmanager] [TIME] Periodic cleanup scheduled (every 30 minutes)');
84
89
 
85
90
  // Store interval handle for cleanup on shutdown
86
91
  if (!strapi.sessionManagerIntervals) {
@@ -104,7 +109,7 @@ module.exports = async ({ strapi }) => {
104
109
 
105
110
  // Find session by decrypting tokens and matching
106
111
  // Since tokens are encrypted, we need to get all active sessions and check each one
107
- const allSessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
112
+ const allSessions = await strapi.documents(SESSION_UID).findMany( {
108
113
  filters: {
109
114
  isActive: true,
110
115
  },
@@ -122,8 +127,8 @@ module.exports = async ({ strapi }) => {
122
127
  });
123
128
 
124
129
  if (matchingSession) {
125
- await sessionService.terminateSession({ sessionId: matchingSession.id });
126
- strapi.log.info(`[magic-sessionmanager] 🚪 Logout via /api/auth/logout - Session ${matchingSession.id} terminated`);
130
+ await sessionService.terminateSession({ sessionId: matchingSession.documentId });
131
+ strapi.log.info(`[magic-sessionmanager] [LOGOUT] Logout via /api/auth/logout - Session ${matchingSession.documentId} terminated`);
127
132
  }
128
133
 
129
134
  ctx.status = 200;
@@ -139,7 +144,7 @@ module.exports = async ({ strapi }) => {
139
144
  },
140
145
  }]);
141
146
 
142
- strapi.log.info('[magic-sessionmanager] /api/auth/logout route registered');
147
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] /api/auth/logout route registered');
143
148
 
144
149
  // Middleware to intercept logins
145
150
  strapi.server.use(async (ctx, next) => {
@@ -158,7 +163,7 @@ module.exports = async ({ strapi }) => {
158
163
  const ip = getClientIp(ctx);
159
164
  const userAgent = ctx.request.headers?.['user-agent'] || ctx.request.header?.['user-agent'] || 'unknown';
160
165
 
161
- strapi.log.info(`[magic-sessionmanager] 🔍 Login detected! User: ${user.id} (${user.email || user.username}) from IP: ${ip}`);
166
+ strapi.log.info(`[magic-sessionmanager] [CHECK] Login detected! User: ${user.id} (${user.email || user.username}) from IP: ${ip}`);
162
167
 
163
168
  // Get config
164
169
  const config = strapi.config.get('plugin::magic-sessionmanager') || {};
@@ -216,7 +221,7 @@ module.exports = async ({ strapi }) => {
216
221
 
217
222
  // Block if needed
218
223
  if (shouldBlock) {
219
- strapi.log.warn(`[magic-sessionmanager] 🚫 Blocking login: ${blockReason}`);
224
+ strapi.log.warn(`[magic-sessionmanager] [BLOCKED] Blocking login: ${blockReason}`);
220
225
 
221
226
  // Don't create session, return error
222
227
  ctx.status = 403;
@@ -239,7 +244,7 @@ module.exports = async ({ strapi }) => {
239
244
  refreshToken: ctx.body.refreshToken, // Store Refresh Token (encrypted) if exists
240
245
  });
241
246
 
242
- strapi.log.info(`[magic-sessionmanager] Session created for user ${user.id} (IP: ${ip})`);
247
+ strapi.log.info(`[magic-sessionmanager] [SUCCESS] Session created for user ${user.id} (IP: ${ip})`);
243
248
 
244
249
  // Advanced: Send notifications
245
250
  if (geoData && (config.enableEmailAlerts || config.enableWebhooks)) {
@@ -286,13 +291,13 @@ module.exports = async ({ strapi }) => {
286
291
  }
287
292
  }
288
293
  } catch (err) {
289
- strapi.log.error('[magic-sessionmanager] Error creating session:', err);
294
+ strapi.log.error('[magic-sessionmanager] [ERROR] Error creating session:', err);
290
295
  // Don't throw - login should still succeed even if session creation fails
291
296
  }
292
297
  }
293
298
  });
294
299
 
295
- strapi.log.info('[magic-sessionmanager] Login/Logout interceptor middleware mounted');
300
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] Login/Logout interceptor middleware mounted');
296
301
 
297
302
  // Middleware to block refresh token requests for terminated sessions
298
303
  strapi.server.use(async (ctx, next) => {
@@ -305,7 +310,7 @@ module.exports = async ({ strapi }) => {
305
310
 
306
311
  if (refreshToken) {
307
312
  // Find session with this refresh token
308
- const allSessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
313
+ const allSessions = await strapi.documents(SESSION_UID).findMany( {
309
314
  filters: {
310
315
  isActive: true,
311
316
  },
@@ -323,8 +328,8 @@ module.exports = async ({ strapi }) => {
323
328
  });
324
329
 
325
330
  if (!matchingSession) {
326
- // No active session with this refresh token Block!
327
- strapi.log.warn('[magic-sessionmanager] 🚫 Blocked refresh token request - no active session');
331
+ // No active session with this refresh token - Block!
332
+ strapi.log.warn('[magic-sessionmanager] [BLOCKED] Blocked refresh token request - no active session');
328
333
  ctx.status = 401;
329
334
  ctx.body = {
330
335
  error: {
@@ -336,7 +341,7 @@ module.exports = async ({ strapi }) => {
336
341
  return; // Don't continue
337
342
  }
338
343
 
339
- strapi.log.info(`[magic-sessionmanager] Refresh token allowed for session ${matchingSession.id}`);
344
+ strapi.log.info(`[magic-sessionmanager] [SUCCESS] Refresh token allowed for session ${matchingSession.documentId}`);
340
345
  }
341
346
  } catch (err) {
342
347
  strapi.log.error('[magic-sessionmanager] Error checking refresh token:', err);
@@ -356,7 +361,7 @@ module.exports = async ({ strapi }) => {
356
361
 
357
362
  if (oldRefreshToken) {
358
363
  // Find session and update with new tokens
359
- const allSessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
364
+ const allSessions = await strapi.documents(SESSION_UID).findMany( {
360
365
  filters: {
361
366
  isActive: true,
362
367
  },
@@ -376,7 +381,8 @@ module.exports = async ({ strapi }) => {
376
381
  const encryptedToken = newAccessToken ? encryptToken(newAccessToken) : matchingSession.token;
377
382
  const encryptedRefreshToken = newRefreshToken ? encryptToken(newRefreshToken) : matchingSession.refreshToken;
378
383
 
379
- await strapi.entityService.update('plugin::magic-sessionmanager.session', matchingSession.id, {
384
+ await strapi.documents(SESSION_UID).update({
385
+ documentId: matchingSession.documentId,
380
386
  data: {
381
387
  token: encryptedToken,
382
388
  refreshToken: encryptedRefreshToken,
@@ -384,7 +390,7 @@ module.exports = async ({ strapi }) => {
384
390
  },
385
391
  });
386
392
 
387
- strapi.log.info(`[magic-sessionmanager] 🔄 Tokens refreshed for session ${matchingSession.id}`);
393
+ strapi.log.info(`[magic-sessionmanager] [REFRESH] Tokens refreshed for session ${matchingSession.documentId}`);
388
394
  }
389
395
  }
390
396
  } catch (err) {
@@ -393,18 +399,18 @@ module.exports = async ({ strapi }) => {
393
399
  }
394
400
  });
395
401
 
396
- strapi.log.info('[magic-sessionmanager] Refresh Token interceptor middleware mounted');
402
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] Refresh Token interceptor middleware mounted');
397
403
 
398
404
  // Mount lastSeen update middleware
399
405
  strapi.server.use(
400
406
  require('./middlewares/last-seen')({ strapi, sessionService })
401
407
  );
402
408
 
403
- strapi.log.info('[magic-sessionmanager] LastSeen middleware mounted');
404
- strapi.log.info('[magic-sessionmanager] Bootstrap complete');
405
- strapi.log.info('[magic-sessionmanager] 🎉 Session Manager ready! Sessions stored in plugin::magic-sessionmanager.session');
409
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] LastSeen middleware mounted');
410
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] Bootstrap complete');
411
+ strapi.log.info('[magic-sessionmanager] [READY] Session Manager ready! Sessions stored in plugin::magic-sessionmanager.session');
406
412
 
407
413
  } catch (err) {
408
- strapi.log.error('[magic-sessionmanager] Bootstrap error:', err);
414
+ strapi.log.error('[magic-sessionmanager] [ERROR] Bootstrap error:', err);
409
415
  }
410
416
  };
@@ -219,7 +219,7 @@ module.exports = ({ strapi }) => ({
219
219
  const verification = await licenseGuard.verifyLicense(trimmedKey);
220
220
 
221
221
  if (!verification.valid) {
222
- strapi.log.warn(`[magic-sessionmanager] ⚠️ Invalid license key attempted: ${trimmedKey.substring(0, 8)}...`);
222
+ strapi.log.warn(`[magic-sessionmanager] [WARNING] Invalid license key attempted: ${trimmedKey.substring(0, 8)}...`);
223
223
  return ctx.badRequest('Invalid or expired license key');
224
224
  }
225
225
 
@@ -227,13 +227,13 @@ module.exports = ({ strapi }) => ({
227
227
  const license = await licenseGuard.getLicenseByKey(trimmedKey);
228
228
 
229
229
  if (!license) {
230
- strapi.log.warn(`[magic-sessionmanager] ⚠️ License not found in database: ${trimmedKey.substring(0, 8)}...`);
230
+ strapi.log.warn(`[magic-sessionmanager] [WARNING] License not found in database: ${trimmedKey.substring(0, 8)}...`);
231
231
  return ctx.badRequest('License not found');
232
232
  }
233
233
 
234
234
  // Verify email matches
235
235
  if (license.email.toLowerCase() !== trimmedEmail) {
236
- strapi.log.warn(`[magic-sessionmanager] ⚠️ Email mismatch for license key: ${trimmedKey.substring(0, 8)}... (Attempted: ${trimmedEmail})`);
236
+ strapi.log.warn(`[magic-sessionmanager] [WARNING] Email mismatch for license key: ${trimmedKey.substring(0, 8)}... (Attempted: ${trimmedEmail})`);
237
237
  return ctx.badRequest('Email address does not match this license key');
238
238
  }
239
239
 
@@ -250,7 +250,7 @@ module.exports = ({ strapi }) => ({
250
250
  data: verification.data,
251
251
  };
252
252
 
253
- strapi.log.info(`[magic-sessionmanager] Existing license key validated and stored: ${trimmedKey.substring(0, 8)}... (Email: ${trimmedEmail})`);
253
+ strapi.log.info(`[magic-sessionmanager] [SUCCESS] Existing license key validated and stored: ${trimmedKey.substring(0, 8)}... (Email: ${trimmedEmail})`);
254
254
 
255
255
  return ctx.send({
256
256
  success: true,
@@ -2,6 +2,9 @@
2
2
 
3
3
  const { decryptToken } = require('../utils/encryption');
4
4
 
5
+ const SESSION_UID = 'plugin::magic-sessionmanager.session';
6
+ const USER_UID = 'plugin::users-permissions.user';
7
+
5
8
  /**
6
9
  * Session Controller
7
10
  * Handles HTTP requests for session management
@@ -111,9 +114,9 @@ module.exports = {
111
114
  .service('session');
112
115
 
113
116
  // Find current session by decrypting and comparing tokens
114
- const sessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
117
+ const sessions = await strapi.documents(SESSION_UID).findMany({
115
118
  filters: {
116
- user: { id: userId },
119
+ user: { documentId: userId },
117
120
  isActive: true,
118
121
  },
119
122
  });
@@ -131,8 +134,8 @@ module.exports = {
131
134
 
132
135
  if (matchingSession) {
133
136
  // Terminate only the current session
134
- await sessionService.terminateSession({ sessionId: matchingSession.id });
135
- strapi.log.info(`[magic-sessionmanager] User ${userId} logged out (session ${matchingSession.id})`);
137
+ await sessionService.terminateSession({ sessionId: matchingSession.documentId });
138
+ strapi.log.info(`[magic-sessionmanager] User ${userId} logged out (session ${matchingSession.documentId})`);
136
139
  }
137
140
 
138
141
  ctx.body = {
@@ -343,7 +346,7 @@ module.exports = {
343
346
  const { userId } = ctx.params;
344
347
 
345
348
  // Get current user status
346
- const user = await strapi.entityService.findOne('plugin::users-permissions.user', userId);
349
+ const user = await strapi.documents(USER_UID).findOne({ documentId: userId });
347
350
 
348
351
  if (!user) {
349
352
  return ctx.throw(404, 'User not found');
@@ -352,7 +355,8 @@ module.exports = {
352
355
  // Toggle blocked status
353
356
  const newBlockedStatus = !user.blocked;
354
357
 
355
- await strapi.entityService.update('plugin::users-permissions.user', userId, {
358
+ await strapi.documents(USER_UID).update({
359
+ documentId: userId,
356
360
  data: {
357
361
  blocked: newBlockedStatus,
358
362
  },
@@ -13,6 +13,6 @@ module.exports = async ({ strapi }) => {
13
13
  strapi.log.info('[magic-sessionmanager] 🛑 Session cleanup interval stopped');
14
14
  }
15
15
 
16
- strapi.log.info('[magic-sessionmanager] Plugin cleanup completed');
16
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] Plugin cleanup completed');
17
17
  };
18
18
 
@@ -4,7 +4,12 @@
4
4
  * lastSeen Middleware
5
5
  * Updates user lastSeen and session lastActive on each authenticated request
6
6
  * Rate-limited to prevent DB write noise (default: 30 seconds)
7
+ *
8
+ * [SUCCESS] Migrated to strapi.documents() API (Strapi v5 Best Practice)
7
9
  */
10
+
11
+ const SESSION_UID = 'plugin::magic-sessionmanager.session';
12
+
8
13
  module.exports = ({ strapi, sessionService }) => {
9
14
  return async (ctx, next) => {
10
15
  // BEFORE processing request: Check if user's sessions are active
@@ -13,9 +18,9 @@ module.exports = ({ strapi, sessionService }) => {
13
18
  const userId = ctx.state.user.id;
14
19
 
15
20
  // Check if user has ANY active sessions
16
- const activeSessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
21
+ const activeSessions = await strapi.documents(SESSION_UID).findMany( {
17
22
  filters: {
18
- user: { id: userId },
23
+ user: { documentId: userId },
19
24
  isActive: true,
20
25
  },
21
26
  limit: 1,
@@ -23,7 +28,7 @@ module.exports = ({ strapi, sessionService }) => {
23
28
 
24
29
  // If user has NO active sessions, reject the request
25
30
  if (!activeSessions || activeSessions.length === 0) {
26
- strapi.log.info(`[magic-sessionmanager] 🚫 Blocked request - User ${userId} has no active sessions`);
31
+ strapi.log.info(`[magic-sessionmanager] [BLOCKED] Blocked request - User ${userId} has no active sessions`);
27
32
  return ctx.unauthorized('All sessions have been terminated. Please login again.');
28
33
  }
29
34
  } catch (err) {
@@ -6,7 +6,7 @@
6
6
  * Sessions are accessed via the Session Manager plugin UI components
7
7
  */
8
8
  module.exports = async ({ strapi }) => {
9
- strapi.log.info('[magic-sessionmanager] 🚀 Plugin registration starting...');
9
+ strapi.log.info('[magic-sessionmanager] [START] Plugin registration starting...');
10
10
 
11
11
  try {
12
12
  // Get the user content type
@@ -21,12 +21,12 @@ module.exports = async ({ strapi }) => {
21
21
  // Sessions are managed through SessionInfoPanel sidebar instead
22
22
  if (userCT.attributes && userCT.attributes.sessions) {
23
23
  delete userCT.attributes.sessions;
24
- strapi.log.info('[magic-sessionmanager] Removed sessions field from User content type');
24
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] Removed sessions field from User content type');
25
25
  }
26
26
 
27
- strapi.log.info('[magic-sessionmanager] Plugin registered successfully');
27
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] Plugin registered successfully');
28
28
 
29
29
  } catch (err) {
30
- strapi.log.error('[magic-sessionmanager] Registration error:', err);
30
+ strapi.log.error('[magic-sessionmanager] [ERROR] Registration error:', err);
31
31
  }
32
32
  };
@@ -132,9 +132,11 @@ module.exports = ({ strapi }) => ({
132
132
 
133
133
  /**
134
134
  * Get country flag emoji
135
+ * @param {string} countryCode - ISO 2-letter country code
136
+ * @returns {string} Flag emoji or empty string
135
137
  */
136
138
  getCountryFlag(countryCode) {
137
- if (!countryCode) return '🏳️';
139
+ if (!countryCode) return '';
138
140
 
139
141
  // Convert country code to flag emoji
140
142
  const codePoints = countryCode
@@ -153,7 +155,7 @@ module.exports = ({ strapi }) => ({
153
155
  ip: ipAddress,
154
156
  country: 'Unknown',
155
157
  country_code: 'XX',
156
- country_flag: '🌍',
158
+ country_flag: '[GEO]',
157
159
  city: 'Unknown',
158
160
  region: 'Unknown',
159
161
  timezone: 'Unknown',
@@ -5,6 +5,7 @@
5
5
 
6
6
  const crypto = require('crypto');
7
7
  const os = require('os');
8
+ const pluginPkg = require('../../../package.json');
8
9
 
9
10
  // FIXED LICENSE SERVER URL
10
11
  const LICENSE_SERVER_URL = 'https://magicapi.fitlex.me';
@@ -68,7 +69,9 @@ module.exports = ({ strapi }) => ({
68
69
  },
69
70
 
70
71
  getUserAgent() {
71
- return `Strapi/${strapi.config.get('info.strapi') || '5.0.0'} Node/${process.version} ${os.platform()}/${os.release()}`;
72
+ const pluginVersion = pluginPkg.version || '1.0.0';
73
+ const strapiVersion = strapi.config.get('info.strapi') || '5.0.0';
74
+ return `MagicSessionManager/${pluginVersion} Strapi/${strapiVersion} Node/${process.version} ${os.platform()}/${os.release()}`;
72
75
  },
73
76
 
74
77
  async createLicense({ email, firstName, lastName }) {
@@ -98,14 +101,14 @@ module.exports = ({ strapi }) => ({
98
101
  const data = await response.json();
99
102
 
100
103
  if (data.success) {
101
- strapi.log.info('[magic-sessionmanager] License created:', data.data.licenseKey);
104
+ strapi.log.info('[magic-sessionmanager] [SUCCESS] License created:', data.data.licenseKey);
102
105
  return data.data;
103
106
  } else {
104
- strapi.log.error('[magic-sessionmanager] License creation failed:', data);
107
+ strapi.log.error('[magic-sessionmanager] [ERROR] License creation failed:', data);
105
108
  return null;
106
109
  }
107
110
  } catch (error) {
108
- strapi.log.error('[magic-sessionmanager] Error creating license:', error);
111
+ strapi.log.error('[magic-sessionmanager] [ERROR] Error creating license:', error);
109
112
  return null;
110
113
  }
111
114
  },
@@ -204,11 +207,11 @@ module.exports = ({ strapi }) => ({
204
207
  name: 'magic-sessionmanager'
205
208
  });
206
209
  await pluginStore.set({ key: 'licenseKey', value: licenseKey });
207
- strapi.log.info(`[magic-sessionmanager] License key stored: ${licenseKey.substring(0, 8)}...`);
210
+ strapi.log.info(`[magic-sessionmanager] [SUCCESS] License key stored: ${licenseKey.substring(0, 8)}...`);
208
211
  },
209
212
 
210
213
  startPinging(licenseKey, intervalMinutes = 15) {
211
- strapi.log.info(`[magic-sessionmanager] Starting license pings every ${intervalMinutes} minutes`);
214
+ strapi.log.info(`[magic-sessionmanager] [TIME] Starting license pings every ${intervalMinutes} minutes`);
212
215
 
213
216
  // Immediate ping
214
217
  this.pingLicense(licenseKey);
@@ -230,7 +233,7 @@ module.exports = ({ strapi }) => ({
230
233
  */
231
234
  async initialize() {
232
235
  try {
233
- strapi.log.info('[magic-sessionmanager] 🔐 Initializing License Guard...');
236
+ strapi.log.info('[magic-sessionmanager] [SECURE] Initializing License Guard...');
234
237
 
235
238
  // Check if license key exists in plugin store
236
239
  const pluginStore = strapi.store({
@@ -240,7 +243,7 @@ module.exports = ({ strapi }) => ({
240
243
  const licenseKey = await pluginStore.get({ key: 'licenseKey' });
241
244
 
242
245
  if (!licenseKey) {
243
- strapi.log.info('[magic-sessionmanager] ℹ️ No license found - Running in demo mode');
246
+ strapi.log.info('[magic-sessionmanager] [INFO] No license found - Running in demo mode');
244
247
  return {
245
248
  valid: false,
246
249
  demo: true,
@@ -287,7 +290,7 @@ module.exports = ({ strapi }) => ({
287
290
  gracePeriod: verification.gracePeriod || false,
288
291
  };
289
292
  } else {
290
- strapi.log.error('[magic-sessionmanager] License validation failed');
293
+ strapi.log.error('[magic-sessionmanager] [ERROR] License validation failed');
291
294
  return {
292
295
  valid: false,
293
296
  demo: true,
@@ -296,7 +299,7 @@ module.exports = ({ strapi }) => ({
296
299
  };
297
300
  }
298
301
  } catch (error) {
299
- strapi.log.error('[magic-sessionmanager] Error initializing License Guard:', error);
302
+ strapi.log.error('[magic-sessionmanager] [ERROR] Error initializing License Guard:', error);
300
303
  return {
301
304
  valid: false,
302
305
  demo: true,
@@ -80,14 +80,14 @@ module.exports = ({ strapi }) => ({
80
80
  text: `🚨 Suspicious Login Detected\n\nA potentially suspicious login was detected for your account.\n\nAccount: {{user.email}}\nUsername: {{user.username}}\n\nLogin Details:\n- Time: {{session.loginTime}}\n- IP: {{session.ipAddress}}\n- Location: {{geo.city}}, {{geo.country}}\n\nSecurity: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThreat}}, Score={{reason.securityScore}}/100`,
81
81
  },
82
82
  newLocation: {
83
- subject: '📍 New Location Login Detected',
84
- html: `<h2>📍 New Location Login</h2><p>Account: {{user.email}}</p><p>Time: {{session.loginTime}}</p><p>Location: {{geo.city}}, {{geo.country}}</p><p>IP: {{session.ipAddress}}</p>`,
85
- text: `📍 New Location Login\n\nAccount: {{user.email}}\nTime: {{session.loginTime}}\nLocation: {{geo.city}}, {{geo.country}}\nIP: {{session.ipAddress}}`,
83
+ subject: '[LOCATION] New Location Login Detected',
84
+ html: `<h2>[LOCATION] New Location Login</h2><p>Account: {{user.email}}</p><p>Time: {{session.loginTime}}</p><p>Location: {{geo.city}}, {{geo.country}}</p><p>IP: {{session.ipAddress}}</p>`,
85
+ text: `[LOCATION] New Location Login\n\nAccount: {{user.email}}\nTime: {{session.loginTime}}\nLocation: {{geo.city}}, {{geo.country}}\nIP: {{session.ipAddress}}`,
86
86
  },
87
87
  vpnProxy: {
88
- subject: '⚠️ VPN/Proxy Login Detected',
89
- html: `<h2>⚠️ VPN/Proxy Detected</h2><p>Account: {{user.email}}</p><p>Time: {{session.loginTime}}</p><p>IP: {{session.ipAddress}}</p><p>VPN: {{reason.isVpn}}, Proxy: {{reason.isProxy}}</p>`,
90
- text: `⚠️ VPN/Proxy Detected\n\nAccount: {{user.email}}\nTime: {{session.loginTime}}\nIP: {{session.ipAddress}}\nVPN: {{reason.isVpn}}, Proxy: {{reason.isProxy}}`,
88
+ subject: '[WARNING] VPN/Proxy Login Detected',
89
+ html: `<h2>[WARNING] VPN/Proxy Detected</h2><p>Account: {{user.email}}</p><p>Time: {{session.loginTime}}</p><p>IP: {{session.ipAddress}}</p><p>VPN: {{reason.isVpn}}, Proxy: {{reason.isProxy}}</p>`,
90
+ text: `[WARNING] VPN/Proxy Detected\n\nAccount: {{user.email}}\nTime: {{session.loginTime}}\nIP: {{session.ipAddress}}\nVPN: {{reason.isVpn}}, Proxy: {{reason.isProxy}}`,
91
91
  },
92
92
  };
93
93
  },
@@ -272,7 +272,7 @@ module.exports = ({ strapi }) => ({
272
272
 
273
273
  if (geoData) {
274
274
  embed.fields.push({
275
- name: '📍 Location',
275
+ name: '[LOCATION] Location',
276
276
  value: `${geoData.country_flag} ${geoData.city}, ${geoData.country}`,
277
277
  inline: true,
278
278
  });
@@ -284,7 +284,7 @@ module.exports = ({ strapi }) => ({
284
284
  if (geoData.isThreat) warnings.push('Threat');
285
285
 
286
286
  embed.fields.push({
287
- name: '⚠️ Security',
287
+ name: '[WARNING] Security',
288
288
  value: `${warnings.join(', ')} detected\nScore: ${geoData.securityScore}/100`,
289
289
  inline: true,
290
290
  });
@@ -297,12 +297,12 @@ module.exports = ({ strapi }) => ({
297
297
  getEventTitle(event) {
298
298
  const titles = {
299
299
  'login.suspicious': '🚨 Suspicious Login',
300
- 'login.new_location': '📍 New Location Login',
300
+ 'login.new_location': '[LOCATION] New Location Login',
301
301
  'login.vpn': '🔴 VPN Login Detected',
302
302
  'login.threat': '⛔ Threat IP Login',
303
303
  'session.terminated': '🔴 Session Terminated',
304
304
  };
305
- return titles[event] || '📊 Session Event';
305
+ return titles[event] || '[STATS] Session Event';
306
306
  },
307
307
 
308
308
  getEventColor(event) {
@@ -1,6 +1,6 @@
1
1
  const service = ({ strapi }) => ({
2
2
  getWelcomeMessage() {
3
- return 'Welcome to Strapi 🚀';
3
+ return 'Welcome to Strapi [START]';
4
4
  },
5
5
  });
6
6