strapi-plugin-magic-sessionmanager 1.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.
@@ -0,0 +1,507 @@
1
+ "use strict";
2
+ const react = require("react");
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const designSystem = require("@strapi/design-system");
5
+ const icons = require("@strapi/icons");
6
+ const admin = require("@strapi/strapi/admin");
7
+ const strapi = {
8
+ name: "magic-sessionmanager",
9
+ displayName: "Magic Sessionmanager"
10
+ };
11
+ const pluginPkg = {
12
+ strapi
13
+ };
14
+ const pluginId = "magic-sessionmanager";
15
+ const Initializer = () => {
16
+ react.useEffect(() => {
17
+ console.log("[magic-sessionmanager] Plugin initialized");
18
+ }, []);
19
+ return null;
20
+ };
21
+ const PluginIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 32 32", fill: "currentColor", width: "24", height: "24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M26 5H6a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h20a3 3 0 0 0 3-3V8a3 3 0 0 0-3-3M20 27h-8a1 1 0 0 0 0 2h8a1 1 0 0 0 0-2" }) });
22
+ const parseUserAgent = (userAgent) => {
23
+ if (!userAgent) {
24
+ return {
25
+ device: "Unknown",
26
+ deviceIcon: "❓",
27
+ browser: "Unknown",
28
+ os: "Unknown"
29
+ };
30
+ }
31
+ const ua = userAgent.toLowerCase();
32
+ let device = "Desktop";
33
+ let deviceIcon = "💻";
34
+ if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(userAgent)) {
35
+ device = "Tablet";
36
+ deviceIcon = "📱";
37
+ } else if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(userAgent)) {
38
+ device = "Mobile";
39
+ deviceIcon = "📱";
40
+ }
41
+ let browser = "Unknown";
42
+ if (ua.includes("edg/")) {
43
+ browser = "Edge";
44
+ } else if (ua.includes("chrome/") && !ua.includes("edg/")) {
45
+ browser = "Chrome";
46
+ } else if (ua.includes("firefox/")) {
47
+ browser = "Firefox";
48
+ } else if (ua.includes("safari/") && !ua.includes("chrome/")) {
49
+ browser = "Safari";
50
+ } else if (ua.includes("opera/") || ua.includes("opr/")) {
51
+ browser = "Opera";
52
+ } else if (ua.includes("curl/")) {
53
+ browser = "cURL";
54
+ deviceIcon = "⚙️";
55
+ device = "API Client";
56
+ } else if (ua.includes("postman")) {
57
+ browser = "Postman";
58
+ deviceIcon = "📮";
59
+ device = "API Client";
60
+ } else if (ua.includes("insomnia")) {
61
+ browser = "Insomnia";
62
+ deviceIcon = "🌙";
63
+ device = "API Client";
64
+ }
65
+ let os = "Unknown";
66
+ if (ua.includes("windows")) {
67
+ os = "Windows";
68
+ } else if (ua.includes("mac os x") || ua.includes("macintosh")) {
69
+ os = "macOS";
70
+ } else if (ua.includes("linux")) {
71
+ os = "Linux";
72
+ } else if (ua.includes("android")) {
73
+ os = "Android";
74
+ } else if (ua.includes("iphone") || ua.includes("ipad")) {
75
+ os = "iOS";
76
+ }
77
+ return {
78
+ device,
79
+ deviceIcon,
80
+ browser,
81
+ os
82
+ };
83
+ };
84
+ const SessionInfoPanel = ({ documentId, model, document }) => {
85
+ const [sessions, setSessions] = react.useState([]);
86
+ const [loading, setLoading] = react.useState(true);
87
+ const [isBlocked, setIsBlocked] = react.useState(false);
88
+ const [actionLoading, setActionLoading] = react.useState(false);
89
+ const { get, post: postRequest } = admin.useFetchClient();
90
+ const { toggleNotification } = admin.useNotification();
91
+ const userId = document?.id || documentId;
92
+ react.useEffect(() => {
93
+ if (model !== "plugin::users-permissions.user" || !userId) {
94
+ setLoading(false);
95
+ return;
96
+ }
97
+ const fetchData = async () => {
98
+ try {
99
+ const { data } = await get(`/api/magic-sessionmanager/user/${userId}/sessions`);
100
+ const activeSessions = (data.data || []).filter((s) => s.isTrulyActive);
101
+ setSessions(activeSessions);
102
+ setIsBlocked(document?.blocked || false);
103
+ } catch (err) {
104
+ console.error("[SessionInfoPanel] Error:", err);
105
+ } finally {
106
+ setLoading(false);
107
+ }
108
+ };
109
+ fetchData();
110
+ }, [userId, model, document, get]);
111
+ const handleLogoutAll = async () => {
112
+ if (!userId) return;
113
+ setActionLoading(true);
114
+ try {
115
+ const response = await postRequest(`/magic-sessionmanager/user/${userId}/terminate-all`);
116
+ if (response.data?.success) {
117
+ toggleNotification({
118
+ type: "success",
119
+ message: "All sessions terminated successfully"
120
+ });
121
+ setSessions([]);
122
+ }
123
+ } catch (error) {
124
+ toggleNotification({
125
+ type: "warning",
126
+ message: "Failed to terminate sessions"
127
+ });
128
+ console.error("[SessionInfoPanel] Logout all error:", error);
129
+ } finally {
130
+ setActionLoading(false);
131
+ }
132
+ };
133
+ const handleToggleBlock = async () => {
134
+ if (!userId) return;
135
+ setActionLoading(true);
136
+ try {
137
+ const response = await postRequest(`/magic-sessionmanager/user/${userId}/toggle-block`);
138
+ if (response.data?.success) {
139
+ const newBlockedStatus = response.data.blocked;
140
+ setIsBlocked(newBlockedStatus);
141
+ toggleNotification({
142
+ type: "success",
143
+ message: newBlockedStatus ? "User blocked successfully" : "User unblocked successfully"
144
+ });
145
+ if (newBlockedStatus) {
146
+ setSessions([]);
147
+ }
148
+ }
149
+ } catch (error) {
150
+ toggleNotification({
151
+ type: "warning",
152
+ message: "Failed to update user status"
153
+ });
154
+ console.error("[SessionInfoPanel] Toggle block error:", error);
155
+ } finally {
156
+ setActionLoading(false);
157
+ }
158
+ };
159
+ const getDeviceIcon = (deviceType) => {
160
+ if (deviceType === "Mobile" || deviceType === "Tablet") return icons.Phone;
161
+ if (deviceType === "Desktop" || deviceType === "Laptop") return icons.Monitor;
162
+ return icons.Server;
163
+ };
164
+ if (model !== "plugin::users-permissions.user") {
165
+ return null;
166
+ }
167
+ if (loading) {
168
+ return {
169
+ title: "Session Info",
170
+ content: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, background: "neutral0", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Loading..." }) })
171
+ };
172
+ }
173
+ const isOnline = sessions.length > 0;
174
+ return {
175
+ title: "Session Info",
176
+ content: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 4, alignItems: "stretch", children: [
177
+ /* @__PURE__ */ jsxRuntime.jsx(
178
+ designSystem.Box,
179
+ {
180
+ padding: 5,
181
+ background: isOnline ? "success100" : "neutral150",
182
+ hasRadius: true,
183
+ style: {
184
+ border: isOnline ? "1px solid #c6f6d5" : "1px solid #eaeaef",
185
+ transition: "all 0.2s ease"
186
+ },
187
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, alignItems: "center", children: [
188
+ /* @__PURE__ */ jsxRuntime.jsx(
189
+ designSystem.Badge,
190
+ {
191
+ backgroundColor: isOnline ? "success600" : "neutral600",
192
+ textColor: "neutral0",
193
+ size: "M",
194
+ style: { fontSize: "14px", padding: "6px 12px" },
195
+ children: isOnline ? "🟢 ACTIVE" : "⚫ OFFLINE"
196
+ }
197
+ ),
198
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", textColor: isOnline ? "success700" : "neutral700", children: [
199
+ sessions.length,
200
+ " active session",
201
+ sessions.length !== 1 ? "s" : ""
202
+ ] })
203
+ ] })
204
+ }
205
+ ),
206
+ isBlocked && /* @__PURE__ */ jsxRuntime.jsxs(
207
+ designSystem.Box,
208
+ {
209
+ padding: 4,
210
+ background: "danger100",
211
+ hasRadius: true,
212
+ children: [
213
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", textColor: "danger700", marginBottom: 1, children: "User is blocked" }),
214
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "danger600", children: "Authentication disabled" })
215
+ ]
216
+ }
217
+ ),
218
+ sessions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, alignItems: "stretch", children: [
219
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: {
220
+ textAlign: "left",
221
+ letterSpacing: "0.5px",
222
+ fontSize: "12px"
223
+ }, children: "Active Sessions" }),
224
+ sessions.slice(0, 5).map((session) => {
225
+ const deviceInfo = parseUserAgent(session.userAgent);
226
+ const DeviceIcon = getDeviceIcon(deviceInfo.device);
227
+ return /* @__PURE__ */ jsxRuntime.jsx(
228
+ designSystem.Box,
229
+ {
230
+ padding: 4,
231
+ background: "neutral0",
232
+ hasRadius: true,
233
+ style: {
234
+ border: "1px solid #e3e8ef",
235
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.04)",
236
+ transition: "all 0.2s ease"
237
+ },
238
+ onMouseEnter: (e) => {
239
+ e.currentTarget.style.boxShadow = "0 4px 12px rgba(0, 0, 0, 0.08)";
240
+ e.currentTarget.style.borderColor = "#4945FF";
241
+ },
242
+ onMouseLeave: (e) => {
243
+ e.currentTarget.style.boxShadow = "0 1px 3px rgba(0, 0, 0, 0.04)";
244
+ e.currentTarget.style.borderColor = "#e3e8ef";
245
+ },
246
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, alignItems: "flex-start", children: [
247
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
248
+ /* @__PURE__ */ jsxRuntime.jsx(DeviceIcon, { width: "20px", height: "20px" }),
249
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", textColor: "neutral800", children: deviceInfo.device })
250
+ ] }),
251
+ /* @__PURE__ */ jsxRuntime.jsx(
252
+ designSystem.Badge,
253
+ {
254
+ backgroundColor: "success600",
255
+ textColor: "neutral0",
256
+ size: "S",
257
+ children: "Active"
258
+ }
259
+ ),
260
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: [
261
+ deviceInfo.browser,
262
+ " on ",
263
+ deviceInfo.os
264
+ ] }),
265
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}),
266
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
267
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Server, { width: "14px", height: "14px" }),
268
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: session.ipAddress })
269
+ ] }),
270
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
271
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, { width: "14px", height: "14px" }),
272
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: new Date(session.loginTime).toLocaleString("en-US", {
273
+ month: "short",
274
+ day: "numeric",
275
+ hour: "2-digit",
276
+ minute: "2-digit"
277
+ }) })
278
+ ] }),
279
+ session.minutesSinceActive !== void 0 && session.minutesSinceActive < 60 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "success600", fontWeight: "semiBold", children: [
280
+ "Active ",
281
+ session.minutesSinceActive === 0 ? "now" : `${session.minutesSinceActive} min ago`
282
+ ] })
283
+ ] })
284
+ },
285
+ session.id
286
+ );
287
+ }),
288
+ sessions.length > 5 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 3, background: "primary100", hasRadius: true, textAlign: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "primary600", fontWeight: "semiBold", children: [
289
+ "+",
290
+ sessions.length - 5,
291
+ " more session",
292
+ sessions.length - 5 !== 1 ? "s" : ""
293
+ ] }) })
294
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
295
+ designSystem.Box,
296
+ {
297
+ padding: 6,
298
+ background: "neutral100",
299
+ hasRadius: true,
300
+ style: {
301
+ border: "1px dashed #dcdce4",
302
+ textAlign: "center"
303
+ },
304
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
305
+ /* @__PURE__ */ jsxRuntime.jsx(
306
+ designSystem.Typography,
307
+ {
308
+ variant: "pi",
309
+ textColor: "neutral600",
310
+ style: { fontSize: "32px", marginBottom: "8px" },
311
+ children: "💤"
312
+ }
313
+ ),
314
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", textColor: "neutral700", children: "No active sessions" }),
315
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", style: { fontSize: "13px" }, children: "User has not logged in yet" })
316
+ ] })
317
+ }
318
+ ),
319
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}),
320
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, alignItems: "stretch", children: [
321
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: {
322
+ textAlign: "left",
323
+ letterSpacing: "0.5px",
324
+ fontSize: "12px"
325
+ }, children: "Actions" }),
326
+ /* @__PURE__ */ jsxRuntime.jsx(
327
+ designSystem.Button,
328
+ {
329
+ variant: "secondary",
330
+ size: "M",
331
+ fullWidth: true,
332
+ onClick: handleLogoutAll,
333
+ disabled: actionLoading || sessions.length === 0,
334
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
335
+ style: {
336
+ border: "1px solid #dc2626",
337
+ color: "#dc2626",
338
+ backgroundColor: "transparent",
339
+ transition: "all 0.2s ease"
340
+ },
341
+ onMouseEnter: (e) => {
342
+ if (!actionLoading && sessions.length > 0) {
343
+ e.currentTarget.style.backgroundColor = "#dc2626";
344
+ e.currentTarget.style.color = "white";
345
+ }
346
+ },
347
+ onMouseLeave: (e) => {
348
+ if (!actionLoading && sessions.length > 0) {
349
+ e.currentTarget.style.backgroundColor = "transparent";
350
+ e.currentTarget.style.color = "#dc2626";
351
+ }
352
+ },
353
+ children: "Terminate All Sessions"
354
+ }
355
+ ),
356
+ /* @__PURE__ */ jsxRuntime.jsx(
357
+ designSystem.Button,
358
+ {
359
+ variant: "secondary",
360
+ size: "M",
361
+ fullWidth: true,
362
+ onClick: handleToggleBlock,
363
+ disabled: actionLoading,
364
+ startIcon: isBlocked ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
365
+ style: {
366
+ border: isBlocked ? "1px solid #16a34a" : "1px solid #dc2626",
367
+ color: isBlocked ? "#16a34a" : "#dc2626",
368
+ backgroundColor: "transparent",
369
+ transition: "all 0.2s ease"
370
+ },
371
+ onMouseEnter: (e) => {
372
+ if (!actionLoading) {
373
+ e.currentTarget.style.backgroundColor = isBlocked ? "#16a34a" : "#dc2626";
374
+ e.currentTarget.style.color = "white";
375
+ }
376
+ },
377
+ onMouseLeave: (e) => {
378
+ if (!actionLoading) {
379
+ e.currentTarget.style.backgroundColor = "transparent";
380
+ e.currentTarget.style.color = isBlocked ? "#16a34a" : "#dc2626";
381
+ }
382
+ },
383
+ children: isBlocked ? "Unblock User" : "Block User"
384
+ }
385
+ )
386
+ ] })
387
+ ] }) })
388
+ };
389
+ };
390
+ const prefixPluginTranslations = (data, pluginId2) => {
391
+ const prefixed = {};
392
+ Object.keys(data).forEach((key) => {
393
+ prefixed[`${pluginId2}.${key}`] = data[key];
394
+ });
395
+ return prefixed;
396
+ };
397
+ const name = pluginPkg.strapi.name;
398
+ const index = {
399
+ register(app) {
400
+ app.addMenuLink({
401
+ to: `/plugins/${pluginId}`,
402
+ icon: PluginIcon,
403
+ intlLabel: {
404
+ id: `${pluginId}.plugin.name`,
405
+ defaultMessage: pluginPkg.strapi.displayName
406
+ },
407
+ Component: () => Promise.resolve().then(() => require("./App-DUVizmi_.js"))
408
+ });
409
+ app.createSettingSection(
410
+ {
411
+ intlLabel: { id: `${pluginId}.settings.section`, defaultMessage: "Sessions" },
412
+ id: pluginId,
413
+ to: `/settings/${pluginId}`
414
+ },
415
+ [
416
+ {
417
+ intlLabel: {
418
+ id: `${pluginId}.settings.general`,
419
+ defaultMessage: "General"
420
+ },
421
+ id: "general",
422
+ to: `/settings/${pluginId}/general`,
423
+ Component: () => Promise.resolve().then(() => require("./Settings-L1ryVQMS.js"))
424
+ },
425
+ {
426
+ intlLabel: {
427
+ id: `${pluginId}.settings.analytics`,
428
+ defaultMessage: "Analytics"
429
+ },
430
+ id: "analytics",
431
+ to: `/settings/${pluginId}/analytics`,
432
+ Component: () => Promise.resolve().then(() => require("./Analytics-BSvvI-Hg.js"))
433
+ },
434
+ {
435
+ intlLabel: {
436
+ id: `${pluginId}.settings.license`,
437
+ defaultMessage: "License"
438
+ },
439
+ id: "license",
440
+ to: `/settings/${pluginId}/license`,
441
+ Component: () => Promise.resolve().then(() => require("./License-BI7jDjPV.js"))
442
+ }
443
+ ]
444
+ );
445
+ app.registerPlugin({
446
+ id: pluginId,
447
+ initializer: Initializer,
448
+ isReady: true,
449
+ name
450
+ });
451
+ if ("widgets" in app) {
452
+ app.widgets.register({
453
+ icon: PluginIcon,
454
+ title: {
455
+ id: `${pluginId}.widget.online-users.title`,
456
+ defaultMessage: "Online Users"
457
+ },
458
+ component: async () => {
459
+ const component = await Promise.resolve().then(() => require("./OnlineUsersWidget-B8JS1xZu.js"));
460
+ return component.default;
461
+ },
462
+ id: "online-users-widget",
463
+ pluginId
464
+ });
465
+ console.log(`[${pluginId}] ✅ Online Users Widget registered`);
466
+ }
467
+ },
468
+ bootstrap(app) {
469
+ console.log(`[${pluginId}] Bootstrapping plugin...`);
470
+ try {
471
+ const contentManagerPlugin = app.getPlugin("content-manager");
472
+ if (contentManagerPlugin && contentManagerPlugin.apis) {
473
+ console.log(`[${pluginId}] Injecting SessionInfoPanel into edit view sidebar...`);
474
+ contentManagerPlugin.apis.addEditViewSidePanel([SessionInfoPanel]);
475
+ console.log(`[${pluginId}] ✅ SessionInfoPanel injected successfully`);
476
+ } else {
477
+ console.warn(`[${pluginId}] Content Manager plugin or APIs not available`);
478
+ }
479
+ } catch (error) {
480
+ console.error(`[${pluginId}] Error injecting SessionInfoPanel:`, error);
481
+ }
482
+ },
483
+ async registerTrads({ locales }) {
484
+ const importedTrads = {
485
+ en: () => Promise.resolve().then(() => require("./en-RqmpDHdS.js")),
486
+ de: () => Promise.resolve().then(() => require("./de-BxFx1pwE.js"))
487
+ };
488
+ const translatedLanguages = Object.keys(importedTrads).filter(
489
+ (lang) => locales.includes(lang)
490
+ );
491
+ const translations = await Promise.all(
492
+ translatedLanguages.map(
493
+ (language) => importedTrads[language]().then(({ default: data }) => ({
494
+ data: prefixPluginTranslations(data, pluginId),
495
+ locale: language
496
+ })).catch(() => ({
497
+ data: {},
498
+ locale: language
499
+ }))
500
+ )
501
+ );
502
+ return Promise.resolve(translations);
503
+ }
504
+ };
505
+ exports.index = index;
506
+ exports.parseUserAgent = parseUserAgent;
507
+ exports.pluginId = pluginId;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ const react = require("react");
3
+ const admin = require("@strapi/strapi/admin");
4
+ const index = require("./index-Dd_SkI79.js");
5
+ const useLicense = () => {
6
+ const { get } = admin.useFetchClient();
7
+ const [isPremium, setIsPremium] = react.useState(false);
8
+ const [isAdvanced, setIsAdvanced] = react.useState(false);
9
+ const [isEnterprise, setIsEnterprise] = react.useState(false);
10
+ const [loading, setLoading] = react.useState(true);
11
+ const [error, setError] = react.useState(null);
12
+ const [licenseData, setLicenseData] = react.useState(null);
13
+ react.useEffect(() => {
14
+ checkLicense();
15
+ const interval = setInterval(() => {
16
+ checkLicense(true);
17
+ }, 60 * 60 * 1e3);
18
+ return () => clearInterval(interval);
19
+ }, []);
20
+ const checkLicense = async (silent = false) => {
21
+ if (!silent) {
22
+ setLoading(true);
23
+ }
24
+ try {
25
+ const response = await get(`/${index.pluginId}/license/status`);
26
+ if (!silent) {
27
+ console.log("[magic-sessionmanager/useLicense] Full API Response:", response.data);
28
+ console.log("[magic-sessionmanager/useLicense] License Details:", {
29
+ valid: response.data?.valid,
30
+ demo: response.data?.demo,
31
+ licenseKey: response.data?.data?.licenseKey?.substring(0, 13) + "...",
32
+ email: response.data?.data?.email,
33
+ features: response.data?.data?.features,
34
+ rawFeaturePremium: response.data?.data?.features?.premium
35
+ });
36
+ }
37
+ const isValid = response.data?.valid || false;
38
+ const hasPremiumFeature = response.data?.data?.features?.premium || false;
39
+ const hasAdvancedFeature = response.data?.data?.features?.advanced || false;
40
+ const hasEnterpriseFeature = response.data?.data?.features?.enterprise || false;
41
+ const newIsPremium = isValid && hasPremiumFeature;
42
+ const newIsAdvanced = isValid && hasAdvancedFeature;
43
+ const newIsEnterprise = isValid && hasEnterpriseFeature;
44
+ if ((newIsPremium !== isPremium || !silent) && !silent) {
45
+ console.log(`[magic-sessionmanager/useLicense] Premium Status: ${newIsPremium} (valid: ${isValid}, featurePremium: ${hasPremiumFeature})`);
46
+ if (!newIsPremium && isValid) {
47
+ console.warn("[magic-sessionmanager/useLicense] ⚠️ License is valid but Premium feature is not enabled!");
48
+ }
49
+ }
50
+ setIsPremium(newIsPremium);
51
+ setIsAdvanced(newIsAdvanced);
52
+ setIsEnterprise(newIsEnterprise);
53
+ setLicenseData(response.data?.data || null);
54
+ setError(null);
55
+ } catch (err) {
56
+ if (!silent) {
57
+ console.error("[useLicense] Error checking license:", err);
58
+ }
59
+ setIsPremium(false);
60
+ setIsAdvanced(false);
61
+ setIsEnterprise(false);
62
+ setLicenseData(null);
63
+ setError(err);
64
+ } finally {
65
+ if (!silent) {
66
+ setLoading(false);
67
+ }
68
+ }
69
+ };
70
+ return {
71
+ isPremium,
72
+ isAdvanced,
73
+ isEnterprise,
74
+ loading,
75
+ error,
76
+ licenseData,
77
+ features: {
78
+ premium: isPremium,
79
+ advanced: isAdvanced,
80
+ enterprise: isEnterprise
81
+ },
82
+ refetch: checkLicense
83
+ };
84
+ };
85
+ exports.useLicense = useLicense;
@@ -0,0 +1,86 @@
1
+ import { useState, useEffect } from "react";
2
+ import { useFetchClient } from "@strapi/strapi/admin";
3
+ import { a as pluginId } from "./index-BGCs2pNv.mjs";
4
+ const useLicense = () => {
5
+ const { get } = useFetchClient();
6
+ const [isPremium, setIsPremium] = useState(false);
7
+ const [isAdvanced, setIsAdvanced] = useState(false);
8
+ const [isEnterprise, setIsEnterprise] = useState(false);
9
+ const [loading, setLoading] = useState(true);
10
+ const [error, setError] = useState(null);
11
+ const [licenseData, setLicenseData] = useState(null);
12
+ useEffect(() => {
13
+ checkLicense();
14
+ const interval = setInterval(() => {
15
+ checkLicense(true);
16
+ }, 60 * 60 * 1e3);
17
+ return () => clearInterval(interval);
18
+ }, []);
19
+ const checkLicense = async (silent = false) => {
20
+ if (!silent) {
21
+ setLoading(true);
22
+ }
23
+ try {
24
+ const response = await get(`/${pluginId}/license/status`);
25
+ if (!silent) {
26
+ console.log("[magic-sessionmanager/useLicense] Full API Response:", response.data);
27
+ console.log("[magic-sessionmanager/useLicense] License Details:", {
28
+ valid: response.data?.valid,
29
+ demo: response.data?.demo,
30
+ licenseKey: response.data?.data?.licenseKey?.substring(0, 13) + "...",
31
+ email: response.data?.data?.email,
32
+ features: response.data?.data?.features,
33
+ rawFeaturePremium: response.data?.data?.features?.premium
34
+ });
35
+ }
36
+ const isValid = response.data?.valid || false;
37
+ const hasPremiumFeature = response.data?.data?.features?.premium || false;
38
+ const hasAdvancedFeature = response.data?.data?.features?.advanced || false;
39
+ const hasEnterpriseFeature = response.data?.data?.features?.enterprise || false;
40
+ const newIsPremium = isValid && hasPremiumFeature;
41
+ const newIsAdvanced = isValid && hasAdvancedFeature;
42
+ const newIsEnterprise = isValid && hasEnterpriseFeature;
43
+ if ((newIsPremium !== isPremium || !silent) && !silent) {
44
+ console.log(`[magic-sessionmanager/useLicense] Premium Status: ${newIsPremium} (valid: ${isValid}, featurePremium: ${hasPremiumFeature})`);
45
+ if (!newIsPremium && isValid) {
46
+ console.warn("[magic-sessionmanager/useLicense] ⚠️ License is valid but Premium feature is not enabled!");
47
+ }
48
+ }
49
+ setIsPremium(newIsPremium);
50
+ setIsAdvanced(newIsAdvanced);
51
+ setIsEnterprise(newIsEnterprise);
52
+ setLicenseData(response.data?.data || null);
53
+ setError(null);
54
+ } catch (err) {
55
+ if (!silent) {
56
+ console.error("[useLicense] Error checking license:", err);
57
+ }
58
+ setIsPremium(false);
59
+ setIsAdvanced(false);
60
+ setIsEnterprise(false);
61
+ setLicenseData(null);
62
+ setError(err);
63
+ } finally {
64
+ if (!silent) {
65
+ setLoading(false);
66
+ }
67
+ }
68
+ };
69
+ return {
70
+ isPremium,
71
+ isAdvanced,
72
+ isEnterprise,
73
+ loading,
74
+ error,
75
+ licenseData,
76
+ features: {
77
+ premium: isPremium,
78
+ advanced: isAdvanced,
79
+ enterprise: isEnterprise
80
+ },
81
+ refetch: checkLicense
82
+ };
83
+ };
84
+ export {
85
+ useLicense as u
86
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ const index = require("../_chunks/index-Dd_SkI79.js");
3
+ module.exports = index.index;
@@ -0,0 +1,4 @@
1
+ import { i } from "../_chunks/index-BGCs2pNv.mjs";
2
+ export {
3
+ i as default
4
+ };