strapi-plugin-magic-sessionmanager 4.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/src/components/LicenseGuard.jsx +6 -6
- package/admin/src/components/SessionDetailModal.jsx +12 -12
- package/admin/src/components/SessionInfoCard.jsx +3 -3
- package/admin/src/components/SessionInfoPanel.jsx +3 -2
- package/admin/src/pages/Analytics.jsx +2 -2
- package/admin/src/pages/HomePage.jsx +11 -14
- package/admin/src/pages/License.jsx +2 -2
- package/admin/src/pages/Settings.jsx +24 -24
- package/admin/src/pages/SettingsNew.jsx +21 -21
- package/admin/src/utils/parseUserAgent.js +6 -6
- package/dist/_chunks/{Analytics-ioaeEh-E.js → Analytics-BBdv1I5y.js} +4 -4
- package/dist/_chunks/{Analytics-mYu_uGwU.mjs → Analytics-Dv9f_0eZ.mjs} +4 -4
- package/dist/_chunks/{App-BXpIS12l.mjs → App-CIQ-7sa7.mjs} +26 -31
- package/dist/_chunks/{App-DdnUYWbC.js → App-CJaZPNjt.js} +26 -31
- package/dist/_chunks/{License-DZYrOgcx.js → License-D24rgaZQ.js} +3 -3
- package/dist/_chunks/{License-C03C2j9P.mjs → License-nrmFxoBm.mjs} +3 -3
- package/dist/_chunks/{Settings-C6_CqpCC.js → Settings-CqxgjU0y.js} +26 -26
- package/dist/_chunks/{Settings-0ocB3qHk.mjs → Settings-D5dLEGc_.mjs} +26 -26
- package/dist/_chunks/{index-DBRS3kt5.mjs → index-Duk1_Wrz.mjs} +12 -12
- package/dist/_chunks/{index-DC8Y0qxx.js → index-WH04CS1c.js} +12 -12
- package/dist/_chunks/{useLicense-qgGfMvse.js → useLicense-BwOlCyhc.js} +1 -1
- package/dist/_chunks/{useLicense-DSLL9n3Y.mjs → useLicense-Ce8GaxB0.mjs} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +142 -33
- package/dist/server/index.mjs +142 -33
- package/package.json +1 -1
- package/server/src/bootstrap.js +76 -4
- package/server/src/controllers/session.js +59 -9
- package/server/src/middlewares/last-seen.js +5 -4
- package/server/src/routes/content-api.js +11 -2
- package/server/src/services/notifications.js +10 -10
- package/server/src/services/session.js +24 -4
package/dist/server/index.js
CHANGED
|
@@ -152,9 +152,9 @@ var encryption = {
|
|
|
152
152
|
const SESSION_UID$3 = "plugin::magic-sessionmanager.session";
|
|
153
153
|
var lastSeen = ({ strapi: strapi2, sessionService }) => {
|
|
154
154
|
return async (ctx, next) => {
|
|
155
|
-
if (ctx.state.user && ctx.state.user.
|
|
155
|
+
if (ctx.state.user && ctx.state.user.documentId) {
|
|
156
156
|
try {
|
|
157
|
-
const userId = ctx.state.user.
|
|
157
|
+
const userId = ctx.state.user.documentId;
|
|
158
158
|
const activeSessions = await strapi2.documents(SESSION_UID$3).findMany({
|
|
159
159
|
filters: {
|
|
160
160
|
user: { documentId: userId },
|
|
@@ -171,9 +171,9 @@ var lastSeen = ({ strapi: strapi2, sessionService }) => {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
await next();
|
|
174
|
-
if (ctx.state.user && ctx.state.user.
|
|
174
|
+
if (ctx.state.user && ctx.state.user.documentId) {
|
|
175
175
|
try {
|
|
176
|
-
const userId = ctx.state.user.
|
|
176
|
+
const userId = ctx.state.user.documentId;
|
|
177
177
|
const sessionId = ctx.state.sessionId;
|
|
178
178
|
await sessionService.touch({
|
|
179
179
|
userId,
|
|
@@ -188,6 +188,7 @@ var lastSeen = ({ strapi: strapi2, sessionService }) => {
|
|
|
188
188
|
const getClientIp = getClientIp_1;
|
|
189
189
|
const { encryptToken: encryptToken$1, decryptToken: decryptToken$2 } = encryption;
|
|
190
190
|
const SESSION_UID$2 = "plugin::magic-sessionmanager.session";
|
|
191
|
+
const USER_UID$2 = "plugin::users-permissions.user";
|
|
191
192
|
var bootstrap$1 = async ({ strapi: strapi2 }) => {
|
|
192
193
|
strapi2.log.info("[magic-sessionmanager] [START] Bootstrap starting...");
|
|
193
194
|
try {
|
|
@@ -295,7 +296,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
|
|
|
295
296
|
const user = ctx.body.user;
|
|
296
297
|
const ip = getClientIp(ctx);
|
|
297
298
|
const userAgent = ctx.request.headers?.["user-agent"] || ctx.request.header?.["user-agent"] || "unknown";
|
|
298
|
-
strapi2.log.info(`[magic-sessionmanager] [CHECK] Login detected! User: ${user.id} (${user.email || user.username}) from IP: ${ip}`);
|
|
299
|
+
strapi2.log.info(`[magic-sessionmanager] [CHECK] Login detected! User: ${user.documentId || user.id} (${user.email || user.username}) from IP: ${ip}`);
|
|
299
300
|
const config2 = strapi2.config.get("plugin::magic-sessionmanager") || {};
|
|
300
301
|
let shouldBlock = false;
|
|
301
302
|
let blockReason = "";
|
|
@@ -348,8 +349,13 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
|
|
|
348
349
|
};
|
|
349
350
|
return;
|
|
350
351
|
}
|
|
352
|
+
let userDocId = user.documentId;
|
|
353
|
+
if (!userDocId && user.id) {
|
|
354
|
+
const fullUser = await strapi2.entityService.findOne(USER_UID$2, user.id);
|
|
355
|
+
userDocId = fullUser?.documentId || user.id;
|
|
356
|
+
}
|
|
351
357
|
const newSession = await sessionService.createSession({
|
|
352
|
-
userId:
|
|
358
|
+
userId: userDocId,
|
|
353
359
|
ip,
|
|
354
360
|
userAgent,
|
|
355
361
|
token: ctx.body.jwt,
|
|
@@ -357,7 +363,7 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
|
|
|
357
363
|
refreshToken: ctx.body.refreshToken
|
|
358
364
|
// Store Refresh Token (encrypted) if exists
|
|
359
365
|
});
|
|
360
|
-
strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Session created for user ${
|
|
366
|
+
strapi2.log.info(`[magic-sessionmanager] [SUCCESS] Session created for user ${userDocId} (IP: ${ip})`);
|
|
361
367
|
if (geoData && (config2.enableEmailAlerts || config2.enableWebhooks)) {
|
|
362
368
|
try {
|
|
363
369
|
const notificationService = strapi2.plugin("magic-sessionmanager").service("notifications");
|
|
@@ -483,12 +489,55 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
|
|
|
483
489
|
lastSeen({ strapi: strapi2, sessionService })
|
|
484
490
|
);
|
|
485
491
|
strapi2.log.info("[magic-sessionmanager] [SUCCESS] LastSeen middleware mounted");
|
|
492
|
+
await ensureContentApiPermissions(strapi2);
|
|
486
493
|
strapi2.log.info("[magic-sessionmanager] [SUCCESS] Bootstrap complete");
|
|
487
494
|
strapi2.log.info("[magic-sessionmanager] [READY] Session Manager ready! Sessions stored in plugin::magic-sessionmanager.session");
|
|
488
495
|
} catch (err) {
|
|
489
496
|
strapi2.log.error("[magic-sessionmanager] [ERROR] Bootstrap error:", err);
|
|
490
497
|
}
|
|
491
498
|
};
|
|
499
|
+
async function ensureContentApiPermissions(strapi2) {
|
|
500
|
+
try {
|
|
501
|
+
const authenticatedRole = await strapi2.query("plugin::users-permissions.role").findOne({
|
|
502
|
+
where: { type: "authenticated" }
|
|
503
|
+
});
|
|
504
|
+
if (!authenticatedRole) {
|
|
505
|
+
strapi2.log.warn("[magic-sessionmanager] Authenticated role not found - skipping permission setup");
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const requiredActions = [
|
|
509
|
+
"plugin::magic-sessionmanager.session.logout",
|
|
510
|
+
"plugin::magic-sessionmanager.session.logoutAll",
|
|
511
|
+
"plugin::magic-sessionmanager.session.getOwnSessions",
|
|
512
|
+
"plugin::magic-sessionmanager.session.getUserSessions"
|
|
513
|
+
];
|
|
514
|
+
const existingPermissions = await strapi2.query("plugin::users-permissions.permission").findMany({
|
|
515
|
+
where: {
|
|
516
|
+
role: authenticatedRole.id,
|
|
517
|
+
action: { $in: requiredActions }
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
const existingActions = existingPermissions.map((p) => p.action);
|
|
521
|
+
const missingActions = requiredActions.filter((action) => !existingActions.includes(action));
|
|
522
|
+
if (missingActions.length === 0) {
|
|
523
|
+
strapi2.log.debug("[magic-sessionmanager] Content-API permissions already configured");
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
for (const action of missingActions) {
|
|
527
|
+
await strapi2.query("plugin::users-permissions.permission").create({
|
|
528
|
+
data: {
|
|
529
|
+
action,
|
|
530
|
+
role: authenticatedRole.id
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
strapi2.log.info(`[magic-sessionmanager] [PERMISSION] Enabled ${action} for authenticated users`);
|
|
534
|
+
}
|
|
535
|
+
strapi2.log.info("[magic-sessionmanager] [SUCCESS] Content-API permissions configured for authenticated users");
|
|
536
|
+
} catch (err) {
|
|
537
|
+
strapi2.log.warn("[magic-sessionmanager] Could not auto-configure permissions:", err.message);
|
|
538
|
+
strapi2.log.warn("[magic-sessionmanager] Please manually enable plugin permissions in Settings > Users & Permissions > Roles > Authenticated");
|
|
539
|
+
}
|
|
540
|
+
}
|
|
492
541
|
var destroy$1 = async ({ strapi: strapi2 }) => {
|
|
493
542
|
if (strapi2.licenseGuard && strapi2.licenseGuard.pingInterval) {
|
|
494
543
|
clearInterval(strapi2.licenseGuard.pingInterval);
|
|
@@ -641,13 +690,22 @@ var contentApi$1 = {
|
|
|
641
690
|
// ============================================================
|
|
642
691
|
// SESSION QUERIES
|
|
643
692
|
// ============================================================
|
|
693
|
+
{
|
|
694
|
+
method: "GET",
|
|
695
|
+
path: "/my-sessions",
|
|
696
|
+
handler: "session.getOwnSessions",
|
|
697
|
+
config: {
|
|
698
|
+
auth: { strategies: ["users-permissions"] },
|
|
699
|
+
description: "Get own sessions (automatically uses authenticated user)"
|
|
700
|
+
}
|
|
701
|
+
},
|
|
644
702
|
{
|
|
645
703
|
method: "GET",
|
|
646
704
|
path: "/user/:userId/sessions",
|
|
647
705
|
handler: "session.getUserSessions",
|
|
648
706
|
config: {
|
|
649
707
|
auth: { strategies: ["users-permissions"] },
|
|
650
|
-
description: "Get
|
|
708
|
+
description: "Get sessions by userId (validates user can only see own sessions)"
|
|
651
709
|
}
|
|
652
710
|
}
|
|
653
711
|
]
|
|
@@ -807,7 +865,7 @@ var routes$1 = {
|
|
|
807
865
|
};
|
|
808
866
|
const { decryptToken: decryptToken$1 } = encryption;
|
|
809
867
|
const SESSION_UID$1 = "plugin::magic-sessionmanager.session";
|
|
810
|
-
const USER_UID = "plugin::users-permissions.user";
|
|
868
|
+
const USER_UID$1 = "plugin::users-permissions.user";
|
|
811
869
|
var session$3 = {
|
|
812
870
|
/**
|
|
813
871
|
* Get ALL sessions (active + inactive) - Admin only
|
|
@@ -847,6 +905,30 @@ var session$3 = {
|
|
|
847
905
|
ctx.throw(500, "Error fetching active sessions");
|
|
848
906
|
}
|
|
849
907
|
},
|
|
908
|
+
/**
|
|
909
|
+
* Get own sessions (authenticated user)
|
|
910
|
+
* GET /api/magic-sessionmanager/my-sessions
|
|
911
|
+
* Automatically uses the authenticated user's documentId
|
|
912
|
+
*/
|
|
913
|
+
async getOwnSessions(ctx) {
|
|
914
|
+
try {
|
|
915
|
+
const userId = ctx.state.user?.documentId;
|
|
916
|
+
if (!userId) {
|
|
917
|
+
return ctx.throw(401, "Unauthorized");
|
|
918
|
+
}
|
|
919
|
+
const sessionService = strapi.plugin("magic-sessionmanager").service("session");
|
|
920
|
+
const sessions = await sessionService.getUserSessions(userId);
|
|
921
|
+
ctx.body = {
|
|
922
|
+
data: sessions,
|
|
923
|
+
meta: {
|
|
924
|
+
count: sessions.length
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
} catch (err) {
|
|
928
|
+
strapi.log.error("[magic-sessionmanager] Error fetching own sessions:", err);
|
|
929
|
+
ctx.throw(500, "Error fetching sessions");
|
|
930
|
+
}
|
|
931
|
+
},
|
|
850
932
|
/**
|
|
851
933
|
* Get user's sessions
|
|
852
934
|
* GET /magic-sessionmanager/user/:userId/sessions (Admin API)
|
|
@@ -857,9 +939,9 @@ var session$3 = {
|
|
|
857
939
|
try {
|
|
858
940
|
const { userId } = ctx.params;
|
|
859
941
|
const isAdminRequest = ctx.state.userAbility || ctx.state.admin;
|
|
860
|
-
const
|
|
861
|
-
if (!isAdminRequest &&
|
|
862
|
-
strapi.log.warn(`[magic-sessionmanager] Security: User ${
|
|
942
|
+
const requestingUserDocId = ctx.state.user?.documentId;
|
|
943
|
+
if (!isAdminRequest && requestingUserDocId && String(requestingUserDocId) !== String(userId)) {
|
|
944
|
+
strapi.log.warn(`[magic-sessionmanager] Security: User ${requestingUserDocId} tried to access sessions of user ${userId}`);
|
|
863
945
|
return ctx.forbidden("You can only access your own sessions");
|
|
864
946
|
}
|
|
865
947
|
const sessionService = strapi.plugin("magic-sessionmanager").service("session");
|
|
@@ -880,7 +962,7 @@ var session$3 = {
|
|
|
880
962
|
*/
|
|
881
963
|
async logout(ctx) {
|
|
882
964
|
try {
|
|
883
|
-
const userId = ctx.state.user?.
|
|
965
|
+
const userId = ctx.state.user?.documentId;
|
|
884
966
|
const token = ctx.request.headers.authorization?.replace("Bearer ", "");
|
|
885
967
|
if (!userId) {
|
|
886
968
|
return ctx.throw(401, "Unauthorized");
|
|
@@ -919,7 +1001,7 @@ var session$3 = {
|
|
|
919
1001
|
*/
|
|
920
1002
|
async logoutAll(ctx) {
|
|
921
1003
|
try {
|
|
922
|
-
const userId = ctx.state.user?.
|
|
1004
|
+
const userId = ctx.state.user?.documentId;
|
|
923
1005
|
if (!userId) {
|
|
924
1006
|
return ctx.throw(401, "Unauthorized");
|
|
925
1007
|
}
|
|
@@ -1059,24 +1141,34 @@ var session$3 = {
|
|
|
1059
1141
|
/**
|
|
1060
1142
|
* Toggle user blocked status
|
|
1061
1143
|
* POST /magic-sessionmanager/user/:userId/toggle-block
|
|
1144
|
+
* Supports both numeric id (from Content Manager) and documentId
|
|
1062
1145
|
*/
|
|
1063
1146
|
async toggleUserBlock(ctx) {
|
|
1064
1147
|
try {
|
|
1065
1148
|
const { userId } = ctx.params;
|
|
1066
|
-
|
|
1149
|
+
let userDocumentId = userId;
|
|
1150
|
+
let user = null;
|
|
1151
|
+
user = await strapi.documents(USER_UID$1).findOne({ documentId: userId });
|
|
1152
|
+
if (!user && !isNaN(userId)) {
|
|
1153
|
+
const numericUser = await strapi.entityService.findOne(USER_UID$1, parseInt(userId, 10));
|
|
1154
|
+
if (numericUser) {
|
|
1155
|
+
userDocumentId = numericUser.documentId;
|
|
1156
|
+
user = numericUser;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1067
1159
|
if (!user) {
|
|
1068
1160
|
return ctx.throw(404, "User not found");
|
|
1069
1161
|
}
|
|
1070
1162
|
const newBlockedStatus = !user.blocked;
|
|
1071
|
-
await strapi.documents(USER_UID).update({
|
|
1072
|
-
documentId:
|
|
1163
|
+
await strapi.documents(USER_UID$1).update({
|
|
1164
|
+
documentId: userDocumentId,
|
|
1073
1165
|
data: {
|
|
1074
1166
|
blocked: newBlockedStatus
|
|
1075
1167
|
}
|
|
1076
1168
|
});
|
|
1077
1169
|
if (newBlockedStatus) {
|
|
1078
1170
|
const sessionService = strapi.plugin("magic-sessionmanager").service("session");
|
|
1079
|
-
await sessionService.terminateSession({ userId });
|
|
1171
|
+
await sessionService.terminateSession({ userId: userDocumentId });
|
|
1080
1172
|
}
|
|
1081
1173
|
ctx.body = {
|
|
1082
1174
|
message: `User ${newBlockedStatus ? "blocked" : "unblocked"} successfully`,
|
|
@@ -1405,6 +1497,7 @@ var controllers$1 = {
|
|
|
1405
1497
|
};
|
|
1406
1498
|
const { encryptToken, decryptToken, generateSessionId } = encryption;
|
|
1407
1499
|
const SESSION_UID = "plugin::magic-sessionmanager.session";
|
|
1500
|
+
const USER_UID = "plugin::users-permissions.user";
|
|
1408
1501
|
var session$1 = ({ strapi: strapi2 }) => ({
|
|
1409
1502
|
/**
|
|
1410
1503
|
* Create a new session record
|
|
@@ -1443,6 +1536,7 @@ var session$1 = ({ strapi: strapi2 }) => ({
|
|
|
1443
1536
|
},
|
|
1444
1537
|
/**
|
|
1445
1538
|
* Terminate a session or all sessions for a user
|
|
1539
|
+
* Supports both numeric id (legacy) and documentId (Strapi v5)
|
|
1446
1540
|
* @param {Object} params - { sessionId | userId }
|
|
1447
1541
|
* @returns {Promise<void>}
|
|
1448
1542
|
*/
|
|
@@ -1459,9 +1553,16 @@ var session$1 = ({ strapi: strapi2 }) => ({
|
|
|
1459
1553
|
});
|
|
1460
1554
|
strapi2.log.info(`[magic-sessionmanager] Session ${sessionId} terminated`);
|
|
1461
1555
|
} else if (userId) {
|
|
1556
|
+
let userDocumentId = userId;
|
|
1557
|
+
if (!isNaN(userId)) {
|
|
1558
|
+
const user = await strapi2.entityService.findOne(USER_UID, parseInt(userId, 10));
|
|
1559
|
+
if (user) {
|
|
1560
|
+
userDocumentId = user.documentId;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1462
1563
|
const activeSessions = await strapi2.documents(SESSION_UID).findMany({
|
|
1463
1564
|
filters: {
|
|
1464
|
-
user: { documentId:
|
|
1565
|
+
user: { documentId: userDocumentId },
|
|
1465
1566
|
// Deep filtering syntax
|
|
1466
1567
|
isActive: true
|
|
1467
1568
|
}
|
|
@@ -1475,7 +1576,7 @@ var session$1 = ({ strapi: strapi2 }) => ({
|
|
|
1475
1576
|
}
|
|
1476
1577
|
});
|
|
1477
1578
|
}
|
|
1478
|
-
strapi2.log.info(`[magic-sessionmanager] All sessions terminated for user ${
|
|
1579
|
+
strapi2.log.info(`[magic-sessionmanager] All sessions terminated for user ${userDocumentId}`);
|
|
1479
1580
|
}
|
|
1480
1581
|
} catch (err) {
|
|
1481
1582
|
strapi2.log.error("[magic-sessionmanager] Error terminating session:", err);
|
|
@@ -1547,13 +1648,21 @@ var session$1 = ({ strapi: strapi2 }) => ({
|
|
|
1547
1648
|
},
|
|
1548
1649
|
/**
|
|
1549
1650
|
* Get all sessions for a specific user
|
|
1550
|
-
*
|
|
1651
|
+
* Supports both numeric id (legacy) and documentId (Strapi v5)
|
|
1652
|
+
* @param {string|number} userId - User documentId or numeric id
|
|
1551
1653
|
* @returns {Promise<Array>} User's sessions with accurate online status
|
|
1552
1654
|
*/
|
|
1553
1655
|
async getUserSessions(userId) {
|
|
1554
1656
|
try {
|
|
1657
|
+
let userDocumentId = userId;
|
|
1658
|
+
if (!isNaN(userId)) {
|
|
1659
|
+
const user = await strapi2.entityService.findOne(USER_UID, parseInt(userId, 10));
|
|
1660
|
+
if (user) {
|
|
1661
|
+
userDocumentId = user.documentId;
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1555
1664
|
const sessions = await strapi2.documents(SESSION_UID).findMany({
|
|
1556
|
-
filters: { user: { documentId:
|
|
1665
|
+
filters: { user: { documentId: userDocumentId } },
|
|
1557
1666
|
sort: { loginTime: "desc" }
|
|
1558
1667
|
});
|
|
1559
1668
|
const config2 = strapi2.config.get("plugin::magic-sessionmanager") || {};
|
|
@@ -1681,7 +1790,7 @@ var session$1 = ({ strapi: strapi2 }) => ({
|
|
|
1681
1790
|
}
|
|
1682
1791
|
}
|
|
1683
1792
|
});
|
|
1684
|
-
const version = "
|
|
1793
|
+
const version = "4.0.0";
|
|
1685
1794
|
const require$$2 = {
|
|
1686
1795
|
version
|
|
1687
1796
|
};
|
|
@@ -2112,12 +2221,12 @@ var notifications$1 = ({ strapi: strapi2 }) => ({
|
|
|
2112
2221
|
strapi2.log.debug("[magic-sessionmanager/notifications] Using default fallback templates");
|
|
2113
2222
|
return {
|
|
2114
2223
|
suspiciousLogin: {
|
|
2115
|
-
subject: "
|
|
2224
|
+
subject: "[ALERT] Suspicious Login Alert - Session Manager",
|
|
2116
2225
|
html: `
|
|
2117
2226
|
<html>
|
|
2118
2227
|
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
|
|
2119
2228
|
<div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9fafb; border-radius: 10px;">
|
|
2120
|
-
<h2 style="color: #dc2626;"
|
|
2229
|
+
<h2 style="color: #dc2626;">[ALERT] Suspicious Login Detected</h2>
|
|
2121
2230
|
<p>A potentially suspicious login was detected for your account.</p>
|
|
2122
2231
|
|
|
2123
2232
|
<div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
|
|
@@ -2152,7 +2261,7 @@ var notifications$1 = ({ strapi: strapi2 }) => ({
|
|
|
2152
2261
|
</div>
|
|
2153
2262
|
</body>
|
|
2154
2263
|
</html>`,
|
|
2155
|
-
text:
|
|
2264
|
+
text: `[ALERT] Suspicious Login Detected
|
|
2156
2265
|
|
|
2157
2266
|
A potentially suspicious login was detected for your account.
|
|
2158
2267
|
|
|
@@ -2323,10 +2432,10 @@ VPN: {{reason.isVpn}}, Proxy: {{reason.isProxy}}`
|
|
|
2323
2432
|
title: this.getEventTitle(event),
|
|
2324
2433
|
color: this.getEventColor(event),
|
|
2325
2434
|
fields: [
|
|
2326
|
-
{ name: "
|
|
2435
|
+
{ name: "User", value: `${user.email}
|
|
2327
2436
|
${user.username || "N/A"}`, inline: true },
|
|
2328
|
-
{ name: "
|
|
2329
|
-
{ name: "
|
|
2437
|
+
{ name: "IP", value: session2.ipAddress, inline: true },
|
|
2438
|
+
{ name: "Time", value: new Date(session2.loginTime).toLocaleString(), inline: false }
|
|
2330
2439
|
],
|
|
2331
2440
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2332
2441
|
footer: { text: "Magic Session Manager" }
|
|
@@ -2354,11 +2463,11 @@ Score: ${geoData.securityScore}/100`,
|
|
|
2354
2463
|
},
|
|
2355
2464
|
getEventTitle(event) {
|
|
2356
2465
|
const titles = {
|
|
2357
|
-
"login.suspicious": "
|
|
2466
|
+
"login.suspicious": "[ALERT] Suspicious Login",
|
|
2358
2467
|
"login.new_location": "[LOCATION] New Location Login",
|
|
2359
|
-
"login.vpn": "
|
|
2360
|
-
"login.threat": "
|
|
2361
|
-
"session.terminated": "
|
|
2468
|
+
"login.vpn": "[WARNING] VPN Login Detected",
|
|
2469
|
+
"login.threat": "[THREAT] Threat IP Login",
|
|
2470
|
+
"session.terminated": "[INFO] Session Terminated"
|
|
2362
2471
|
};
|
|
2363
2472
|
return titles[event] || "[STATS] Session Event";
|
|
2364
2473
|
},
|