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
@@ -8,7 +8,7 @@ function getDefaultExportFromCjs(x) {
8
8
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
9
9
  }
10
10
  var register$1 = async ({ strapi: strapi2 }) => {
11
- strapi2.log.info("[magic-sessionmanager] 🚀 Plugin registration starting...");
11
+ strapi2.log.info("[magic-sessionmanager] [START] Plugin registration starting...");
12
12
  try {
13
13
  const userCT = strapi2.contentType("plugin::users-permissions.user");
14
14
  if (!userCT) {
@@ -17,11 +17,11 @@ var register$1 = async ({ strapi: strapi2 }) => {
17
17
  }
18
18
  if (userCT.attributes && userCT.attributes.sessions) {
19
19
  delete userCT.attributes.sessions;
20
- strapi2.log.info("[magic-sessionmanager] Removed sessions field from User content type");
20
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Removed sessions field from User content type");
21
21
  }
22
- strapi2.log.info("[magic-sessionmanager] Plugin registered successfully");
22
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Plugin registered successfully");
23
23
  } catch (err) {
24
- strapi2.log.error("[magic-sessionmanager] Registration error:", err);
24
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Registration error:", err);
25
25
  }
26
26
  };
27
27
  const getClientIp$1 = (ctx) => {
@@ -98,7 +98,7 @@ function getEncryptionKey() {
98
98
  }
99
99
  const strapiKeys = process.env.APP_KEYS || process.env.API_TOKEN_SALT || "default-insecure-key";
100
100
  const key = crypto$1.createHash("sha256").update(strapiKeys).digest();
101
- console.warn("[magic-sessionmanager/encryption] ⚠️ No SESSION_ENCRYPTION_KEY found. Using fallback (not recommended for production).");
101
+ console.warn("[magic-sessionmanager/encryption] [WARNING] No SESSION_ENCRYPTION_KEY found. Using fallback (not recommended for production).");
102
102
  console.warn("[magic-sessionmanager/encryption] Set SESSION_ENCRYPTION_KEY in .env for better security.");
103
103
  return key;
104
104
  }
@@ -149,20 +149,21 @@ var encryption = {
149
149
  decryptToken: decryptToken$3,
150
150
  generateSessionId: generateSessionId$1
151
151
  };
152
+ const SESSION_UID$3 = "plugin::magic-sessionmanager.session";
152
153
  var lastSeen = ({ strapi: strapi2, sessionService }) => {
153
154
  return async (ctx, next) => {
154
155
  if (ctx.state.user && ctx.state.user.id) {
155
156
  try {
156
157
  const userId = ctx.state.user.id;
157
- const activeSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
158
+ const activeSessions = await strapi2.documents(SESSION_UID$3).findMany({
158
159
  filters: {
159
- user: { id: userId },
160
+ user: { documentId: userId },
160
161
  isActive: true
161
162
  },
162
163
  limit: 1
163
164
  });
164
165
  if (!activeSessions || activeSessions.length === 0) {
165
- strapi2.log.info(`[magic-sessionmanager] 🚫 Blocked request - User ${userId} has no active sessions`);
166
+ strapi2.log.info(`[magic-sessionmanager] [BLOCKED] Blocked request - User ${userId} has no active sessions`);
166
167
  return ctx.unauthorized("All sessions have been terminated. Please login again.");
167
168
  }
168
169
  } catch (err) {
@@ -186,15 +187,16 @@ var lastSeen = ({ strapi: strapi2, sessionService }) => {
186
187
  };
187
188
  const getClientIp = getClientIp_1;
188
189
  const { encryptToken: encryptToken$1, decryptToken: decryptToken$2 } = encryption;
190
+ const SESSION_UID$2 = "plugin::magic-sessionmanager.session";
189
191
  var bootstrap$1 = async ({ strapi: strapi2 }) => {
190
- strapi2.log.info("[magic-sessionmanager] 🚀 Bootstrap starting...");
192
+ strapi2.log.info("[magic-sessionmanager] [START] Bootstrap starting...");
191
193
  try {
192
194
  const licenseGuardService = strapi2.plugin("magic-sessionmanager").service("license-guard");
193
195
  setTimeout(async () => {
194
196
  const licenseStatus = await licenseGuardService.initialize();
195
197
  if (!licenseStatus.valid) {
196
198
  strapi2.log.error("╔════════════════════════════════════════════════════════════════╗");
197
- strapi2.log.error("║ SESSION MANAGER - NO VALID LICENSE ║");
199
+ strapi2.log.error("║ [ERROR] SESSION MANAGER - NO VALID LICENSE ║");
198
200
  strapi2.log.error("║ ║");
199
201
  strapi2.log.error("║ This plugin requires a valid license to operate. ║");
200
202
  strapi2.log.error("║ Please activate your license via Admin UI: ║");
@@ -210,7 +212,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
210
212
  });
211
213
  const storedKey = await pluginStore.get({ key: "licenseKey" });
212
214
  strapi2.log.info("╔════════════════════════════════════════════════════════════════╗");
213
- strapi2.log.info("║ SESSION MANAGER LICENSE ACTIVE ║");
215
+ strapi2.log.info("║ [SUCCESS] SESSION MANAGER LICENSE ACTIVE ║");
214
216
  strapi2.log.info("║ ║");
215
217
  if (licenseStatus.data) {
216
218
  strapi2.log.info(`║ License: ${licenseStatus.data.licenseKey}`.padEnd(66) + "║");
@@ -221,7 +223,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
221
223
  strapi2.log.info(`║ Status: Grace Period Active`.padEnd(66) + "║");
222
224
  }
223
225
  strapi2.log.info("║ ║");
224
- strapi2.log.info("║ 🔄 Auto-pinging every 15 minutes ║");
226
+ strapi2.log.info("║ [RELOAD] Auto-pinging every 15 minutes ║");
225
227
  strapi2.log.info("╚════════════════════════════════════════════════════════════════╝");
226
228
  }
227
229
  }, 3e3);
@@ -237,7 +239,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
237
239
  strapi2.log.error("[magic-sessionmanager] Periodic cleanup error:", err);
238
240
  }
239
241
  }, cleanupInterval);
240
- strapi2.log.info("[magic-sessionmanager] Periodic cleanup scheduled (every 30 minutes)");
242
+ strapi2.log.info("[magic-sessionmanager] [TIME] Periodic cleanup scheduled (every 30 minutes)");
241
243
  if (!strapi2.sessionManagerIntervals) {
242
244
  strapi2.sessionManagerIntervals = {};
243
245
  }
@@ -253,7 +255,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
253
255
  ctx.body = { message: "Logged out successfully" };
254
256
  return;
255
257
  }
256
- const allSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
258
+ const allSessions = await strapi2.documents(SESSION_UID$2).findMany({
257
259
  filters: {
258
260
  isActive: true
259
261
  }
@@ -268,8 +270,8 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
268
270
  }
269
271
  });
270
272
  if (matchingSession) {
271
- await sessionService.terminateSession({ sessionId: matchingSession.id });
272
- strapi2.log.info(`[magic-sessionmanager] 🚪 Logout via /api/auth/logout - Session ${matchingSession.id} terminated`);
273
+ await sessionService.terminateSession({ sessionId: matchingSession.documentId });
274
+ strapi2.log.info(`[magic-sessionmanager] [LOGOUT] Logout via /api/auth/logout - Session ${matchingSession.documentId} terminated`);
273
275
  }
274
276
  ctx.status = 200;
275
277
  ctx.body = { message: "Logged out successfully" };
@@ -283,7 +285,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
283
285
  auth: false
284
286
  }
285
287
  }]);
286
- strapi2.log.info("[magic-sessionmanager] /api/auth/logout route registered");
288
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] /api/auth/logout route registered");
287
289
  strapi2.server.use(async (ctx, next) => {
288
290
  await next();
289
291
  const isAuthLocal = ctx.path === "/api/auth/local" && ctx.method === "POST";
@@ -293,7 +295,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
293
295
  const user = ctx.body.user;
294
296
  const ip = getClientIp(ctx);
295
297
  const userAgent = ctx.request.headers?.["user-agent"] || ctx.request.header?.["user-agent"] || "unknown";
296
- strapi2.log.info(`[magic-sessionmanager] 🔍 Login detected! User: ${user.id} (${user.email || user.username}) from IP: ${ip}`);
298
+ strapi2.log.info(`[magic-sessionmanager] [CHECK] Login detected! User: ${user.id} (${user.email || user.username}) from IP: ${ip}`);
297
299
  const config2 = strapi2.config.get("plugin::magic-sessionmanager") || {};
298
300
  let shouldBlock = false;
299
301
  let blockReason = "";
@@ -335,7 +337,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
335
337
  }
336
338
  }
337
339
  if (shouldBlock) {
338
- strapi2.log.warn(`[magic-sessionmanager] 🚫 Blocking login: ${blockReason}`);
340
+ strapi2.log.warn(`[magic-sessionmanager] [BLOCKED] Blocking login: ${blockReason}`);
339
341
  ctx.status = 403;
340
342
  ctx.body = {
341
343
  error: {
@@ -355,7 +357,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
355
357
  refreshToken: ctx.body.refreshToken
356
358
  // Store Refresh Token (encrypted) if exists
357
359
  });
358
- strapi2.log.info(`[magic-sessionmanager] Session created for user ${user.id} (IP: ${ip})`);
360
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Session created for user ${user.id} (IP: ${ip})`);
359
361
  if (geoData && (config2.enableEmailAlerts || config2.enableWebhooks)) {
360
362
  try {
361
363
  const notificationService = strapi2.plugin("magic-sessionmanager").service("notifications");
@@ -393,18 +395,18 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
393
395
  }
394
396
  }
395
397
  } catch (err) {
396
- strapi2.log.error("[magic-sessionmanager] Error creating session:", err);
398
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Error creating session:", err);
397
399
  }
398
400
  }
399
401
  });
400
- strapi2.log.info("[magic-sessionmanager] Login/Logout interceptor middleware mounted");
402
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Login/Logout interceptor middleware mounted");
401
403
  strapi2.server.use(async (ctx, next) => {
402
404
  const isRefreshToken = ctx.path === "/api/auth/refresh" && ctx.method === "POST";
403
405
  if (isRefreshToken) {
404
406
  try {
405
407
  const refreshToken = ctx.request.body?.refreshToken;
406
408
  if (refreshToken) {
407
- const allSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
409
+ const allSessions = await strapi2.documents(SESSION_UID$2).findMany({
408
410
  filters: {
409
411
  isActive: true
410
412
  }
@@ -419,7 +421,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
419
421
  }
420
422
  });
421
423
  if (!matchingSession) {
422
- strapi2.log.warn("[magic-sessionmanager] 🚫 Blocked refresh token request - no active session");
424
+ strapi2.log.warn("[magic-sessionmanager] [BLOCKED] Blocked refresh token request - no active session");
423
425
  ctx.status = 401;
424
426
  ctx.body = {
425
427
  error: {
@@ -430,7 +432,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
430
432
  };
431
433
  return;
432
434
  }
433
- strapi2.log.info(`[magic-sessionmanager] Refresh token allowed for session ${matchingSession.id}`);
435
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Refresh token allowed for session ${matchingSession.documentId}`);
434
436
  }
435
437
  } catch (err) {
436
438
  strapi2.log.error("[magic-sessionmanager] Error checking refresh token:", err);
@@ -443,7 +445,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
443
445
  const newAccessToken = ctx.body.jwt;
444
446
  const newRefreshToken = ctx.body.refreshToken;
445
447
  if (oldRefreshToken) {
446
- const allSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
448
+ const allSessions = await strapi2.documents(SESSION_UID$2).findMany({
447
449
  filters: {
448
450
  isActive: true
449
451
  }
@@ -460,14 +462,15 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
460
462
  if (matchingSession) {
461
463
  const encryptedToken = newAccessToken ? encryptToken$1(newAccessToken) : matchingSession.token;
462
464
  const encryptedRefreshToken = newRefreshToken ? encryptToken$1(newRefreshToken) : matchingSession.refreshToken;
463
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", matchingSession.id, {
465
+ await strapi2.documents(SESSION_UID$2).update({
466
+ documentId: matchingSession.documentId,
464
467
  data: {
465
468
  token: encryptedToken,
466
469
  refreshToken: encryptedRefreshToken,
467
470
  lastActive: /* @__PURE__ */ new Date()
468
471
  }
469
472
  });
470
- strapi2.log.info(`[magic-sessionmanager] 🔄 Tokens refreshed for session ${matchingSession.id}`);
473
+ strapi2.log.info(`[magic-sessionmanager] [REFRESH] Tokens refreshed for session ${matchingSession.documentId}`);
471
474
  }
472
475
  }
473
476
  } catch (err) {
@@ -475,15 +478,15 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
475
478
  }
476
479
  }
477
480
  });
478
- strapi2.log.info("[magic-sessionmanager] Refresh Token interceptor middleware mounted");
481
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Refresh Token interceptor middleware mounted");
479
482
  strapi2.server.use(
480
483
  lastSeen({ strapi: strapi2, sessionService })
481
484
  );
482
- strapi2.log.info("[magic-sessionmanager] LastSeen middleware mounted");
483
- strapi2.log.info("[magic-sessionmanager] Bootstrap complete");
484
- strapi2.log.info("[magic-sessionmanager] 🎉 Session Manager ready! Sessions stored in plugin::magic-sessionmanager.session");
485
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] LastSeen middleware mounted");
486
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Bootstrap complete");
487
+ strapi2.log.info("[magic-sessionmanager] [READY] Session Manager ready! Sessions stored in plugin::magic-sessionmanager.session");
485
488
  } catch (err) {
486
- strapi2.log.error("[magic-sessionmanager] Bootstrap error:", err);
489
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Bootstrap error:", err);
487
490
  }
488
491
  };
489
492
  var destroy$1 = async ({ strapi: strapi2 }) => {
@@ -495,7 +498,7 @@ var destroy$1 = async ({ strapi: strapi2 }) => {
495
498
  clearInterval(strapi2.sessionManagerIntervals.cleanup);
496
499
  strapi2.log.info("[magic-sessionmanager] 🛑 Session cleanup interval stopped");
497
500
  }
498
- strapi2.log.info("[magic-sessionmanager] Plugin cleanup completed");
501
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] Plugin cleanup completed");
499
502
  };
500
503
  var config$1 = {
501
504
  default: {
@@ -803,6 +806,8 @@ var routes$1 = {
803
806
  "content-api": contentApi
804
807
  };
805
808
  const { decryptToken: decryptToken$1 } = encryption;
809
+ const SESSION_UID$1 = "plugin::magic-sessionmanager.session";
810
+ const USER_UID = "plugin::users-permissions.user";
806
811
  var session$3 = {
807
812
  /**
808
813
  * Get ALL sessions (active + inactive) - Admin only
@@ -881,9 +886,9 @@ var session$3 = {
881
886
  return ctx.throw(401, "Unauthorized");
882
887
  }
883
888
  const sessionService = strapi.plugin("magic-sessionmanager").service("session");
884
- const sessions = await strapi.entityService.findMany("plugin::magic-sessionmanager.session", {
889
+ const sessions = await strapi.documents(SESSION_UID$1).findMany({
885
890
  filters: {
886
- user: { id: userId },
891
+ user: { documentId: userId },
887
892
  isActive: true
888
893
  }
889
894
  });
@@ -897,8 +902,8 @@ var session$3 = {
897
902
  }
898
903
  });
899
904
  if (matchingSession) {
900
- await sessionService.terminateSession({ sessionId: matchingSession.id });
901
- strapi.log.info(`[magic-sessionmanager] User ${userId} logged out (session ${matchingSession.id})`);
905
+ await sessionService.terminateSession({ sessionId: matchingSession.documentId });
906
+ strapi.log.info(`[magic-sessionmanager] User ${userId} logged out (session ${matchingSession.documentId})`);
902
907
  }
903
908
  ctx.body = {
904
909
  message: "Logged out successfully"
@@ -1058,12 +1063,13 @@ var session$3 = {
1058
1063
  async toggleUserBlock(ctx) {
1059
1064
  try {
1060
1065
  const { userId } = ctx.params;
1061
- const user = await strapi.entityService.findOne("plugin::users-permissions.user", userId);
1066
+ const user = await strapi.documents(USER_UID).findOne({ documentId: userId });
1062
1067
  if (!user) {
1063
1068
  return ctx.throw(404, "User not found");
1064
1069
  }
1065
1070
  const newBlockedStatus = !user.blocked;
1066
- await strapi.entityService.update("plugin::users-permissions.user", userId, {
1071
+ await strapi.documents(USER_UID).update({
1072
+ documentId: userId,
1067
1073
  data: {
1068
1074
  blocked: newBlockedStatus
1069
1075
  }
@@ -1257,16 +1263,16 @@ var license$1 = ({ strapi: strapi2 }) => ({
1257
1263
  const licenseGuard2 = strapi2.plugin("magic-sessionmanager").service("license-guard");
1258
1264
  const verification = await licenseGuard2.verifyLicense(trimmedKey);
1259
1265
  if (!verification.valid) {
1260
- strapi2.log.warn(`[magic-sessionmanager] ⚠️ Invalid license key attempted: ${trimmedKey.substring(0, 8)}...`);
1266
+ strapi2.log.warn(`[magic-sessionmanager] [WARNING] Invalid license key attempted: ${trimmedKey.substring(0, 8)}...`);
1261
1267
  return ctx.badRequest("Invalid or expired license key");
1262
1268
  }
1263
1269
  const license2 = await licenseGuard2.getLicenseByKey(trimmedKey);
1264
1270
  if (!license2) {
1265
- strapi2.log.warn(`[magic-sessionmanager] ⚠️ License not found in database: ${trimmedKey.substring(0, 8)}...`);
1271
+ strapi2.log.warn(`[magic-sessionmanager] [WARNING] License not found in database: ${trimmedKey.substring(0, 8)}...`);
1266
1272
  return ctx.badRequest("License not found");
1267
1273
  }
1268
1274
  if (license2.email.toLowerCase() !== trimmedEmail) {
1269
- strapi2.log.warn(`[magic-sessionmanager] ⚠️ Email mismatch for license key: ${trimmedKey.substring(0, 8)}... (Attempted: ${trimmedEmail})`);
1275
+ strapi2.log.warn(`[magic-sessionmanager] [WARNING] Email mismatch for license key: ${trimmedKey.substring(0, 8)}... (Attempted: ${trimmedEmail})`);
1270
1276
  return ctx.badRequest("Email address does not match this license key");
1271
1277
  }
1272
1278
  await licenseGuard2.storeLicenseKey(trimmedKey);
@@ -1276,7 +1282,7 @@ var license$1 = ({ strapi: strapi2 }) => ({
1276
1282
  pingInterval,
1277
1283
  data: verification.data
1278
1284
  };
1279
- strapi2.log.info(`[magic-sessionmanager] Existing license key validated and stored: ${trimmedKey.substring(0, 8)}... (Email: ${trimmedEmail})`);
1285
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Existing license key validated and stored: ${trimmedKey.substring(0, 8)}... (Email: ${trimmedEmail})`);
1280
1286
  return ctx.send({
1281
1287
  success: true,
1282
1288
  message: "License key validated and activated successfully",
@@ -1398,6 +1404,7 @@ var controllers$1 = {
1398
1404
  settings
1399
1405
  };
1400
1406
  const { encryptToken, decryptToken, generateSessionId } = encryption;
1407
+ const SESSION_UID = "plugin::magic-sessionmanager.session";
1401
1408
  var session$1 = ({ strapi: strapi2 }) => ({
1402
1409
  /**
1403
1410
  * Create a new session record
@@ -1410,23 +1417,24 @@ var session$1 = ({ strapi: strapi2 }) => ({
1410
1417
  const sessionId = generateSessionId(userId);
1411
1418
  const encryptedToken = token ? encryptToken(token) : null;
1412
1419
  const encryptedRefreshToken = refreshToken ? encryptToken(refreshToken) : null;
1413
- const session2 = await strapi2.entityService.create("plugin::magic-sessionmanager.session", {
1420
+ const session2 = await strapi2.documents(SESSION_UID).create({
1414
1421
  data: {
1415
1422
  user: userId,
1423
+ // userId should be documentId (string)
1416
1424
  ipAddress: ip.substring(0, 45),
1417
1425
  userAgent: userAgent.substring(0, 500),
1418
1426
  loginTime: now,
1419
1427
  lastActive: now,
1420
1428
  isActive: true,
1421
1429
  token: encryptedToken,
1422
- // Encrypted Access Token
1430
+ // [SUCCESS] Encrypted Access Token
1423
1431
  refreshToken: encryptedRefreshToken,
1424
- // Encrypted Refresh Token
1432
+ // [SUCCESS] Encrypted Refresh Token
1425
1433
  sessionId
1426
- // Unique identifier
1434
+ // [SUCCESS] Unique identifier
1427
1435
  }
1428
1436
  });
1429
- strapi2.log.info(`[magic-sessionmanager] Session ${session2.id} (${sessionId}) created for user ${userId}`);
1437
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Session ${session2.documentId} (${sessionId}) created for user ${userId}`);
1430
1438
  return session2;
1431
1439
  } catch (err) {
1432
1440
  strapi2.log.error("[magic-sessionmanager] Error creating session:", err);
@@ -1442,7 +1450,8 @@ var session$1 = ({ strapi: strapi2 }) => ({
1442
1450
  try {
1443
1451
  const now = /* @__PURE__ */ new Date();
1444
1452
  if (sessionId) {
1445
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", sessionId, {
1453
+ await strapi2.documents(SESSION_UID).update({
1454
+ documentId: sessionId,
1446
1455
  data: {
1447
1456
  isActive: false,
1448
1457
  logoutTime: now
@@ -1450,14 +1459,16 @@ var session$1 = ({ strapi: strapi2 }) => ({
1450
1459
  });
1451
1460
  strapi2.log.info(`[magic-sessionmanager] Session ${sessionId} terminated`);
1452
1461
  } else if (userId) {
1453
- const activeSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1462
+ const activeSessions = await strapi2.documents(SESSION_UID).findMany({
1454
1463
  filters: {
1455
- user: { id: userId },
1464
+ user: { documentId: userId },
1465
+ // Deep filtering syntax
1456
1466
  isActive: true
1457
1467
  }
1458
1468
  });
1459
1469
  for (const session2 of activeSessions) {
1460
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", session2.id, {
1470
+ await strapi2.documents(SESSION_UID).update({
1471
+ documentId: session2.documentId,
1461
1472
  data: {
1462
1473
  isActive: false,
1463
1474
  logoutTime: now
@@ -1477,7 +1488,7 @@ var session$1 = ({ strapi: strapi2 }) => ({
1477
1488
  */
1478
1489
  async getAllSessions() {
1479
1490
  try {
1480
- const sessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1491
+ const sessions = await strapi2.documents(SESSION_UID).findMany({
1481
1492
  populate: { user: { fields: ["id", "email", "username"] } },
1482
1493
  sort: { loginTime: "desc" },
1483
1494
  limit: 1e3
@@ -1509,7 +1520,7 @@ var session$1 = ({ strapi: strapi2 }) => ({
1509
1520
  */
1510
1521
  async getActiveSessions() {
1511
1522
  try {
1512
- const sessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1523
+ const sessions = await strapi2.documents(SESSION_UID).findMany({
1513
1524
  filters: { isActive: true },
1514
1525
  populate: { user: { fields: ["id", "email", "username"] } },
1515
1526
  sort: { loginTime: "desc" }
@@ -1541,8 +1552,8 @@ var session$1 = ({ strapi: strapi2 }) => ({
1541
1552
  */
1542
1553
  async getUserSessions(userId) {
1543
1554
  try {
1544
- const sessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1545
- filters: { user: { id: userId } },
1555
+ const sessions = await strapi2.documents(SESSION_UID).findMany({
1556
+ filters: { user: { documentId: userId } },
1546
1557
  sort: { loginTime: "desc" }
1547
1558
  });
1548
1559
  const config2 = strapi2.config.get("plugin::magic-sessionmanager") || {};
@@ -1576,17 +1587,19 @@ var session$1 = ({ strapi: strapi2 }) => ({
1576
1587
  const config2 = strapi2.config.get("plugin::magic-sessionmanager") || {};
1577
1588
  const rateLimit = config2.lastSeenRateLimit || 3e4;
1578
1589
  if (sessionId) {
1579
- const session2 = await strapi2.entityService.findOne("plugin::magic-sessionmanager.session", sessionId);
1590
+ const session2 = await strapi2.documents(SESSION_UID).findOne({ documentId: sessionId });
1580
1591
  if (session2 && session2.lastActive) {
1581
1592
  const lastActiveTime = new Date(session2.lastActive).getTime();
1582
1593
  const currentTime = now.getTime();
1583
1594
  if (currentTime - lastActiveTime > rateLimit) {
1584
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", sessionId, {
1595
+ await strapi2.documents(SESSION_UID).update({
1596
+ documentId: sessionId,
1585
1597
  data: { lastActive: now }
1586
1598
  });
1587
1599
  }
1588
1600
  } else if (session2) {
1589
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", sessionId, {
1601
+ await strapi2.documents(SESSION_UID).update({
1602
+ documentId: sessionId,
1590
1603
  data: { lastActive: now }
1591
1604
  });
1592
1605
  }
@@ -1605,22 +1618,23 @@ var session$1 = ({ strapi: strapi2 }) => ({
1605
1618
  const inactivityTimeout = config2.inactivityTimeout || 15 * 60 * 1e3;
1606
1619
  const now = /* @__PURE__ */ new Date();
1607
1620
  const cutoffTime = new Date(now.getTime() - inactivityTimeout);
1608
- strapi2.log.info(`[magic-sessionmanager] 🧹 Cleaning up sessions inactive since before ${cutoffTime.toISOString()}`);
1609
- const activeSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1621
+ strapi2.log.info(`[magic-sessionmanager] [CLEANUP] Cleaning up sessions inactive since before ${cutoffTime.toISOString()}`);
1622
+ const activeSessions = await strapi2.documents(SESSION_UID).findMany({
1610
1623
  filters: { isActive: true },
1611
- fields: ["id", "lastActive", "loginTime"]
1624
+ fields: ["lastActive", "loginTime"]
1612
1625
  });
1613
1626
  let deactivatedCount = 0;
1614
1627
  for (const session2 of activeSessions) {
1615
1628
  const lastActiveTime = session2.lastActive ? new Date(session2.lastActive) : new Date(session2.loginTime);
1616
1629
  if (lastActiveTime < cutoffTime) {
1617
- await strapi2.entityService.update("plugin::magic-sessionmanager.session", session2.id, {
1630
+ await strapi2.documents(SESSION_UID).update({
1631
+ documentId: session2.documentId,
1618
1632
  data: { isActive: false }
1619
1633
  });
1620
1634
  deactivatedCount++;
1621
1635
  }
1622
1636
  }
1623
- strapi2.log.info(`[magic-sessionmanager] Cleanup complete: ${deactivatedCount} sessions deactivated`);
1637
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Cleanup complete: ${deactivatedCount} sessions deactivated`);
1624
1638
  return deactivatedCount;
1625
1639
  } catch (err) {
1626
1640
  strapi2.log.error("[magic-sessionmanager] Error cleaning up inactive sessions:", err);
@@ -1635,8 +1649,8 @@ var session$1 = ({ strapi: strapi2 }) => ({
1635
1649
  */
1636
1650
  async deleteSession(sessionId) {
1637
1651
  try {
1638
- await strapi2.entityService.delete("plugin::magic-sessionmanager.session", sessionId);
1639
- strapi2.log.info(`[magic-sessionmanager] 🗑️ Session ${sessionId} permanently deleted`);
1652
+ await strapi2.documents(SESSION_UID).delete({ documentId: sessionId });
1653
+ strapi2.log.info(`[magic-sessionmanager] [DELETE] Session ${sessionId} permanently deleted`);
1640
1654
  return true;
1641
1655
  } catch (err) {
1642
1656
  strapi2.log.error("[magic-sessionmanager] Error deleting session:", err);
@@ -1650,17 +1664,16 @@ var session$1 = ({ strapi: strapi2 }) => ({
1650
1664
  */
1651
1665
  async deleteInactiveSessions() {
1652
1666
  try {
1653
- strapi2.log.info("[magic-sessionmanager] 🗑️ Deleting all inactive sessions...");
1654
- const inactiveSessions = await strapi2.entityService.findMany("plugin::magic-sessionmanager.session", {
1655
- filters: { isActive: false },
1656
- fields: ["id"]
1667
+ strapi2.log.info("[magic-sessionmanager] [DELETE] Deleting all inactive sessions...");
1668
+ const inactiveSessions = await strapi2.documents(SESSION_UID).findMany({
1669
+ filters: { isActive: false }
1657
1670
  });
1658
1671
  let deletedCount = 0;
1659
1672
  for (const session2 of inactiveSessions) {
1660
- await strapi2.entityService.delete("plugin::magic-sessionmanager.session", session2.id);
1673
+ await strapi2.documents(SESSION_UID).delete({ documentId: session2.documentId });
1661
1674
  deletedCount++;
1662
1675
  }
1663
- strapi2.log.info(`[magic-sessionmanager] Deleted ${deletedCount} inactive sessions`);
1676
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Deleted ${deletedCount} inactive sessions`);
1664
1677
  return deletedCount;
1665
1678
  } catch (err) {
1666
1679
  strapi2.log.error("[magic-sessionmanager] Error deleting inactive sessions:", err);
@@ -1668,8 +1681,13 @@ var session$1 = ({ strapi: strapi2 }) => ({
1668
1681
  }
1669
1682
  }
1670
1683
  });
1684
+ const version = "3.7.0";
1685
+ const require$$2 = {
1686
+ version
1687
+ };
1671
1688
  const crypto = require$$0__default.default;
1672
1689
  const os = require$$1__default.default;
1690
+ const pluginPkg = require$$2;
1673
1691
  const LICENSE_SERVER_URL = "https://magicapi.fitlex.me";
1674
1692
  var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1675
1693
  /**
@@ -1724,7 +1742,9 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1724
1742
  }
1725
1743
  },
1726
1744
  getUserAgent() {
1727
- return `Strapi/${strapi2.config.get("info.strapi") || "5.0.0"} Node/${process.version} ${os.platform()}/${os.release()}`;
1745
+ const pluginVersion = pluginPkg.version;
1746
+ const strapiVersion = strapi2.config.get("info.strapi") || "5.0.0";
1747
+ return `MagicSessionManager/${pluginVersion} Strapi/${strapiVersion} Node/${process.version} ${os.platform()}/${os.release()}`;
1728
1748
  },
1729
1749
  async createLicense({ email, firstName, lastName }) {
1730
1750
  try {
@@ -1750,14 +1770,14 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1750
1770
  });
1751
1771
  const data = await response.json();
1752
1772
  if (data.success) {
1753
- strapi2.log.info("[magic-sessionmanager] License created:", data.data.licenseKey);
1773
+ strapi2.log.info("[magic-sessionmanager] [SUCCESS] License created:", data.data.licenseKey);
1754
1774
  return data.data;
1755
1775
  } else {
1756
- strapi2.log.error("[magic-sessionmanager] License creation failed:", data);
1776
+ strapi2.log.error("[magic-sessionmanager] [ERROR] License creation failed:", data);
1757
1777
  return null;
1758
1778
  }
1759
1779
  } catch (error) {
1760
- strapi2.log.error("[magic-sessionmanager] Error creating license:", error);
1780
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Error creating license:", error);
1761
1781
  return null;
1762
1782
  }
1763
1783
  },
@@ -1842,10 +1862,10 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1842
1862
  name: "magic-sessionmanager"
1843
1863
  });
1844
1864
  await pluginStore.set({ key: "licenseKey", value: licenseKey });
1845
- strapi2.log.info(`[magic-sessionmanager] License key stored: ${licenseKey.substring(0, 8)}...`);
1865
+ strapi2.log.info(`[magic-sessionmanager] [SUCCESS] License key stored: ${licenseKey.substring(0, 8)}...`);
1846
1866
  },
1847
1867
  startPinging(licenseKey, intervalMinutes = 15) {
1848
- strapi2.log.info(`[magic-sessionmanager] Starting license pings every ${intervalMinutes} minutes`);
1868
+ strapi2.log.info(`[magic-sessionmanager] [TIME] Starting license pings every ${intervalMinutes} minutes`);
1849
1869
  this.pingLicense(licenseKey);
1850
1870
  const interval = setInterval(async () => {
1851
1871
  try {
@@ -1862,14 +1882,14 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1862
1882
  */
1863
1883
  async initialize() {
1864
1884
  try {
1865
- strapi2.log.info("[magic-sessionmanager] 🔐 Initializing License Guard...");
1885
+ strapi2.log.info("[magic-sessionmanager] [SECURE] Initializing License Guard...");
1866
1886
  const pluginStore = strapi2.store({
1867
1887
  type: "plugin",
1868
1888
  name: "magic-sessionmanager"
1869
1889
  });
1870
1890
  const licenseKey = await pluginStore.get({ key: "licenseKey" });
1871
1891
  if (!licenseKey) {
1872
- strapi2.log.info("[magic-sessionmanager] ℹ️ No license found - Running in demo mode");
1892
+ strapi2.log.info("[magic-sessionmanager] [INFO] No license found - Running in demo mode");
1873
1893
  return {
1874
1894
  valid: false,
1875
1895
  demo: true,
@@ -1904,7 +1924,7 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1904
1924
  gracePeriod: verification.gracePeriod || false
1905
1925
  };
1906
1926
  } else {
1907
- strapi2.log.error("[magic-sessionmanager] License validation failed");
1927
+ strapi2.log.error("[magic-sessionmanager] [ERROR] License validation failed");
1908
1928
  return {
1909
1929
  valid: false,
1910
1930
  demo: true,
@@ -1913,7 +1933,7 @@ var licenseGuard$1 = ({ strapi: strapi2 }) => ({
1913
1933
  };
1914
1934
  }
1915
1935
  } catch (error) {
1916
- strapi2.log.error("[magic-sessionmanager] Error initializing License Guard:", error);
1936
+ strapi2.log.error("[magic-sessionmanager] [ERROR] Error initializing License Guard:", error);
1917
1937
  return {
1918
1938
  valid: false,
1919
1939
  demo: true,
@@ -2026,9 +2046,11 @@ var geolocation$1 = ({ strapi: strapi2 }) => ({
2026
2046
  },
2027
2047
  /**
2028
2048
  * Get country flag emoji
2049
+ * @param {string} countryCode - ISO 2-letter country code
2050
+ * @returns {string} Flag emoji or empty string
2029
2051
  */
2030
2052
  getCountryFlag(countryCode) {
2031
- if (!countryCode) return "🏳️";
2053
+ if (!countryCode) return "";
2032
2054
  const codePoints = countryCode.toUpperCase().split("").map((char) => 127397 + char.charCodeAt());
2033
2055
  return String.fromCodePoint(...codePoints);
2034
2056
  },
@@ -2040,7 +2062,7 @@ var geolocation$1 = ({ strapi: strapi2 }) => ({
2040
2062
  ip: ipAddress,
2041
2063
  country: "Unknown",
2042
2064
  country_code: "XX",
2043
- country_flag: "🌍",
2065
+ country_flag: "[GEO]",
2044
2066
  city: "Unknown",
2045
2067
  region: "Unknown",
2046
2068
  timezone: "Unknown",
@@ -2145,9 +2167,9 @@ Login Details:
2145
2167
  Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThreat}}, Score={{reason.securityScore}}/100`
2146
2168
  },
2147
2169
  newLocation: {
2148
- subject: "📍 New Location Login Detected",
2149
- 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>`,
2150
- text: `📍 New Location Login
2170
+ subject: "[LOCATION] New Location Login Detected",
2171
+ 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>`,
2172
+ text: `[LOCATION] New Location Login
2151
2173
 
2152
2174
  Account: {{user.email}}
2153
2175
  Time: {{session.loginTime}}
@@ -2155,9 +2177,9 @@ Location: {{geo.city}}, {{geo.country}}
2155
2177
  IP: {{session.ipAddress}}`
2156
2178
  },
2157
2179
  vpnProxy: {
2158
- subject: "⚠️ VPN/Proxy Login Detected",
2159
- 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>`,
2160
- text: `⚠️ VPN/Proxy Detected
2180
+ subject: "[WARNING] VPN/Proxy Login Detected",
2181
+ 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>`,
2182
+ text: `[WARNING] VPN/Proxy Detected
2161
2183
 
2162
2184
  Account: {{user.email}}
2163
2185
  Time: {{session.loginTime}}
@@ -2311,7 +2333,7 @@ ${user.username || "N/A"}`, inline: true },
2311
2333
  };
2312
2334
  if (geoData) {
2313
2335
  embed.fields.push({
2314
- name: "📍 Location",
2336
+ name: "[LOCATION] Location",
2315
2337
  value: `${geoData.country_flag} ${geoData.city}, ${geoData.country}`,
2316
2338
  inline: true
2317
2339
  });
@@ -2321,7 +2343,7 @@ ${user.username || "N/A"}`, inline: true },
2321
2343
  if (geoData.isProxy) warnings.push("Proxy");
2322
2344
  if (geoData.isThreat) warnings.push("Threat");
2323
2345
  embed.fields.push({
2324
- name: "⚠️ Security",
2346
+ name: "[WARNING] Security",
2325
2347
  value: `${warnings.join(", ")} detected
2326
2348
  Score: ${geoData.securityScore}/100`,
2327
2349
  inline: true
@@ -2333,12 +2355,12 @@ Score: ${geoData.securityScore}/100`,
2333
2355
  getEventTitle(event) {
2334
2356
  const titles = {
2335
2357
  "login.suspicious": "🚨 Suspicious Login",
2336
- "login.new_location": "📍 New Location Login",
2358
+ "login.new_location": "[LOCATION] New Location Login",
2337
2359
  "login.vpn": "🔴 VPN Login Detected",
2338
2360
  "login.threat": "⛔ Threat IP Login",
2339
2361
  "session.terminated": "🔴 Session Terminated"
2340
2362
  };
2341
- return titles[event] || "📊 Session Event";
2363
+ return titles[event] || "[STATS] Session Event";
2342
2364
  },
2343
2365
  getEventColor(event) {
2344
2366
  const colors = {