strapi-plugin-magic-sessionmanager 3.6.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 (43) hide show
  1. package/README.md +104 -0
  2. package/admin/src/hooks/useLicense.js +1 -1
  3. package/admin/src/index.js +5 -2
  4. package/admin/src/pages/Settings.jsx +0 -1
  5. package/admin/src/translations/es.json +21 -0
  6. package/admin/src/translations/fr.json +21 -0
  7. package/admin/src/translations/pt.json +21 -0
  8. package/admin/src/utils/parseUserAgent.js +1 -1
  9. package/dist/_chunks/{Analytics-DRzCKaDF.js → Analytics-ioaeEh-E.js} +2 -2
  10. package/dist/_chunks/{Analytics-CwyLwdOZ.mjs → Analytics-mYu_uGwU.mjs} +2 -2
  11. package/dist/_chunks/{App-Zhs_vt59.mjs → App-BXpIS12l.mjs} +2 -2
  12. package/dist/_chunks/{App-nGu2Eb87.js → App-DdnUYWbC.js} +2 -2
  13. package/dist/_chunks/{License-CPI0p_W8.mjs → License-C03C2j9P.mjs} +1 -1
  14. package/dist/_chunks/{License-k5vvhgKr.js → License-DZYrOgcx.js} +1 -1
  15. package/dist/_chunks/{Settings-CL2im8M3.mjs → Settings-0ocB3qHk.mjs} +2 -2
  16. package/dist/_chunks/{Settings-Lkmxisuv.js → Settings-C6_CqpCC.js} +2 -2
  17. package/dist/_chunks/es-CuLHazN1.js +23 -0
  18. package/dist/_chunks/es-Dkmjhy9c.mjs +23 -0
  19. package/dist/_chunks/fr-BAJp2yhI.js +23 -0
  20. package/dist/_chunks/fr-Bssg_3UF.mjs +23 -0
  21. package/dist/_chunks/{index-B-0VPfeF.mjs → index-DBRS3kt5.mjs} +11 -8
  22. package/dist/_chunks/{index-W_QbTAYU.js → index-DC8Y0qxx.js} +11 -8
  23. package/dist/_chunks/pt-BAP9cKs3.js +23 -0
  24. package/dist/_chunks/pt-BVNoNcuY.mjs +23 -0
  25. package/dist/_chunks/{useLicense-DUGjNbQ9.mjs → useLicense-DSLL9n3Y.mjs} +2 -2
  26. package/dist/_chunks/{useLicense-C_Rneohy.js → useLicense-qgGfMvse.js} +2 -2
  27. package/dist/admin/index.js +1 -1
  28. package/dist/admin/index.mjs +1 -1
  29. package/dist/server/index.js +117 -95
  30. package/dist/server/index.mjs +117 -95
  31. package/package.json +1 -1
  32. package/server/src/bootstrap.js +32 -26
  33. package/server/src/controllers/license.js +4 -4
  34. package/server/src/controllers/session.js +10 -6
  35. package/server/src/destroy.js +1 -1
  36. package/server/src/middlewares/last-seen.js +8 -3
  37. package/server/src/register.js +4 -4
  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 +10 -10
  41. package/server/src/services/service.js +1 -1
  42. package/server/src/services/session.js +41 -31
  43. package/server/src/utils/encryption.js +1 -1
@@ -4,7 +4,7 @@ function getDefaultExportFromCjs(x) {
4
4
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
5
5
  }
6
6
  var register$1 = async ({ strapi: strapi2 }) => {
7
- strapi2.log.info("[magic-sessionmanager] 🚀 Plugin registration starting...");
7
+ strapi2.log.info("[magic-sessionmanager] [START] Plugin registration starting...");
8
8
  try {
9
9
  const userCT = strapi2.contentType("plugin::users-permissions.user");
10
10
  if (!userCT) {
@@ -13,11 +13,11 @@ var register$1 = async ({ strapi: strapi2 }) => {
13
13
  }
14
14
  if (userCT.attributes && userCT.attributes.sessions) {
15
15
  delete userCT.attributes.sessions;
16
- strapi2.log.info("[magic-sessionmanager] Removed sessions field from User content type");
16
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Removed sessions field from User content type");
17
17
  }
18
- strapi2.log.info("[magic-sessionmanager] Plugin registered successfully");
18
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Plugin registered successfully");
19
19
  } catch (err) {
20
- strapi2.log.error("[magic-sessionmanager] Registration error:", err);
20
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Registration error:", err);
21
21
  }
22
22
  };
23
23
  const getClientIp$1 = (ctx) => {
@@ -94,7 +94,7 @@ function getEncryptionKey() {
94
94
  }
95
95
  const strapiKeys = process.env.APP_KEYS || process.env.API_TOKEN_SALT || "default-insecure-key";
96
96
  const key = crypto$1.createHash("sha256").update(strapiKeys).digest();
97
- console.warn("[magic-sessionmanager/encryption] ⚠️ No SESSION_ENCRYPTION_KEY found. Using fallback (not recommended for production).");
97
+ console.warn("[magic-sessionmanager/encryption] [WARNING] No SESSION_ENCRYPTION_KEY found. Using fallback (not recommended for production).");
98
98
  console.warn("[magic-sessionmanager/encryption] Set SESSION_ENCRYPTION_KEY in .env for better security.");
99
99
  return key;
100
100
  }
@@ -145,20 +145,21 @@ var encryption = {
145
145
  decryptToken: decryptToken$3,
146
146
  generateSessionId: generateSessionId$1
147
147
  };
148
+ const SESSION_UID$3 = "plugin::magic-sessionmanager.session";
148
149
  var lastSeen = ({ strapi: strapi2, sessionService }) => {
149
150
  return async (ctx, next) => {
150
151
  if (ctx.state.user && ctx.state.user.id) {
151
152
  try {
152
153
  const userId = ctx.state.user.id;
153
- const activeSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
154
+ const activeSessions = await strapi2.documents(SESSION_UID$3).findMany({
154
155
  filters: {
155
- user: { id: userId },
156
+ user: { documentId: userId },
156
157
  isActive: true
157
158
  },
158
159
  limit: 1
159
160
  });
160
161
  if (!activeSessions || activeSessions.length === 0) {
161
- strapi2.log.info(`[magic-sessionmanager] 🚫 Blocked request - User ${userId} has no active sessions`);
162
+ strapi2.log.info(`[magic-sessionmanager] [BLOCKED] Blocked request - User ${userId} has no active sessions`);
162
163
  return ctx.unauthorized("All sessions have been terminated. Please login again.");
163
164
  }
164
165
  } catch (err) {
@@ -182,15 +183,16 @@ var lastSeen = ({ strapi: strapi2, sessionService }) => {
182
183
  };
183
184
  const getClientIp = getClientIp_1;
184
185
  const { encryptToken: encryptToken$1, decryptToken: decryptToken$2 } = encryption;
186
+ const SESSION_UID$2 = "plugin::magic-sessionmanager.session";
185
187
  var bootstrap$1 = async ({ strapi: strapi2 }) => {
186
- strapi2.log.info("[magic-sessionmanager] 🚀 Bootstrap starting...");
188
+ strapi2.log.info("[magic-sessionmanager] [START] Bootstrap starting...");
187
189
  try {
188
190
  const licenseGuardService = strapi2.plugin("magic-sessionmanager").service("license-guard");
189
191
  setTimeout(async () => {
190
192
  const licenseStatus = await licenseGuardService.initialize();
191
193
  if (!licenseStatus.valid) {
192
194
  strapi2.log.error("╔════════════════════════════════════════════════════════════════╗");
193
- strapi2.log.error("║ SESSION MANAGER - NO VALID LICENSE ║");
195
+ strapi2.log.error("║ [ERROR] SESSION MANAGER - NO VALID LICENSE ║");
194
196
  strapi2.log.error("║ ║");
195
197
  strapi2.log.error("║ This plugin requires a valid license to operate. ║");
196
198
  strapi2.log.error("║ Please activate your license via Admin UI: ║");
@@ -206,7 +208,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
206
208
  });
207
209
  const storedKey = await pluginStore.get({ key: "licenseKey" });
208
210
  strapi2.log.info("╔════════════════════════════════════════════════════════════════╗");
209
- strapi2.log.info("║ SESSION MANAGER LICENSE ACTIVE ║");
211
+ strapi2.log.info("║ [SUCCESS] SESSION MANAGER LICENSE ACTIVE ║");
210
212
  strapi2.log.info("║ ║");
211
213
  if (licenseStatus.data) {
212
214
  strapi2.log.info(`║ License: ${licenseStatus.data.licenseKey}`.padEnd(66) + "║");
@@ -217,7 +219,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
217
219
  strapi2.log.info(`║ Status: Grace Period Active`.padEnd(66) + "║");
218
220
  }
219
221
  strapi2.log.info("║ ║");
220
- strapi2.log.info("║ 🔄 Auto-pinging every 15 minutes ║");
222
+ strapi2.log.info("║ [RELOAD] Auto-pinging every 15 minutes ║");
221
223
  strapi2.log.info("╚════════════════════════════════════════════════════════════════╝");
222
224
  }
223
225
  }, 3e3);
@@ -233,7 +235,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
233
235
  strapi2.log.error("[magic-sessionmanager] Periodic cleanup error:", err);
234
236
  }
235
237
  }, cleanupInterval);
236
- strapi2.log.info("[magic-sessionmanager] Periodic cleanup scheduled (every 30 minutes)");
238
+ strapi2.log.info("[magic-sessionmanager] [TIME] Periodic cleanup scheduled (every 30 minutes)");
237
239
  if (!strapi2.sessionManagerIntervals) {
238
240
  strapi2.sessionManagerIntervals = {};
239
241
  }
@@ -249,7 +251,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
249
251
  ctx.body = { message: "Logged out successfully" };
250
252
  return;
251
253
  }
252
- const allSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
254
+ const allSessions = await strapi2.documents(SESSION_UID$2).findMany({
253
255
  filters: {
254
256
  isActive: true
255
257
  }
@@ -264,8 +266,8 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
264
266
  }
265
267
  });
266
268
  if (matchingSession) {
267
- await sessionService.terminateSession({ sessionId: matchingSession.id });
268
- strapi2.log.info(`[magic-sessionmanager] 🚪 Logout via /api/auth/logout - Session ${matchingSession.id} terminated`);
269
+ await sessionService.terminateSession({ sessionId: matchingSession.documentId });
270
+ strapi2.log.info(`[magic-sessionmanager] [LOGOUT] Logout via /api/auth/logout - Session ${matchingSession.documentId} terminated`);
269
271
  }
270
272
  ctx.status = 200;
271
273
  ctx.body = { message: "Logged out successfully" };
@@ -279,7 +281,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
279
281
  auth: false
280
282
  }
281
283
  }]);
282
- strapi2.log.info("[magic-sessionmanager] /api/auth/logout route registered");
284
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] /api/auth/logout route registered");
283
285
  strapi2.server.use(async (ctx, next) => {
284
286
  await next();
285
287
  const isAuthLocal = ctx.path === "/api/auth/local" && ctx.method === "POST";
@@ -289,7 +291,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
289
291
  const user = ctx.body.user;
290
292
  const ip = getClientIp(ctx);
291
293
  const userAgent = ctx.request.headers?.["user-agent"] || ctx.request.header?.["user-agent"] || "unknown";
292
- strapi2.log.info(`[magic-sessionmanager] 🔍 Login detected! User: ${user.id} (${user.email || user.username}) from IP: ${ip}`);
294
+ strapi2.log.info(`[magic-sessionmanager] [CHECK] Login detected! User: ${user.id} (${user.email || user.username}) from IP: ${ip}`);
293
295
  const config2 = strapi2.config.get("plugin::magic-sessionmanager") || {};
294
296
  let shouldBlock = false;
295
297
  let blockReason = "";
@@ -331,7 +333,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
331
333
  }
332
334
  }
333
335
  if (shouldBlock) {
334
- strapi2.log.warn(`[magic-sessionmanager] 🚫 Blocking login: ${blockReason}`);
336
+ strapi2.log.warn(`[magic-sessionmanager] [BLOCKED] Blocking login: ${blockReason}`);
335
337
  ctx.status = 403;
336
338
  ctx.body = {
337
339
  error: {
@@ -351,7 +353,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
351
353
  refreshToken: ctx.body.refreshToken
352
354
  // Store Refresh Token (encrypted) if exists
353
355
  });
354
- strapi2.log.info(`[magic-sessionmanager] Session created for user ${user.id} (IP: ${ip})`);
356
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Session created for user ${user.id} (IP: ${ip})`);
355
357
  if (geoData && (config2.enableEmailAlerts || config2.enableWebhooks)) {
356
358
  try {
357
359
  const notificationService = strapi2.plugin("magic-sessionmanager").service("notifications");
@@ -389,18 +391,18 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
389
391
  }
390
392
  }
391
393
  } catch (err) {
392
- strapi2.log.error("[magic-sessionmanager] Error creating session:", err);
394
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Error creating session:", err);
393
395
  }
394
396
  }
395
397
  });
396
- strapi2.log.info("[magic-sessionmanager] Login/Logout interceptor middleware mounted");
398
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Login/Logout interceptor middleware mounted");
397
399
  strapi2.server.use(async (ctx, next) => {
398
400
  const isRefreshToken = ctx.path === "/api/auth/refresh" && ctx.method === "POST";
399
401
  if (isRefreshToken) {
400
402
  try {
401
403
  const refreshToken = ctx.request.body?.refreshToken;
402
404
  if (refreshToken) {
403
- const allSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
405
+ const allSessions = await strapi2.documents(SESSION_UID$2).findMany({
404
406
  filters: {
405
407
  isActive: true
406
408
  }
@@ -415,7 +417,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
415
417
  }
416
418
  });
417
419
  if (!matchingSession) {
418
- strapi2.log.warn("[magic-sessionmanager] 🚫 Blocked refresh token request - no active session");
420
+ strapi2.log.warn("[magic-sessionmanager] [BLOCKED] Blocked refresh token request - no active session");
419
421
  ctx.status = 401;
420
422
  ctx.body = {
421
423
  error: {
@@ -426,7 +428,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
426
428
  };
427
429
  return;
428
430
  }
429
- strapi2.log.info(`[magic-sessionmanager] Refresh token allowed for session ${matchingSession.id}`);
431
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Refresh token allowed for session ${matchingSession.documentId}`);
430
432
  }
431
433
  } catch (err) {
432
434
  strapi2.log.error("[magic-sessionmanager] Error checking refresh token:", err);
@@ -439,7 +441,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
439
441
  const newAccessToken = ctx.body.jwt;
440
442
  const newRefreshToken = ctx.body.refreshToken;
441
443
  if (oldRefreshToken) {
442
- const allSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
444
+ const allSessions = await strapi2.documents(SESSION_UID$2).findMany({
443
445
  filters: {
444
446
  isActive: true
445
447
  }
@@ -456,14 +458,15 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
456
458
  if (matchingSession) {
457
459
  const encryptedToken = newAccessToken ? encryptToken$1(newAccessToken) : matchingSession.token;
458
460
  const encryptedRefreshToken = newRefreshToken ? encryptToken$1(newRefreshToken) : matchingSession.refreshToken;
459
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", matchingSession.id, {
461
+ await strapi2.documents(SESSION_UID$2).update({
462
+ documentId: matchingSession.documentId,
460
463
  data: {
461
464
  token: encryptedToken,
462
465
  refreshToken: encryptedRefreshToken,
463
466
  lastActive: /* @__PURE__ */ new Date()
464
467
  }
465
468
  });
466
- strapi2.log.info(`[magic-sessionmanager] 🔄 Tokens refreshed for session ${matchingSession.id}`);
469
+ strapi2.log.info(`[magic-sessionmanager] [REFRESH] Tokens refreshed for session ${matchingSession.documentId}`);
467
470
  }
468
471
  }
469
472
  } catch (err) {
@@ -471,15 +474,15 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
471
474
  }
472
475
  }
473
476
  });
474
- strapi2.log.info("[magic-sessionmanager] Refresh Token interceptor middleware mounted");
477
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Refresh Token interceptor middleware mounted");
475
478
  strapi2.server.use(
476
479
  lastSeen({ strapi: strapi2, sessionService })
477
480
  );
478
- strapi2.log.info("[magic-sessionmanager] LastSeen middleware mounted");
479
- strapi2.log.info("[magic-sessionmanager] Bootstrap complete");
480
- strapi2.log.info("[magic-sessionmanager] 🎉 Session Manager ready! Sessions stored in plugin::magic-sessionmanager.session");
481
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] LastSeen middleware mounted");
482
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Bootstrap complete");
483
+ strapi2.log.info("[magic-sessionmanager] [READY] Session Manager ready! Sessions stored in plugin::magic-sessionmanager.session");
481
484
  } catch (err) {
482
- strapi2.log.error("[magic-sessionmanager] Bootstrap error:", err);
485
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Bootstrap error:", err);
483
486
  }
484
487
  };
485
488
  var destroy$1 = async ({ strapi: strapi2 }) => {
@@ -491,7 +494,7 @@ var destroy$1 = async ({ strapi: strapi2 }) => {
491
494
  clearInterval(strapi2.sessionManagerIntervals.cleanup);
492
495
  strapi2.log.info("[magic-sessionmanager] 🛑 Session cleanup interval stopped");
493
496
  }
494
- strapi2.log.info("[magic-sessionmanager] Plugin cleanup completed");
497
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Plugin cleanup completed");
495
498
  };
496
499
  var config$1 = {
497
500
  default: {
@@ -799,6 +802,8 @@ var routes$1 = {
799
802
  "content-api": contentApi
800
803
  };
801
804
  const { decryptToken: decryptToken$1 } = encryption;
805
+ const SESSION_UID$1 = "plugin::magic-sessionmanager.session";
806
+ const USER_UID = "plugin::users-permissions.user";
802
807
  var session$3 = {
803
808
  /**
804
809
  * Get ALL sessions (active + inactive) - Admin only
@@ -877,9 +882,9 @@ var session$3 = {
877
882
  return ctx.throw(401, "Unauthorized");
878
883
  }
879
884
  const sessionService = strapi.plugin("magic-sessionmanager").service("session");
880
- const sessions = await strapi.entityService.findMany("plugin::magic-sessionmanager.session", {
885
+ const sessions = await strapi.documents(SESSION_UID$1).findMany({
881
886
  filters: {
882
- user: { id: userId },
887
+ user: { documentId: userId },
883
888
  isActive: true
884
889
  }
885
890
  });
@@ -893,8 +898,8 @@ var session$3 = {
893
898
  }
894
899
  });
895
900
  if (matchingSession) {
896
- await sessionService.terminateSession({ sessionId: matchingSession.id });
897
- strapi.log.info(`[magic-sessionmanager] User ${userId} logged out (session ${matchingSession.id})`);
901
+ await sessionService.terminateSession({ sessionId: matchingSession.documentId });
902
+ strapi.log.info(`[magic-sessionmanager] User ${userId} logged out (session ${matchingSession.documentId})`);
898
903
  }
899
904
  ctx.body = {
900
905
  message: "Logged out successfully"
@@ -1054,12 +1059,13 @@ var session$3 = {
1054
1059
  async toggleUserBlock(ctx) {
1055
1060
  try {
1056
1061
  const { userId } = ctx.params;
1057
- const user = await strapi.entityService.findOne("plugin::users-permissions.user", userId);
1062
+ const user = await strapi.documents(USER_UID).findOne({ documentId: userId });
1058
1063
  if (!user) {
1059
1064
  return ctx.throw(404, "User not found");
1060
1065
  }
1061
1066
  const newBlockedStatus = !user.blocked;
1062
- await strapi.entityService.update("plugin::users-permissions.user", userId, {
1067
+ await strapi.documents(USER_UID).update({
1068
+ documentId: userId,
1063
1069
  data: {
1064
1070
  blocked: newBlockedStatus
1065
1071
  }
@@ -1253,16 +1259,16 @@ var license$1 = ({ strapi: strapi2 }) => ({
1253
1259
  const licenseGuard2 = strapi2.plugin("magic-sessionmanager").service("license-guard");
1254
1260
  const verification = await licenseGuard2.verifyLicense(trimmedKey);
1255
1261
  if (!verification.valid) {
1256
- strapi2.log.warn(`[magic-sessionmanager] ⚠️ Invalid license key attempted: ${trimmedKey.substring(0, 8)}...`);
1262
+ strapi2.log.warn(`[magic-sessionmanager] [WARNING] Invalid license key attempted: ${trimmedKey.substring(0, 8)}...`);
1257
1263
  return ctx.badRequest("Invalid or expired license key");
1258
1264
  }
1259
1265
  const license2 = await licenseGuard2.getLicenseByKey(trimmedKey);
1260
1266
  if (!license2) {
1261
- strapi2.log.warn(`[magic-sessionmanager] ⚠️ License not found in database: ${trimmedKey.substring(0, 8)}...`);
1267
+ strapi2.log.warn(`[magic-sessionmanager] [WARNING] License not found in database: ${trimmedKey.substring(0, 8)}...`);
1262
1268
  return ctx.badRequest("License not found");
1263
1269
  }
1264
1270
  if (license2.email.toLowerCase() !== trimmedEmail) {
1265
- strapi2.log.warn(`[magic-sessionmanager] ⚠️ Email mismatch for license key: ${trimmedKey.substring(0, 8)}... (Attempted: ${trimmedEmail})`);
1271
+ strapi2.log.warn(`[magic-sessionmanager] [WARNING] Email mismatch for license key: ${trimmedKey.substring(0, 8)}... (Attempted: ${trimmedEmail})`);
1266
1272
  return ctx.badRequest("Email address does not match this license key");
1267
1273
  }
1268
1274
  await licenseGuard2.storeLicenseKey(trimmedKey);
@@ -1272,7 +1278,7 @@ var license$1 = ({ strapi: strapi2 }) => ({
1272
1278
  pingInterval,
1273
1279
  data: verification.data
1274
1280
  };
1275
- strapi2.log.info(`[magic-sessionmanager] Existing license key validated and stored: ${trimmedKey.substring(0, 8)}... (Email: ${trimmedEmail})`);
1281
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Existing license key validated and stored: ${trimmedKey.substring(0, 8)}... (Email: ${trimmedEmail})`);
1276
1282
  return ctx.send({
1277
1283
  success: true,
1278
1284
  message: "License key validated and activated successfully",
@@ -1394,6 +1400,7 @@ var controllers$1 = {
1394
1400
  settings
1395
1401
  };
1396
1402
  const { encryptToken, decryptToken, generateSessionId } = encryption;
1403
+ const SESSION_UID = "plugin::magic-sessionmanager.session";
1397
1404
  var session$1 = ({ strapi: strapi2 }) => ({
1398
1405
  /**
1399
1406
  * Create a new session record
@@ -1406,23 +1413,24 @@ var session$1 = ({ strapi: strapi2 }) => ({
1406
1413
  const sessionId = generateSessionId(userId);
1407
1414
  const encryptedToken = token ? encryptToken(token) : null;
1408
1415
  const encryptedRefreshToken = refreshToken ? encryptToken(refreshToken) : null;
1409
- const session2 = await strapi2.entityService.create("plugin::magic-sessionmanager.session", {
1416
+ const session2 = await strapi2.documents(SESSION_UID).create({
1410
1417
  data: {
1411
1418
  user: userId,
1419
+ // userId should be documentId (string)
1412
1420
  ipAddress: ip.substring(0, 45),
1413
1421
  userAgent: userAgent.substring(0, 500),
1414
1422
  loginTime: now,
1415
1423
  lastActive: now,
1416
1424
  isActive: true,
1417
1425
  token: encryptedToken,
1418
- // Encrypted Access Token
1426
+ // [SUCCESS] Encrypted Access Token
1419
1427
  refreshToken: encryptedRefreshToken,
1420
- // Encrypted Refresh Token
1428
+ // [SUCCESS] Encrypted Refresh Token
1421
1429
  sessionId
1422
- // Unique identifier
1430
+ // [SUCCESS] Unique identifier
1423
1431
  }
1424
1432
  });
1425
- strapi2.log.info(`[magic-sessionmanager] Session ${session2.id} (${sessionId}) created for user ${userId}`);
1433
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Session ${session2.documentId} (${sessionId}) created for user ${userId}`);
1426
1434
  return session2;
1427
1435
  } catch (err) {
1428
1436
  strapi2.log.error("[magic-sessionmanager] Error creating session:", err);
@@ -1438,7 +1446,8 @@ var session$1 = ({ strapi: strapi2 }) => ({
1438
1446
  try {
1439
1447
  const now = /* @__PURE__ */ new Date();
1440
1448
  if (sessionId) {
1441
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", sessionId, {
1449
+ await strapi2.documents(SESSION_UID).update({
1450
+ documentId: sessionId,
1442
1451
  data: {
1443
1452
  isActive: false,
1444
1453
  logoutTime: now
@@ -1446,14 +1455,16 @@ var session$1 = ({ strapi: strapi2 }) => ({
1446
1455
  });
1447
1456
  strapi2.log.info(`[magic-sessionmanager] Session ${sessionId} terminated`);
1448
1457
  } else if (userId) {
1449
- const activeSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1458
+ const activeSessions = await strapi2.documents(SESSION_UID).findMany({
1450
1459
  filters: {
1451
- user: { id: userId },
1460
+ user: { documentId: userId },
1461
+ // Deep filtering syntax
1452
1462
  isActive: true
1453
1463
  }
1454
1464
  });
1455
1465
  for (const session2 of activeSessions) {
1456
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", session2.id, {
1466
+ await strapi2.documents(SESSION_UID).update({
1467
+ documentId: session2.documentId,
1457
1468
  data: {
1458
1469
  isActive: false,
1459
1470
  logoutTime: now
@@ -1473,7 +1484,7 @@ var session$1 = ({ strapi: strapi2 }) => ({
1473
1484
  */
1474
1485
  async getAllSessions() {
1475
1486
  try {
1476
- const sessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1487
+ const sessions = await strapi2.documents(SESSION_UID).findMany({
1477
1488
  populate: { user: { fields: ["id", "email", "username"] } },
1478
1489
  sort: { loginTime: "desc" },
1479
1490
  limit: 1e3
@@ -1505,7 +1516,7 @@ var session$1 = ({ strapi: strapi2 }) => ({
1505
1516
  */
1506
1517
  async getActiveSessions() {
1507
1518
  try {
1508
- const sessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1519
+ const sessions = await strapi2.documents(SESSION_UID).findMany({
1509
1520
  filters: { isActive: true },
1510
1521
  populate: { user: { fields: ["id", "email", "username"] } },
1511
1522
  sort: { loginTime: "desc" }
@@ -1537,8 +1548,8 @@ var session$1 = ({ strapi: strapi2 }) => ({
1537
1548
  */
1538
1549
  async getUserSessions(userId) {
1539
1550
  try {
1540
- const sessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1541
- filters: { user: { id: userId } },
1551
+ const sessions = await strapi2.documents(SESSION_UID).findMany({
1552
+ filters: { user: { documentId: userId } },
1542
1553
  sort: { loginTime: "desc" }
1543
1554
  });
1544
1555
  const config2 = strapi2.config.get("plugin::magic-sessionmanager") || {};
@@ -1572,17 +1583,19 @@ var session$1 = ({ strapi: strapi2 }) => ({
1572
1583
  const config2 = strapi2.config.get("plugin::magic-sessionmanager") || {};
1573
1584
  const rateLimit = config2.lastSeenRateLimit || 3e4;
1574
1585
  if (sessionId) {
1575
- const session2 = await strapi2.entityService.findOne("plugin::magic-sessionmanager.session", sessionId);
1586
+ const session2 = await strapi2.documents(SESSION_UID).findOne({ documentId: sessionId });
1576
1587
  if (session2 && session2.lastActive) {
1577
1588
  const lastActiveTime = new Date(session2.lastActive).getTime();
1578
1589
  const currentTime = now.getTime();
1579
1590
  if (currentTime - lastActiveTime > rateLimit) {
1580
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", sessionId, {
1591
+ await strapi2.documents(SESSION_UID).update({
1592
+ documentId: sessionId,
1581
1593
  data: { lastActive: now }
1582
1594
  });
1583
1595
  }
1584
1596
  } else if (session2) {
1585
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", sessionId, {
1597
+ await strapi2.documents(SESSION_UID).update({
1598
+ documentId: sessionId,
1586
1599
  data: { lastActive: now }
1587
1600
  });
1588
1601
  }
@@ -1601,22 +1614,23 @@ var session$1 = ({ strapi: strapi2 }) => ({
1601
1614
  const inactivityTimeout = config2.inactivityTimeout || 15 * 60 * 1e3;
1602
1615
  const now = /* @__PURE__ */ new Date();
1603
1616
  const cutoffTime = new Date(now.getTime() - inactivityTimeout);
1604
- strapi2.log.info(`[magic-sessionmanager] 🧹 Cleaning up sessions inactive since before ${cutoffTime.toISOString()}`);
1605
- const activeSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1617
+ strapi2.log.info(`[magic-sessionmanager] [CLEANUP] Cleaning up sessions inactive since before ${cutoffTime.toISOString()}`);
1618
+ const activeSessions = await strapi2.documents(SESSION_UID).findMany({
1606
1619
  filters: { isActive: true },
1607
- fields: ["id", "lastActive", "loginTime"]
1620
+ fields: ["lastActive", "loginTime"]
1608
1621
  });
1609
1622
  let deactivatedCount = 0;
1610
1623
  for (const session2 of activeSessions) {
1611
1624
  const lastActiveTime = session2.lastActive ? new Date(session2.lastActive) : new Date(session2.loginTime);
1612
1625
  if (lastActiveTime < cutoffTime) {
1613
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", session2.id, {
1626
+ await strapi2.documents(SESSION_UID).update({
1627
+ documentId: session2.documentId,
1614
1628
  data: { isActive: false }
1615
1629
  });
1616
1630
  deactivatedCount++;
1617
1631
  }
1618
1632
  }
1619
- strapi2.log.info(`[magic-sessionmanager] Cleanup complete: ${deactivatedCount} sessions deactivated`);
1633
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Cleanup complete: ${deactivatedCount} sessions deactivated`);
1620
1634
  return deactivatedCount;
1621
1635
  } catch (err) {
1622
1636
  strapi2.log.error("[magic-sessionmanager] Error cleaning up inactive sessions:", err);
@@ -1631,8 +1645,8 @@ var session$1 = ({ strapi: strapi2 }) => ({
1631
1645
  */
1632
1646
  async deleteSession(sessionId) {
1633
1647
  try {
1634
- await strapi2.entityService.delete("plugin::magic-sessionmanager.session", sessionId);
1635
- strapi2.log.info(`[magic-sessionmanager] 🗑️ Session ${sessionId} permanently deleted`);
1648
+ await strapi2.documents(SESSION_UID).delete({ documentId: sessionId });
1649
+ strapi2.log.info(`[magic-sessionmanager] [DELETE] Session ${sessionId} permanently deleted`);
1636
1650
  return true;
1637
1651
  } catch (err) {
1638
1652
  strapi2.log.error("[magic-sessionmanager] Error deleting session:", err);
@@ -1646,17 +1660,16 @@ var session$1 = ({ strapi: strapi2 }) => ({
1646
1660
  */
1647
1661
  async deleteInactiveSessions() {
1648
1662
  try {
1649
- strapi2.log.info("[magic-sessionmanager] 🗑️ Deleting all inactive sessions...");
1650
- const inactiveSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1651
- filters: { isActive: false },
1652
- fields: ["id"]
1663
+ strapi2.log.info("[magic-sessionmanager] [DELETE] Deleting all inactive sessions...");
1664
+ const inactiveSessions = await strapi2.documents(SESSION_UID).findMany({
1665
+ filters: { isActive: false }
1653
1666
  });
1654
1667
  let deletedCount = 0;
1655
1668
  for (const session2 of inactiveSessions) {
1656
- await strapi2.entityService.delete("plugin::magic-sessionmanager.session", session2.id);
1669
+ await strapi2.documents(SESSION_UID).delete({ documentId: session2.documentId });
1657
1670
  deletedCount++;
1658
1671
  }
1659
- strapi2.log.info(`[magic-sessionmanager] Deleted ${deletedCount} inactive sessions`);
1672
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Deleted ${deletedCount} inactive sessions`);
1660
1673
  return deletedCount;
1661
1674
  } catch (err) {
1662
1675
  strapi2.log.error("[magic-sessionmanager] Error deleting inactive sessions:", err);
@@ -1664,8 +1677,13 @@ var session$1 = ({ strapi: strapi2 }) => ({
1664
1677
  }
1665
1678
  }
1666
1679
  });
1680
+ const version = "3.7.0";
1681
+ const require$$2 = {
1682
+ version
1683
+ };
1667
1684
  const crypto = require$$0$1;
1668
1685
  const os = require$$1;
1686
+ const pluginPkg = require$$2;
1669
1687
  const LICENSE_SERVER_URL = "https://magicapi.fitlex.me";
1670
1688
  var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1671
1689
  /**
@@ -1720,7 +1738,9 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1720
1738
  }
1721
1739
  },
1722
1740
  getUserAgent() {
1723
- return `Strapi/${strapi2.config.get("info.strapi") || "5.0.0"} Node/${process.version} ${os.platform()}/${os.release()}`;
1741
+ const pluginVersion = pluginPkg.version;
1742
+ const strapiVersion = strapi2.config.get("info.strapi") || "5.0.0";
1743
+ return `MagicSessionManager/${pluginVersion} Strapi/${strapiVersion} Node/${process.version} ${os.platform()}/${os.release()}`;
1724
1744
  },
1725
1745
  async createLicense({ email, firstName, lastName }) {
1726
1746
  try {
@@ -1746,14 +1766,14 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1746
1766
  });
1747
1767
  const data = await response.json();
1748
1768
  if (data.success) {
1749
- strapi2.log.info("[magic-sessionmanager] License created:", data.data.licenseKey);
1769
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] License created:", data.data.licenseKey);
1750
1770
  return data.data;
1751
1771
  } else {
1752
- strapi2.log.error("[magic-sessionmanager] License creation failed:", data);
1772
+ strapi2.log.error("[magic-sessionmanager] [ERROR] License creation failed:", data);
1753
1773
  return null;
1754
1774
  }
1755
1775
  } catch (error) {
1756
- strapi2.log.error("[magic-sessionmanager] Error creating license:", error);
1776
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Error creating license:", error);
1757
1777
  return null;
1758
1778
  }
1759
1779
  },
@@ -1838,10 +1858,10 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1838
1858
  name: "magic-sessionmanager"
1839
1859
  });
1840
1860
  await pluginStore.set({ key: "licenseKey", value: licenseKey });
1841
- strapi2.log.info(`[magic-sessionmanager] License key stored: ${licenseKey.substring(0, 8)}...`);
1861
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] License key stored: ${licenseKey.substring(0, 8)}...`);
1842
1862
  },
1843
1863
  startPinging(licenseKey, intervalMinutes = 15) {
1844
- strapi2.log.info(`[magic-sessionmanager] Starting license pings every ${intervalMinutes} minutes`);
1864
+ strapi2.log.info(`[magic-sessionmanager] [TIME] Starting license pings every ${intervalMinutes} minutes`);
1845
1865
  this.pingLicense(licenseKey);
1846
1866
  const interval = setInterval(async () => {
1847
1867
  try {
@@ -1858,14 +1878,14 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1858
1878
  */
1859
1879
  async initialize() {
1860
1880
  try {
1861
- strapi2.log.info("[magic-sessionmanager] 🔐 Initializing License Guard...");
1881
+ strapi2.log.info("[magic-sessionmanager] [SECURE] Initializing License Guard...");
1862
1882
  const pluginStore = strapi2.store({
1863
1883
  type: "plugin",
1864
1884
  name: "magic-sessionmanager"
1865
1885
  });
1866
1886
  const licenseKey = await pluginStore.get({ key: "licenseKey" });
1867
1887
  if (!licenseKey) {
1868
- strapi2.log.info("[magic-sessionmanager] ℹ️ No license found - Running in demo mode");
1888
+ strapi2.log.info("[magic-sessionmanager] [INFO] No license found - Running in demo mode");
1869
1889
  return {
1870
1890
  valid: false,
1871
1891
  demo: true,
@@ -1900,7 +1920,7 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1900
1920
  gracePeriod: verification.gracePeriod || false
1901
1921
  };
1902
1922
  } else {
1903
- strapi2.log.error("[magic-sessionmanager] License validation failed");
1923
+ strapi2.log.error("[magic-sessionmanager] [ERROR] License validation failed");
1904
1924
  return {
1905
1925
  valid: false,
1906
1926
  demo: true,
@@ -1909,7 +1929,7 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1909
1929
  };
1910
1930
  }
1911
1931
  } catch (error) {
1912
- strapi2.log.error("[magic-sessionmanager] Error initializing License Guard:", error);
1932
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Error initializing License Guard:", error);
1913
1933
  return {
1914
1934
  valid: false,
1915
1935
  demo: true,
@@ -2022,9 +2042,11 @@ var geolocation$1 = ({ strapi: strapi2 }) => ({
2022
2042
  },
2023
2043
  /**
2024
2044
  * Get country flag emoji
2045
+ * @param {string} countryCode - ISO 2-letter country code
2046
+ * @returns {string} Flag emoji or empty string
2025
2047
  */
2026
2048
  getCountryFlag(countryCode) {
2027
- if (!countryCode) return "🏳️";
2049
+ if (!countryCode) return "";
2028
2050
  const codePoints = countryCode.toUpperCase().split("").map((char) => 127397 + char.charCodeAt());
2029
2051
  return String.fromCodePoint(...codePoints);
2030
2052
  },
@@ -2036,7 +2058,7 @@ var geolocation$1 = ({ strapi: strapi2 }) => ({
2036
2058
  ip: ipAddress,
2037
2059
  country: "Unknown",
2038
2060
  country_code: "XX",
2039
- country_flag: "🌍",
2061
+ country_flag: "[GEO]",
2040
2062
  city: "Unknown",
2041
2063
  region: "Unknown",
2042
2064
  timezone: "Unknown",
@@ -2141,9 +2163,9 @@ Login Details:
2141
2163
  Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThreat}}, Score={{reason.securityScore}}/100`
2142
2164
  },
2143
2165
  newLocation: {
2144
- subject: "📍 New Location Login Detected",
2145
- 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>`,
2146
- text: `📍 New Location Login
2166
+ subject: "[LOCATION] New Location Login Detected",
2167
+ 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>`,
2168
+ text: `[LOCATION] New Location Login
2147
2169
 
2148
2170
  Account: {{user.email}}
2149
2171
  Time: {{session.loginTime}}
@@ -2151,9 +2173,9 @@ Location: {{geo.city}}, {{geo.country}}
2151
2173
  IP: {{session.ipAddress}}`
2152
2174
  },
2153
2175
  vpnProxy: {
2154
- subject: "⚠️ VPN/Proxy Login Detected",
2155
- 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>`,
2156
- text: `⚠️ VPN/Proxy Detected
2176
+ subject: "[WARNING] VPN/Proxy Login Detected",
2177
+ 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>`,
2178
+ text: `[WARNING] VPN/Proxy Detected
2157
2179
 
2158
2180
  Account: {{user.email}}
2159
2181
  Time: {{session.loginTime}}
@@ -2307,7 +2329,7 @@ ${user.username || "N/A"}`, inline: true },
2307
2329
  };
2308
2330
  if (geoData) {
2309
2331
  embed.fields.push({
2310
- name: "📍 Location",
2332
+ name: "[LOCATION] Location",
2311
2333
  value: `${geoData.country_flag} ${geoData.city}, ${geoData.country}`,
2312
2334
  inline: true
2313
2335
  });
@@ -2317,7 +2339,7 @@ ${user.username || "N/A"}`, inline: true },
2317
2339
  if (geoData.isProxy) warnings.push("Proxy");
2318
2340
  if (geoData.isThreat) warnings.push("Threat");
2319
2341
  embed.fields.push({
2320
- name: "⚠️ Security",
2342
+ name: "[WARNING] Security",
2321
2343
  value: `${warnings.join(", ")} detected
2322
2344
  Score: ${geoData.securityScore}/100`,
2323
2345
  inline: true
@@ -2329,12 +2351,12 @@ Score: ${geoData.securityScore}/100`,
2329
2351
  getEventTitle(event) {
2330
2352
  const titles = {
2331
2353
  "login.suspicious": "🚨 Suspicious Login",
2332
- "login.new_location": "📍 New Location Login",
2354
+ "login.new_location": "[LOCATION] New Location Login",
2333
2355
  "login.vpn": "🔴 VPN Login Detected",
2334
2356
  "login.threat": "⛔ Threat IP Login",
2335
2357
  "session.terminated": "🔴 Session Terminated"
2336
2358
  };
2337
- return titles[event] || "📊 Session Event";
2359
+ return titles[event] || "[STATS] Session Event";
2338
2360
  },
2339
2361
  getEventColor(event) {
2340
2362
  const colors = {