strapi-plugin-magic-sessionmanager 3.7.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 (43) hide show
  1. package/README.md +90 -0
  2. package/admin/src/components/LicenseGuard.jsx +6 -6
  3. package/admin/src/components/SessionDetailModal.jsx +12 -12
  4. package/admin/src/components/SessionInfoCard.jsx +3 -3
  5. package/admin/src/components/SessionInfoPanel.jsx +3 -2
  6. package/admin/src/hooks/useLicense.js +1 -1
  7. package/admin/src/index.js +2 -2
  8. package/admin/src/pages/Analytics.jsx +2 -2
  9. package/admin/src/pages/HomePage.jsx +11 -14
  10. package/admin/src/pages/License.jsx +2 -2
  11. package/admin/src/pages/Settings.jsx +24 -25
  12. package/admin/src/pages/SettingsNew.jsx +21 -21
  13. package/admin/src/utils/parseUserAgent.js +7 -7
  14. package/dist/_chunks/{Analytics-Bi-vcT63.js → Analytics-BBdv1I5y.js} +4 -4
  15. package/dist/_chunks/{Analytics-BM9i88xu.mjs → Analytics-Dv9f_0eZ.mjs} +4 -4
  16. package/dist/_chunks/{App-DcnJOCL9.mjs → App-CIQ-7sa7.mjs} +26 -31
  17. package/dist/_chunks/{App-BbiNy_cT.js → App-CJaZPNjt.js} +26 -31
  18. package/dist/_chunks/{License-kYo8j2yl.js → License-D24rgaZQ.js} +3 -3
  19. package/dist/_chunks/{License-DsxP-MAL.mjs → License-nrmFxoBm.mjs} +3 -3
  20. package/dist/_chunks/{Settings-jW0TOE_d.js → Settings-CqxgjU0y.js} +26 -26
  21. package/dist/_chunks/{Settings-C3sW9eBD.mjs → Settings-D5dLEGc_.mjs} +26 -26
  22. package/dist/_chunks/{index-DG9XeVSg.mjs → index-Duk1_Wrz.mjs} +15 -15
  23. package/dist/_chunks/{index-Dr2HT-Dd.js → index-WH04CS1c.js} +15 -15
  24. package/dist/_chunks/{useLicense-BL_3bX9O.js → useLicense-BwOlCyhc.js} +2 -2
  25. package/dist/_chunks/{useLicense-DOkJX-tk.mjs → useLicense-Ce8GaxB0.mjs} +2 -2
  26. package/dist/admin/index.js +1 -1
  27. package/dist/admin/index.mjs +1 -1
  28. package/dist/server/index.js +250 -119
  29. package/dist/server/index.mjs +250 -119
  30. package/package.json +1 -1
  31. package/server/src/bootstrap.js +106 -28
  32. package/server/src/controllers/license.js +4 -4
  33. package/server/src/controllers/session.js +67 -13
  34. package/server/src/destroy.js +1 -1
  35. package/server/src/middlewares/last-seen.js +13 -7
  36. package/server/src/register.js +4 -4
  37. package/server/src/routes/content-api.js +11 -2
  38. package/server/src/services/geolocation.js +4 -2
  39. package/server/src/services/license-guard.js +13 -10
  40. package/server/src/services/notifications.js +20 -20
  41. package/server/src/services/service.js +1 -1
  42. package/server/src/services/session.js +63 -33
  43. package/server/src/utils/encryption.js +1 -1
@@ -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,
@@ -37,12 +37,12 @@ module.exports = ({ strapi }) => ({
37
37
  strapi.log.debug('[magic-sessionmanager/notifications] Using default fallback templates');
38
38
  return {
39
39
  suspiciousLogin: {
40
- subject: '🚨 Suspicious Login Alert - Session Manager',
40
+ subject: '[ALERT] Suspicious Login Alert - Session Manager',
41
41
  html: `
42
42
  <html>
43
43
  <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
44
44
  <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9fafb; border-radius: 10px;">
45
- <h2 style="color: #dc2626;">🚨 Suspicious Login Detected</h2>
45
+ <h2 style="color: #dc2626;">[ALERT] Suspicious Login Detected</h2>
46
46
  <p>A potentially suspicious login was detected for your account.</p>
47
47
 
48
48
  <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
@@ -77,17 +77,17 @@ module.exports = ({ strapi }) => ({
77
77
  </div>
78
78
  </body>
79
79
  </html>`,
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`,
80
+ text: `[ALERT] 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
  },
@@ -262,9 +262,9 @@ module.exports = ({ strapi }) => ({
262
262
  title: this.getEventTitle(event),
263
263
  color: this.getEventColor(event),
264
264
  fields: [
265
- { name: '👤 User', value: `${user.email}\n${user.username || 'N/A'}`, inline: true },
266
- { name: '🌐 IP', value: session.ipAddress, inline: true },
267
- { name: '📅 Time', value: new Date(session.loginTime).toLocaleString(), inline: false },
265
+ { name: 'User', value: `${user.email}\n${user.username || 'N/A'}`, inline: true },
266
+ { name: 'IP', value: session.ipAddress, inline: true },
267
+ { name: 'Time', value: new Date(session.loginTime).toLocaleString(), inline: false },
268
268
  ],
269
269
  timestamp: new Date().toISOString(),
270
270
  footer: { text: 'Magic Session Manager' },
@@ -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
  });
@@ -296,13 +296,13 @@ module.exports = ({ strapi }) => ({
296
296
 
297
297
  getEventTitle(event) {
298
298
  const titles = {
299
- 'login.suspicious': '🚨 Suspicious Login',
300
- 'login.new_location': '📍 New Location Login',
301
- 'login.vpn': '🔴 VPN Login Detected',
302
- 'login.threat': ' Threat IP Login',
303
- 'session.terminated': '🔴 Session Terminated',
299
+ 'login.suspicious': '[ALERT] Suspicious Login',
300
+ 'login.new_location': '[LOCATION] New Location Login',
301
+ 'login.vpn': '[WARNING] VPN Login Detected',
302
+ 'login.threat': '[THREAT] Threat IP Login',
303
+ 'session.terminated': '[INFO] 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
 
@@ -9,11 +9,17 @@ const { encryptToken, decryptToken, generateSessionId } = require('../utils/encr
9
9
  *
10
10
  * SECURITY: JWT tokens are encrypted before storing in database using AES-256-GCM
11
11
  *
12
+ * [SUCCESS] Migrated to strapi.documents() API (Strapi v5 Best Practice)
13
+ *
12
14
  * TODO: For production multi-instance deployments, use Redis for:
13
15
  * - Session store instead of DB
14
16
  * - Rate limiting locks
15
17
  * - Distributed session state
16
18
  */
19
+
20
+ const SESSION_UID = 'plugin::magic-sessionmanager.session';
21
+ const USER_UID = 'plugin::users-permissions.user';
22
+
17
23
  module.exports = ({ strapi }) => ({
18
24
  /**
19
25
  * Create a new session record
@@ -31,21 +37,22 @@ module.exports = ({ strapi }) => ({
31
37
  const encryptedToken = token ? encryptToken(token) : null;
32
38
  const encryptedRefreshToken = refreshToken ? encryptToken(refreshToken) : null;
33
39
 
34
- const session = await strapi.entityService.create('plugin::magic-sessionmanager.session', {
40
+ // Using Document Service API (Strapi v5)
41
+ const session = await strapi.documents(SESSION_UID).create({
35
42
  data: {
36
- user: userId,
43
+ user: userId, // userId should be documentId (string)
37
44
  ipAddress: ip.substring(0, 45),
38
45
  userAgent: userAgent.substring(0, 500),
39
46
  loginTime: now,
40
47
  lastActive: now,
41
48
  isActive: true,
42
- token: encryptedToken, // Encrypted Access Token
43
- refreshToken: encryptedRefreshToken, // Encrypted Refresh Token
44
- sessionId: sessionId, // Unique identifier
49
+ token: encryptedToken, // [SUCCESS] Encrypted Access Token
50
+ refreshToken: encryptedRefreshToken, // [SUCCESS] Encrypted Refresh Token
51
+ sessionId: sessionId, // [SUCCESS] Unique identifier
45
52
  },
46
53
  });
47
54
 
48
- strapi.log.info(`[magic-sessionmanager] Session ${session.id} (${sessionId}) created for user ${userId}`);
55
+ strapi.log.info(`[magic-sessionmanager] [SUCCESS] Session ${session.documentId} (${sessionId}) created for user ${userId}`);
49
56
 
50
57
  return session;
51
58
  } catch (err) {
@@ -56,6 +63,7 @@ module.exports = ({ strapi }) => ({
56
63
 
57
64
  /**
58
65
  * Terminate a session or all sessions for a user
66
+ * Supports both numeric id (legacy) and documentId (Strapi v5)
59
67
  * @param {Object} params - { sessionId | userId }
60
68
  * @returns {Promise<void>}
61
69
  */
@@ -64,7 +72,9 @@ module.exports = ({ strapi }) => ({
64
72
  const now = new Date();
65
73
 
66
74
  if (sessionId) {
67
- await strapi.entityService.update('plugin::magic-sessionmanager.session', sessionId, {
75
+ // Using Document Service API (Strapi v5)
76
+ await strapi.documents(SESSION_UID).update({
77
+ documentId: sessionId,
68
78
  data: {
69
79
  isActive: false,
70
80
  logoutTime: now,
@@ -73,17 +83,27 @@ module.exports = ({ strapi }) => ({
73
83
 
74
84
  strapi.log.info(`[magic-sessionmanager] Session ${sessionId} terminated`);
75
85
  } else if (userId) {
76
- // Find all active sessions for user
77
- const activeSessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
86
+ // Strapi v5: If numeric id provided, look up documentId first
87
+ let userDocumentId = userId;
88
+ if (!isNaN(userId)) {
89
+ const user = await strapi.entityService.findOne(USER_UID, parseInt(userId, 10));
90
+ if (user) {
91
+ userDocumentId = user.documentId;
92
+ }
93
+ }
94
+
95
+ // Find all active sessions for user - use Deep Filtering (Strapi v5)
96
+ const activeSessions = await strapi.documents(SESSION_UID).findMany({
78
97
  filters: {
79
- user: { id: userId },
98
+ user: { documentId: userDocumentId }, // Deep filtering syntax
80
99
  isActive: true,
81
100
  },
82
101
  });
83
102
 
84
103
  // Terminate all active sessions
85
104
  for (const session of activeSessions) {
86
- await strapi.entityService.update('plugin::magic-sessionmanager.session', session.id, {
105
+ await strapi.documents(SESSION_UID).update({
106
+ documentId: session.documentId,
87
107
  data: {
88
108
  isActive: false,
89
109
  logoutTime: now,
@@ -91,7 +111,7 @@ module.exports = ({ strapi }) => ({
91
111
  });
92
112
  }
93
113
 
94
- strapi.log.info(`[magic-sessionmanager] All sessions terminated for user ${userId}`);
114
+ strapi.log.info(`[magic-sessionmanager] All sessions terminated for user ${userDocumentId}`);
95
115
  }
96
116
  } catch (err) {
97
117
  strapi.log.error('[magic-sessionmanager] Error terminating session:', err);
@@ -105,7 +125,7 @@ module.exports = ({ strapi }) => ({
105
125
  */
106
126
  async getAllSessions() {
107
127
  try {
108
- const sessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
128
+ const sessions = await strapi.documents(SESSION_UID).findMany( {
109
129
  populate: { user: { fields: ['id', 'email', 'username'] } },
110
130
  sort: { loginTime: 'desc' },
111
131
  limit: 1000, // Reasonable limit
@@ -147,7 +167,7 @@ module.exports = ({ strapi }) => ({
147
167
  */
148
168
  async getActiveSessions() {
149
169
  try {
150
- const sessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
170
+ const sessions = await strapi.documents(SESSION_UID).findMany( {
151
171
  filters: { isActive: true },
152
172
  populate: { user: { fields: ['id', 'email', 'username'] } },
153
173
  sort: { loginTime: 'desc' },
@@ -186,13 +206,23 @@ module.exports = ({ strapi }) => ({
186
206
 
187
207
  /**
188
208
  * Get all sessions for a specific user
189
- * @param {number} userId
209
+ * Supports both numeric id (legacy) and documentId (Strapi v5)
210
+ * @param {string|number} userId - User documentId or numeric id
190
211
  * @returns {Promise<Array>} User's sessions with accurate online status
191
212
  */
192
213
  async getUserSessions(userId) {
193
214
  try {
194
- const sessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
195
- filters: { user: { id: userId } },
215
+ // Strapi v5: If numeric id provided, look up documentId first
216
+ let userDocumentId = userId;
217
+ if (!isNaN(userId)) {
218
+ const user = await strapi.entityService.findOne(USER_UID, parseInt(userId, 10));
219
+ if (user) {
220
+ userDocumentId = user.documentId;
221
+ }
222
+ }
223
+
224
+ const sessions = await strapi.documents(SESSION_UID).findMany( {
225
+ filters: { user: { documentId: userDocumentId } },
196
226
  sort: { loginTime: 'desc' },
197
227
  });
198
228
 
@@ -241,20 +271,20 @@ module.exports = ({ strapi }) => ({
241
271
 
242
272
  // Update session lastActive only
243
273
  if (sessionId) {
244
- const session = await strapi.entityService.findOne('plugin::magic-sessionmanager.session', sessionId);
274
+ const session = await strapi.documents(SESSION_UID).findOne({ documentId: sessionId });
245
275
 
246
276
  if (session && session.lastActive) {
247
277
  const lastActiveTime = new Date(session.lastActive).getTime();
248
278
  const currentTime = now.getTime();
249
279
 
250
280
  if (currentTime - lastActiveTime > rateLimit) {
251
- await strapi.entityService.update('plugin::magic-sessionmanager.session', sessionId, {
281
+ await strapi.documents(SESSION_UID).update({ documentId: sessionId,
252
282
  data: { lastActive: now },
253
283
  });
254
284
  }
255
285
  } else if (session) {
256
286
  // First time or null
257
- await strapi.entityService.update('plugin::magic-sessionmanager.session', sessionId, {
287
+ await strapi.documents(SESSION_UID).update({ documentId: sessionId,
258
288
  data: { lastActive: now },
259
289
  });
260
290
  }
@@ -279,12 +309,12 @@ module.exports = ({ strapi }) => ({
279
309
  const now = new Date();
280
310
  const cutoffTime = new Date(now.getTime() - inactivityTimeout);
281
311
 
282
- strapi.log.info(`[magic-sessionmanager] 🧹 Cleaning up sessions inactive since before ${cutoffTime.toISOString()}`);
312
+ strapi.log.info(`[magic-sessionmanager] [CLEANUP] Cleaning up sessions inactive since before ${cutoffTime.toISOString()}`);
283
313
 
284
314
  // Find all active sessions
285
- const activeSessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
315
+ const activeSessions = await strapi.documents(SESSION_UID).findMany({
286
316
  filters: { isActive: true },
287
- fields: ['id', 'lastActive', 'loginTime'],
317
+ fields: ['lastActive', 'loginTime'],
288
318
  });
289
319
 
290
320
  // Deactivate old sessions
@@ -293,14 +323,15 @@ module.exports = ({ strapi }) => ({
293
323
  const lastActiveTime = session.lastActive ? new Date(session.lastActive) : new Date(session.loginTime);
294
324
 
295
325
  if (lastActiveTime < cutoffTime) {
296
- await strapi.entityService.update('plugin::magic-sessionmanager.session', session.id, {
326
+ await strapi.documents(SESSION_UID).update({
327
+ documentId: session.documentId,
297
328
  data: { isActive: false },
298
329
  });
299
330
  deactivatedCount++;
300
331
  }
301
332
  }
302
333
 
303
- strapi.log.info(`[magic-sessionmanager] Cleanup complete: ${deactivatedCount} sessions deactivated`);
334
+ strapi.log.info(`[magic-sessionmanager] [SUCCESS] Cleanup complete: ${deactivatedCount} sessions deactivated`);
304
335
  return deactivatedCount;
305
336
  } catch (err) {
306
337
  strapi.log.error('[magic-sessionmanager] Error cleaning up inactive sessions:', err);
@@ -316,8 +347,8 @@ module.exports = ({ strapi }) => ({
316
347
  */
317
348
  async deleteSession(sessionId) {
318
349
  try {
319
- await strapi.entityService.delete('plugin::magic-sessionmanager.session', sessionId);
320
- strapi.log.info(`[magic-sessionmanager] 🗑️ Session ${sessionId} permanently deleted`);
350
+ await strapi.documents(SESSION_UID).delete({ documentId: sessionId });
351
+ strapi.log.info(`[magic-sessionmanager] [DELETE] Session ${sessionId} permanently deleted`);
321
352
  return true;
322
353
  } catch (err) {
323
354
  strapi.log.error('[magic-sessionmanager] Error deleting session:', err);
@@ -332,23 +363,22 @@ module.exports = ({ strapi }) => ({
332
363
  */
333
364
  async deleteInactiveSessions() {
334
365
  try {
335
- strapi.log.info('[magic-sessionmanager] 🗑️ Deleting all inactive sessions...');
366
+ strapi.log.info('[magic-sessionmanager] [DELETE] Deleting all inactive sessions...');
336
367
 
337
- // Find all inactive sessions
338
- const inactiveSessions = await strapi.entityService.findMany('plugin::magic-sessionmanager.session', {
368
+ // Find all inactive sessions (documentId is always included automatically)
369
+ const inactiveSessions = await strapi.documents(SESSION_UID).findMany({
339
370
  filters: { isActive: false },
340
- fields: ['id'],
341
371
  });
342
372
 
343
373
  let deletedCount = 0;
344
374
 
345
375
  // Delete each inactive session
346
376
  for (const session of inactiveSessions) {
347
- await strapi.entityService.delete('plugin::magic-sessionmanager.session', session.id);
377
+ await strapi.documents(SESSION_UID).delete({ documentId: session.documentId });
348
378
  deletedCount++;
349
379
  }
350
380
 
351
- strapi.log.info(`[magic-sessionmanager] Deleted ${deletedCount} inactive sessions`);
381
+ strapi.log.info(`[magic-sessionmanager] [SUCCESS] Deleted ${deletedCount} inactive sessions`);
352
382
  return deletedCount;
353
383
  } catch (err) {
354
384
  strapi.log.error('[magic-sessionmanager] Error deleting inactive sessions:', err);
@@ -31,7 +31,7 @@ function getEncryptionKey() {
31
31
  const strapiKeys = process.env.APP_KEYS || process.env.API_TOKEN_SALT || 'default-insecure-key';
32
32
  const key = crypto.createHash('sha256').update(strapiKeys).digest();
33
33
 
34
- console.warn('[magic-sessionmanager/encryption] ⚠️ No SESSION_ENCRYPTION_KEY found. Using fallback (not recommended for production).');
34
+ console.warn('[magic-sessionmanager/encryption] [WARNING] No SESSION_ENCRYPTION_KEY found. Using fallback (not recommended for production).');
35
35
  console.warn('[magic-sessionmanager/encryption] Set SESSION_ENCRYPTION_KEY in .env for better security.');
36
36
 
37
37
  return key;