strapi-plugin-magic-mark 1.3.1 → 3.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.
- package/COPYRIGHT_NOTICE.txt +2 -2
- package/README.md +488 -209
- package/dist/_chunks/{App-CMSut1pt.js → App-C5UU0yUr.js} +2 -2
- package/dist/_chunks/{App-7ZH1Reka.mjs → App-Dt-v39BQ.mjs} +3 -3
- package/dist/_chunks/{index-DYHEyGJr.mjs → index-BAmZV8aX.mjs} +1 -1
- package/dist/_chunks/{index-DkkmdRgb.js → index-RuDV4dTy.js} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +265 -184
- package/dist/server/index.mjs +260 -179
- package/dist/server/src/content-types/index.d.ts +10 -0
- package/dist/server/src/controllers/controller.d.ts +38 -0
- package/dist/server/src/index.d.ts +20 -22
- package/dist/server/src/services/index.d.ts +10 -22
- package/dist/server/src/services/service.d.ts +67 -22
- package/package.json +4 -4
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const crypto = require("crypto");
|
|
3
3
|
const os = require("os");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
4
6
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
5
7
|
const crypto__default = /* @__PURE__ */ _interopDefault(crypto);
|
|
6
8
|
const os__default = /* @__PURE__ */ _interopDefault(os);
|
|
@@ -36,7 +38,7 @@ const bootstrap = ({ strapi }) => {
|
|
|
36
38
|
const licenseStatus = await licenseGuardService2.initialize();
|
|
37
39
|
if (!licenseStatus.valid) {
|
|
38
40
|
strapi.log.error("╔════════════════════════════════════════════════════════════════╗");
|
|
39
|
-
strapi.log.error("║
|
|
41
|
+
strapi.log.error("║ [ERROR] MAGICMARK PLUGIN - NO VALID LICENSE ║");
|
|
40
42
|
strapi.log.error("║ ║");
|
|
41
43
|
strapi.log.error("║ This plugin requires a valid license to operate. ║");
|
|
42
44
|
strapi.log.error("║ Please activate your license via Admin UI: ║");
|
|
@@ -52,7 +54,7 @@ const bootstrap = ({ strapi }) => {
|
|
|
52
54
|
});
|
|
53
55
|
const storedKey = await pluginStore.get({ key: "licenseKey" });
|
|
54
56
|
strapi.log.info("╔════════════════════════════════════════════════════════════════╗");
|
|
55
|
-
strapi.log.info("║
|
|
57
|
+
strapi.log.info("║ [SUCCESS] MAGICMARK PLUGIN LICENSE ACTIVE ║");
|
|
56
58
|
strapi.log.info("║ ║");
|
|
57
59
|
if (licenseStatus.data) {
|
|
58
60
|
strapi.log.info(`║ License: ${licenseStatus.data.licenseKey} ║`);
|
|
@@ -63,12 +65,12 @@ const bootstrap = ({ strapi }) => {
|
|
|
63
65
|
strapi.log.info(`║ Status: Grace Period Active ║`);
|
|
64
66
|
}
|
|
65
67
|
strapi.log.info("║ ║");
|
|
66
|
-
strapi.log.info("║
|
|
68
|
+
strapi.log.info("║ [PING] Auto-pinging every 15 minutes ║");
|
|
67
69
|
strapi.log.info("╚════════════════════════════════════════════════════════════════╝");
|
|
68
70
|
}
|
|
69
71
|
}, 3e3);
|
|
70
72
|
} catch (error) {
|
|
71
|
-
strapi.log.error("
|
|
73
|
+
strapi.log.error("[ERROR] Error initializing License Guard:", error);
|
|
72
74
|
}
|
|
73
75
|
strapi.log.info("[Magic-Mark] Plugin bootstrapped successfully");
|
|
74
76
|
};
|
|
@@ -77,10 +79,10 @@ const destroy = ({ strapi }) => {
|
|
|
77
79
|
const licenseGuardService2 = strapi.plugin("magic-mark")?.service("license-guard");
|
|
78
80
|
if (licenseGuardService2) {
|
|
79
81
|
licenseGuardService2.cleanup();
|
|
80
|
-
strapi.log.info("
|
|
82
|
+
strapi.log.info("[SUCCESS] License Guard cleanup completed");
|
|
81
83
|
}
|
|
82
84
|
} catch (error) {
|
|
83
|
-
strapi.log.error("
|
|
85
|
+
strapi.log.error("[ERROR] Error during License Guard cleanup:", error);
|
|
84
86
|
}
|
|
85
87
|
};
|
|
86
88
|
const config = {
|
|
@@ -129,9 +131,9 @@ const contentTypes = {
|
|
|
129
131
|
},
|
|
130
132
|
emoji: {
|
|
131
133
|
type: "string",
|
|
132
|
-
default: "
|
|
134
|
+
default: "bookmark",
|
|
133
135
|
configurable: false,
|
|
134
|
-
maxLength:
|
|
136
|
+
maxLength: 50
|
|
135
137
|
},
|
|
136
138
|
isPinned: {
|
|
137
139
|
type: "boolean",
|
|
@@ -147,17 +149,30 @@ const contentTypes = {
|
|
|
147
149
|
type: "text",
|
|
148
150
|
configurable: false
|
|
149
151
|
},
|
|
150
|
-
//
|
|
152
|
+
// Creator's documentId (stored as string, not relation)
|
|
153
|
+
// We store documentId instead of relation to avoid admin::user permission issues
|
|
154
|
+
creatorId: {
|
|
155
|
+
type: "string",
|
|
156
|
+
configurable: false,
|
|
157
|
+
description: "documentId of the admin user who created this bookmark"
|
|
158
|
+
},
|
|
159
|
+
// Last updater's documentId
|
|
160
|
+
updaterId: {
|
|
161
|
+
type: "string",
|
|
162
|
+
configurable: false,
|
|
163
|
+
description: "documentId of the admin user who last updated this bookmark"
|
|
164
|
+
},
|
|
165
|
+
// Array of role documentIds that have access to this bookmark
|
|
151
166
|
sharedWithRoles: {
|
|
152
167
|
type: "json",
|
|
153
168
|
configurable: false,
|
|
154
|
-
description: "Array of role
|
|
169
|
+
description: "Array of role documentIds that have access to this bookmark"
|
|
155
170
|
},
|
|
156
|
-
// Array of user
|
|
171
|
+
// Array of user documentIds that have direct access to this bookmark
|
|
157
172
|
sharedWithUsers: {
|
|
158
173
|
type: "json",
|
|
159
174
|
configurable: false,
|
|
160
|
-
description: "Array of user
|
|
175
|
+
description: "Array of user documentIds that have direct access to this bookmark"
|
|
161
176
|
},
|
|
162
177
|
// Whether this bookmark is public to all admin users
|
|
163
178
|
isPublic: {
|
|
@@ -170,14 +185,21 @@ const contentTypes = {
|
|
|
170
185
|
}
|
|
171
186
|
}
|
|
172
187
|
};
|
|
188
|
+
const ADMIN_ROLE_UID = "admin::role";
|
|
189
|
+
const ADMIN_USER_UID$1 = "admin::user";
|
|
173
190
|
const bookmarkController = ({ strapi }) => ({
|
|
191
|
+
/**
|
|
192
|
+
* Get all bookmarks for current user
|
|
193
|
+
* GET /magic-mark/bookmarks
|
|
194
|
+
*/
|
|
174
195
|
async getAll(ctx) {
|
|
175
196
|
try {
|
|
176
197
|
const user = ctx.state.user;
|
|
177
198
|
if (!user) {
|
|
178
199
|
return ctx.throw(401, "User not authenticated");
|
|
179
200
|
}
|
|
180
|
-
const
|
|
201
|
+
const userId = user.documentId || String(user.id);
|
|
202
|
+
const bookmarks = await strapi.plugin("magic-mark").service("bookmarks").findAll(userId);
|
|
181
203
|
ctx.body = {
|
|
182
204
|
data: bookmarks,
|
|
183
205
|
meta: {
|
|
@@ -188,21 +210,26 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
188
210
|
ctx.throw(500, `Error fetching bookmarks: ${error}`);
|
|
189
211
|
}
|
|
190
212
|
},
|
|
213
|
+
/**
|
|
214
|
+
* Create a new bookmark
|
|
215
|
+
* POST /magic-mark/bookmarks
|
|
216
|
+
*/
|
|
191
217
|
async create(ctx) {
|
|
192
218
|
try {
|
|
193
219
|
const user = ctx.state.user;
|
|
194
220
|
if (!user) {
|
|
195
221
|
return ctx.throw(401, "User not authenticated");
|
|
196
222
|
}
|
|
197
|
-
const { name, path, query, emoji, description, sharedWithRoles, sharedWithUsers, isPublic } = ctx.request.body;
|
|
223
|
+
const { name, path: path2, query, emoji, description, sharedWithRoles, sharedWithUsers, isPublic } = ctx.request.body;
|
|
198
224
|
if (!name || name.trim().length === 0) {
|
|
199
225
|
return ctx.throw(400, "Name is required");
|
|
200
226
|
}
|
|
201
|
-
if (!
|
|
227
|
+
if (!path2 || path2.trim().length === 0) {
|
|
202
228
|
return ctx.throw(400, "Path is required");
|
|
203
229
|
}
|
|
230
|
+
const userId = user.documentId || String(user.id);
|
|
204
231
|
const service = strapi.plugin("magic-mark").service("bookmarks");
|
|
205
|
-
const bookmark = await service.create(name,
|
|
232
|
+
const bookmark = await service.create(name, path2, query, emoji, description, userId, sharedWithRoles, sharedWithUsers, isPublic);
|
|
206
233
|
ctx.body = {
|
|
207
234
|
data: bookmark
|
|
208
235
|
};
|
|
@@ -210,6 +237,10 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
210
237
|
ctx.throw(500, `Error creating bookmark: ${error}`);
|
|
211
238
|
}
|
|
212
239
|
},
|
|
240
|
+
/**
|
|
241
|
+
* Update an existing bookmark
|
|
242
|
+
* PUT /magic-mark/bookmarks/:id
|
|
243
|
+
*/
|
|
213
244
|
async update(ctx) {
|
|
214
245
|
try {
|
|
215
246
|
const user = ctx.state.user;
|
|
@@ -217,14 +248,15 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
217
248
|
return ctx.throw(401, "User not authenticated");
|
|
218
249
|
}
|
|
219
250
|
const { id } = ctx.params;
|
|
220
|
-
const { name, path, query, emoji, description, isPinned, order, sharedWithRoles, sharedWithUsers, isPublic } = ctx.request.body;
|
|
251
|
+
const { name, path: path2, query, emoji, description, isPinned, order, sharedWithRoles, sharedWithUsers, isPublic } = ctx.request.body;
|
|
221
252
|
if (!name || name.trim().length === 0) {
|
|
222
253
|
return ctx.throw(400, "Name is required");
|
|
223
254
|
}
|
|
224
|
-
if (!
|
|
255
|
+
if (!path2 || path2.trim().length === 0) {
|
|
225
256
|
return ctx.throw(400, "Path is required");
|
|
226
257
|
}
|
|
227
|
-
const
|
|
258
|
+
const userId = user.documentId || String(user.id);
|
|
259
|
+
const bookmark = await strapi.plugin("magic-mark").service("bookmarks").update(id, { name, path: path2, query, emoji, description, isPinned, order, sharedWithRoles, sharedWithUsers, isPublic }, userId);
|
|
228
260
|
ctx.body = {
|
|
229
261
|
data: bookmark
|
|
230
262
|
};
|
|
@@ -232,6 +264,10 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
232
264
|
ctx.throw(500, `Error updating bookmark: ${error}`);
|
|
233
265
|
}
|
|
234
266
|
},
|
|
267
|
+
/**
|
|
268
|
+
* Delete a bookmark
|
|
269
|
+
* DELETE /magic-mark/bookmarks/:id
|
|
270
|
+
*/
|
|
235
271
|
async delete(ctx) {
|
|
236
272
|
try {
|
|
237
273
|
const user = ctx.state.user;
|
|
@@ -247,6 +283,10 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
247
283
|
ctx.throw(500, `Error deleting bookmark: ${error}`);
|
|
248
284
|
}
|
|
249
285
|
},
|
|
286
|
+
/**
|
|
287
|
+
* Pin or unpin a bookmark
|
|
288
|
+
* PUT /magic-mark/bookmarks/:id/pin
|
|
289
|
+
*/
|
|
250
290
|
async pin(ctx) {
|
|
251
291
|
try {
|
|
252
292
|
const user = ctx.state.user;
|
|
@@ -255,7 +295,8 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
255
295
|
}
|
|
256
296
|
const { id } = ctx.params;
|
|
257
297
|
const { isPinned } = ctx.request.body;
|
|
258
|
-
const
|
|
298
|
+
const userId = user.documentId || String(user.id);
|
|
299
|
+
const bookmark = await strapi.plugin("magic-mark").service("bookmarks").pin(id, isPinned, userId);
|
|
259
300
|
ctx.body = {
|
|
260
301
|
data: bookmark
|
|
261
302
|
};
|
|
@@ -263,6 +304,10 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
263
304
|
ctx.throw(500, `Error pinning bookmark: ${error}`);
|
|
264
305
|
}
|
|
265
306
|
},
|
|
307
|
+
/**
|
|
308
|
+
* Reorder bookmarks
|
|
309
|
+
* PUT /magic-mark/bookmarks/reorder
|
|
310
|
+
*/
|
|
266
311
|
async reorder(ctx) {
|
|
267
312
|
try {
|
|
268
313
|
const user = ctx.state.user;
|
|
@@ -273,7 +318,8 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
273
318
|
if (!bookmarkIds || !Array.isArray(bookmarkIds)) {
|
|
274
319
|
return ctx.throw(400, "Bookmark IDs array is required");
|
|
275
320
|
}
|
|
276
|
-
const
|
|
321
|
+
const userId = user.documentId || String(user.id);
|
|
322
|
+
const bookmarks = await strapi.plugin("magic-mark").service("bookmarks").reorder(bookmarkIds, userId);
|
|
277
323
|
ctx.body = {
|
|
278
324
|
data: bookmarks
|
|
279
325
|
};
|
|
@@ -281,30 +327,28 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
281
327
|
ctx.throw(500, `Error reordering bookmarks: ${error}`);
|
|
282
328
|
}
|
|
283
329
|
},
|
|
330
|
+
/**
|
|
331
|
+
* Get all admin roles for sharing
|
|
332
|
+
* GET /magic-mark/roles
|
|
333
|
+
*/
|
|
284
334
|
async getRoles(ctx) {
|
|
285
335
|
try {
|
|
286
336
|
const user = ctx.state.user;
|
|
287
337
|
if (!user) {
|
|
288
338
|
return ctx.throw(401, "User not authenticated");
|
|
289
339
|
}
|
|
290
|
-
const roles = await strapi.
|
|
291
|
-
"
|
|
292
|
-
{
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
sort: { name: "asc" },
|
|
296
|
-
populate: ["users"]
|
|
297
|
-
// Also get user count for each role
|
|
298
|
-
}
|
|
299
|
-
);
|
|
340
|
+
const roles = await strapi.documents(ADMIN_ROLE_UID).findMany({
|
|
341
|
+
fields: ["name", "code", "description", "createdAt", "updatedAt"],
|
|
342
|
+
sort: { name: "asc" },
|
|
343
|
+
populate: ["users"]
|
|
344
|
+
});
|
|
300
345
|
const rolesWithDetails = roles?.map((role) => ({
|
|
301
|
-
id: role.
|
|
346
|
+
id: role.documentId,
|
|
302
347
|
name: role.name,
|
|
303
348
|
code: role.code,
|
|
304
349
|
description: role.description,
|
|
305
350
|
userCount: role.users?.length || 0,
|
|
306
351
|
isCustom: !["super_admin", "editor", "author"].includes(role.code)
|
|
307
|
-
// Mark custom roles
|
|
308
352
|
})) || [];
|
|
309
353
|
ctx.body = {
|
|
310
354
|
data: {
|
|
@@ -315,6 +359,10 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
315
359
|
ctx.throw(500, `Error fetching roles: ${error}`);
|
|
316
360
|
}
|
|
317
361
|
},
|
|
362
|
+
/**
|
|
363
|
+
* Get all admin users for sharing
|
|
364
|
+
* GET /magic-mark/users
|
|
365
|
+
*/
|
|
318
366
|
async getUsers(ctx) {
|
|
319
367
|
try {
|
|
320
368
|
const user = ctx.state.user;
|
|
@@ -336,37 +384,36 @@ const bookmarkController = ({ strapi }) => ({
|
|
|
336
384
|
users = await adminUserService.find();
|
|
337
385
|
}
|
|
338
386
|
} catch (err) {
|
|
339
|
-
|
|
387
|
+
strapi.log.debug("[magic-mark] Admin service not available, trying Document Service");
|
|
340
388
|
}
|
|
341
389
|
if (!users || users.length === 0) {
|
|
342
390
|
try {
|
|
343
|
-
users = await strapi.
|
|
391
|
+
users = await strapi.documents(ADMIN_USER_UID$1).findMany({
|
|
344
392
|
limit: 100
|
|
345
393
|
});
|
|
346
394
|
} catch (err) {
|
|
347
|
-
|
|
395
|
+
strapi.log.debug("[magic-mark] Document Service error for admin::user");
|
|
348
396
|
}
|
|
349
397
|
}
|
|
350
398
|
if (!users || users.length === 0) {
|
|
351
399
|
try {
|
|
352
|
-
users = await strapi.
|
|
400
|
+
users = await strapi.entityService.findMany(ADMIN_USER_UID$1, {
|
|
353
401
|
limit: 100
|
|
354
402
|
});
|
|
355
403
|
} catch (err) {
|
|
356
|
-
|
|
404
|
+
strapi.log.warn("[magic-mark] entityService fallback also failed");
|
|
357
405
|
}
|
|
358
406
|
}
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
})));
|
|
407
|
+
const currentUserId = user.documentId || String(user.id);
|
|
408
|
+
const filteredUsers = users.filter((u) => {
|
|
409
|
+
const uId = u.documentId || String(u.id);
|
|
410
|
+
return uId !== currentUserId;
|
|
411
|
+
});
|
|
412
|
+
strapi.log.debug(`[magic-mark] Total admin users found: ${users.length}`);
|
|
366
413
|
ctx.body = {
|
|
367
414
|
data: {
|
|
368
415
|
data: filteredUsers.map((u) => ({
|
|
369
|
-
id: u.id,
|
|
416
|
+
id: u.documentId || u.id,
|
|
370
417
|
firstname: u.firstname || "",
|
|
371
418
|
lastname: u.lastname || "",
|
|
372
419
|
email: u.email,
|
|
@@ -544,16 +591,16 @@ const license = ({ strapi }) => ({
|
|
|
544
591
|
const licenseGuard = strapi.plugin("magic-mark").service("license-guard");
|
|
545
592
|
const verification = await licenseGuard.verifyLicense(trimmedKey);
|
|
546
593
|
if (!verification.valid) {
|
|
547
|
-
strapi.log.warn(
|
|
594
|
+
strapi.log.warn(`[WARN] Invalid license key attempted: ${trimmedKey.substring(0, 8)}...`);
|
|
548
595
|
return ctx.badRequest("Invalid or expired license key");
|
|
549
596
|
}
|
|
550
597
|
const license2 = await licenseGuard.getLicenseByKey(trimmedKey);
|
|
551
598
|
if (!license2) {
|
|
552
|
-
strapi.log.warn(
|
|
599
|
+
strapi.log.warn(`[WARN] License not found in database: ${trimmedKey.substring(0, 8)}...`);
|
|
553
600
|
return ctx.badRequest("License not found");
|
|
554
601
|
}
|
|
555
602
|
if (license2.email.toLowerCase() !== trimmedEmail) {
|
|
556
|
-
strapi.log.warn(
|
|
603
|
+
strapi.log.warn(`[WARN] Email mismatch for license key: ${trimmedKey.substring(0, 8)}... (Attempted: ${trimmedEmail})`);
|
|
557
604
|
return ctx.badRequest("Email address does not match this license key");
|
|
558
605
|
}
|
|
559
606
|
await licenseGuard.storeLicenseKey(trimmedKey);
|
|
@@ -563,7 +610,7 @@ const license = ({ strapi }) => ({
|
|
|
563
610
|
pingInterval,
|
|
564
611
|
data: verification.data
|
|
565
612
|
};
|
|
566
|
-
strapi.log.info(
|
|
613
|
+
strapi.log.info(`[SUCCESS] Existing license key validated and stored: ${trimmedKey.substring(0, 8)}... (Email: ${trimmedEmail})`);
|
|
567
614
|
return ctx.send({
|
|
568
615
|
success: true,
|
|
569
616
|
message: "License key validated and activated successfully",
|
|
@@ -724,12 +771,12 @@ const licenseCheck$1 = (config2, { strapi }) => {
|
|
|
724
771
|
});
|
|
725
772
|
const licenseKey = await pluginStore.get({ key: "licenseKey" });
|
|
726
773
|
if (!licenseKey) {
|
|
727
|
-
strapi.log.warn("
|
|
774
|
+
strapi.log.warn("[WARN] MagicMark: No license key found");
|
|
728
775
|
return await next();
|
|
729
776
|
}
|
|
730
777
|
const verification = await licenseGuard.verifyLicense(licenseKey, true);
|
|
731
778
|
if (!verification.valid && !verification.gracePeriod) {
|
|
732
|
-
strapi.log.warn("
|
|
779
|
+
strapi.log.warn("[WARN] MagicMark: Invalid license detected");
|
|
733
780
|
}
|
|
734
781
|
return await next();
|
|
735
782
|
} catch (error) {
|
|
@@ -747,25 +794,25 @@ const licenseCheck = async (policyContext, config2, { strapi }) => {
|
|
|
747
794
|
const pluginStore = strapi.store({ type: "plugin", name: "magic-mark" });
|
|
748
795
|
const licenseKey = await pluginStore.get({ key: "licenseKey" });
|
|
749
796
|
if (!licenseKey) {
|
|
750
|
-
strapi.log.warn("
|
|
797
|
+
strapi.log.warn("[WARN] API access denied: No license key found");
|
|
751
798
|
return policyContext.unauthorized("No license found. Please activate the plugin first.");
|
|
752
799
|
}
|
|
753
800
|
const verification = await licenseGuard.verifyLicense(licenseKey);
|
|
754
801
|
if (!verification.valid) {
|
|
755
|
-
strapi.log.warn("
|
|
802
|
+
strapi.log.warn("[WARN] API access denied: Invalid license");
|
|
756
803
|
return policyContext.unauthorized("Invalid or expired license. Please check your license status.");
|
|
757
804
|
}
|
|
758
805
|
const license2 = await licenseGuard.getLicenseByKey(licenseKey);
|
|
759
806
|
if (!license2) {
|
|
760
|
-
strapi.log.warn("
|
|
807
|
+
strapi.log.warn("[WARN] API access denied: License not found in database");
|
|
761
808
|
return policyContext.unauthorized("License not found. Please contact support.");
|
|
762
809
|
}
|
|
763
810
|
if (!license2.isActive) {
|
|
764
|
-
strapi.log.warn("
|
|
811
|
+
strapi.log.warn("[WARN] API access denied: License is inactive");
|
|
765
812
|
return policyContext.unauthorized("License is inactive. Please activate your license.");
|
|
766
813
|
}
|
|
767
814
|
if (license2.isExpired) {
|
|
768
|
-
strapi.log.warn("
|
|
815
|
+
strapi.log.warn("[WARN] API access denied: License has expired");
|
|
769
816
|
return policyContext.unauthorized("License has expired. Please renew your license.");
|
|
770
817
|
}
|
|
771
818
|
return true;
|
|
@@ -777,29 +824,29 @@ const licenseCheck = async (policyContext, config2, { strapi }) => {
|
|
|
777
824
|
const policies = {
|
|
778
825
|
"license-check": licenseCheck
|
|
779
826
|
};
|
|
827
|
+
const BOOKMARK_UID = "plugin::magic-mark.bookmark";
|
|
828
|
+
const ADMIN_USER_UID = "admin::user";
|
|
780
829
|
const bookmarkService = ({ strapi }) => ({
|
|
830
|
+
/**
|
|
831
|
+
* Find all bookmarks accessible to a user
|
|
832
|
+
* @param userId - The admin user's documentId
|
|
833
|
+
* @returns Array of accessible bookmarks
|
|
834
|
+
*/
|
|
781
835
|
async findAll(userId) {
|
|
782
836
|
try {
|
|
783
|
-
const user = await strapi.
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
sort: [
|
|
795
|
-
{ isPinned: "desc" },
|
|
796
|
-
{ order: "asc" }
|
|
797
|
-
],
|
|
798
|
-
populate: ["createdBy"]
|
|
799
|
-
}
|
|
800
|
-
);
|
|
837
|
+
const user = await strapi.documents(ADMIN_USER_UID).findOne({
|
|
838
|
+
documentId: userId,
|
|
839
|
+
populate: ["roles"]
|
|
840
|
+
});
|
|
841
|
+
const userRoleIds = user?.roles?.map((role) => role.documentId || role.id) || [];
|
|
842
|
+
const allBookmarks = await strapi.documents(BOOKMARK_UID).findMany({
|
|
843
|
+
sort: [
|
|
844
|
+
{ isPinned: "desc" },
|
|
845
|
+
{ order: "asc" }
|
|
846
|
+
]
|
|
847
|
+
});
|
|
801
848
|
const accessibleBookmarks = allBookmarks?.filter((bookmark) => {
|
|
802
|
-
if (bookmark.
|
|
849
|
+
if (bookmark.creatorId === userId) {
|
|
803
850
|
return true;
|
|
804
851
|
}
|
|
805
852
|
if (bookmark.isPublic) {
|
|
@@ -823,119 +870,140 @@ const bookmarkService = ({ strapi }) => ({
|
|
|
823
870
|
throw error;
|
|
824
871
|
}
|
|
825
872
|
},
|
|
826
|
-
|
|
873
|
+
/**
|
|
874
|
+
* Create a new bookmark
|
|
875
|
+
* @param name - Bookmark name
|
|
876
|
+
* @param path - URL path
|
|
877
|
+
* @param query - Query string
|
|
878
|
+
* @param emoji - Emoji icon
|
|
879
|
+
* @param description - Description
|
|
880
|
+
* @param userId - Creator's documentId
|
|
881
|
+
* @param sharedWithRoles - Array of role documentIds
|
|
882
|
+
* @param sharedWithUsers - Array of user documentIds
|
|
883
|
+
* @param isPublic - Public visibility
|
|
884
|
+
* @returns Created bookmark
|
|
885
|
+
*/
|
|
886
|
+
async create(name, path2, query, emoji, description, userId, sharedWithRoles, sharedWithUsers, isPublic) {
|
|
827
887
|
try {
|
|
828
|
-
const bookmarks = await strapi.
|
|
829
|
-
"
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
limit: 1
|
|
833
|
-
}
|
|
834
|
-
);
|
|
888
|
+
const bookmarks = await strapi.documents(BOOKMARK_UID).findMany({
|
|
889
|
+
sort: [{ order: "desc" }],
|
|
890
|
+
limit: 1
|
|
891
|
+
});
|
|
835
892
|
const maxOrder = bookmarks && bookmarks.length > 0 ? bookmarks[0].order : 0;
|
|
836
|
-
const bookmark = await strapi.
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
}
|
|
893
|
+
const bookmark = await strapi.documents(BOOKMARK_UID).create({
|
|
894
|
+
data: {
|
|
895
|
+
name,
|
|
896
|
+
path: path2,
|
|
897
|
+
query: query || "",
|
|
898
|
+
emoji: emoji || "bookmark",
|
|
899
|
+
description,
|
|
900
|
+
isPinned: false,
|
|
901
|
+
order: (maxOrder || 0) + 1,
|
|
902
|
+
creatorId: userId,
|
|
903
|
+
// Store as string field, not relation
|
|
904
|
+
updaterId: userId,
|
|
905
|
+
sharedWithRoles: sharedWithRoles || [],
|
|
906
|
+
sharedWithUsers: sharedWithUsers || [],
|
|
907
|
+
isPublic: isPublic || false
|
|
852
908
|
}
|
|
853
|
-
);
|
|
909
|
+
});
|
|
854
910
|
return bookmark;
|
|
855
911
|
} catch (error) {
|
|
856
912
|
strapi.log.error("[magic-mark] Error creating bookmark:", error);
|
|
857
913
|
throw error;
|
|
858
914
|
}
|
|
859
915
|
},
|
|
860
|
-
|
|
916
|
+
/**
|
|
917
|
+
* Update an existing bookmark
|
|
918
|
+
* @param documentId - Bookmark's documentId
|
|
919
|
+
* @param data - Update data
|
|
920
|
+
* @param userId - Editor's documentId
|
|
921
|
+
* @returns Updated bookmark
|
|
922
|
+
*/
|
|
923
|
+
async update(documentId, data, userId) {
|
|
861
924
|
try {
|
|
862
|
-
const existingBookmark = await strapi.
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
populate: ["createdBy"]
|
|
867
|
-
}
|
|
868
|
-
);
|
|
869
|
-
if (!existingBookmark || existingBookmark.createdBy?.id !== userId) {
|
|
925
|
+
const existingBookmark = await strapi.documents(BOOKMARK_UID).findOne({
|
|
926
|
+
documentId
|
|
927
|
+
});
|
|
928
|
+
if (!existingBookmark || existingBookmark.creatorId !== userId) {
|
|
870
929
|
throw new Error("Unauthorized: You can only edit your own bookmarks");
|
|
871
930
|
}
|
|
872
|
-
const bookmark = await strapi.
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
updatedBy: userId
|
|
888
|
-
}
|
|
931
|
+
const bookmark = await strapi.documents(BOOKMARK_UID).update({
|
|
932
|
+
documentId,
|
|
933
|
+
data: {
|
|
934
|
+
name: data.name,
|
|
935
|
+
path: data.path,
|
|
936
|
+
query: data.query || "",
|
|
937
|
+
emoji: data.emoji || "bookmark",
|
|
938
|
+
description: data.description,
|
|
939
|
+
isPinned: data.isPinned,
|
|
940
|
+
order: data.order,
|
|
941
|
+
sharedWithRoles: data.sharedWithRoles,
|
|
942
|
+
sharedWithUsers: data.sharedWithUsers,
|
|
943
|
+
isPublic: data.isPublic,
|
|
944
|
+
updaterId: userId
|
|
945
|
+
// Store as string field
|
|
889
946
|
}
|
|
890
|
-
);
|
|
947
|
+
});
|
|
891
948
|
return bookmark;
|
|
892
949
|
} catch (error) {
|
|
893
950
|
strapi.log.error("[magic-mark] Error updating bookmark:", error);
|
|
894
951
|
throw error;
|
|
895
952
|
}
|
|
896
953
|
},
|
|
897
|
-
|
|
954
|
+
/**
|
|
955
|
+
* Delete a bookmark
|
|
956
|
+
* @param documentId - Bookmark's documentId
|
|
957
|
+
* @returns Deleted bookmark
|
|
958
|
+
*/
|
|
959
|
+
async delete(documentId) {
|
|
898
960
|
try {
|
|
899
|
-
return await strapi.
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
);
|
|
961
|
+
return await strapi.documents(BOOKMARK_UID).delete({
|
|
962
|
+
documentId
|
|
963
|
+
});
|
|
903
964
|
} catch (error) {
|
|
904
965
|
strapi.log.error("[magic-mark] Error deleting bookmark:", error);
|
|
905
966
|
throw error;
|
|
906
967
|
}
|
|
907
968
|
},
|
|
908
|
-
|
|
969
|
+
/**
|
|
970
|
+
* Pin or unpin a bookmark
|
|
971
|
+
* @param documentId - Bookmark's documentId
|
|
972
|
+
* @param isPinned - Pin status
|
|
973
|
+
* @param userId - Editor's documentId
|
|
974
|
+
* @returns Updated bookmark
|
|
975
|
+
*/
|
|
976
|
+
async pin(documentId, isPinned, userId) {
|
|
909
977
|
try {
|
|
910
|
-
const bookmark = await strapi.
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
isPinned,
|
|
916
|
-
updatedBy: userId
|
|
917
|
-
}
|
|
978
|
+
const bookmark = await strapi.documents(BOOKMARK_UID).update({
|
|
979
|
+
documentId,
|
|
980
|
+
data: {
|
|
981
|
+
isPinned,
|
|
982
|
+
updaterId: userId
|
|
918
983
|
}
|
|
919
|
-
);
|
|
984
|
+
});
|
|
920
985
|
return bookmark;
|
|
921
986
|
} catch (error) {
|
|
922
987
|
strapi.log.error("[magic-mark] Error pinning bookmark:", error);
|
|
923
988
|
throw error;
|
|
924
989
|
}
|
|
925
990
|
},
|
|
991
|
+
/**
|
|
992
|
+
* Reorder bookmarks
|
|
993
|
+
* @param bookmarkIds - Array of bookmark documentIds in new order
|
|
994
|
+
* @param userId - Editor's documentId
|
|
995
|
+
* @returns Updated bookmarks
|
|
996
|
+
*/
|
|
926
997
|
async reorder(bookmarkIds, userId) {
|
|
927
998
|
try {
|
|
928
999
|
const updates = bookmarkIds.map(
|
|
929
|
-
(
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
order: index2,
|
|
935
|
-
updatedBy: userId
|
|
936
|
-
}
|
|
1000
|
+
(documentId, index2) => strapi.documents(BOOKMARK_UID).update({
|
|
1001
|
+
documentId,
|
|
1002
|
+
data: {
|
|
1003
|
+
order: index2,
|
|
1004
|
+
updaterId: userId
|
|
937
1005
|
}
|
|
938
|
-
)
|
|
1006
|
+
})
|
|
939
1007
|
);
|
|
940
1008
|
return Promise.all(updates);
|
|
941
1009
|
} catch (error) {
|
|
@@ -943,6 +1011,11 @@ const bookmarkService = ({ strapi }) => ({
|
|
|
943
1011
|
throw error;
|
|
944
1012
|
}
|
|
945
1013
|
},
|
|
1014
|
+
/**
|
|
1015
|
+
* Validate URL format
|
|
1016
|
+
* @param url - URL to validate
|
|
1017
|
+
* @returns True if valid
|
|
1018
|
+
*/
|
|
946
1019
|
validateUrl(url) {
|
|
947
1020
|
try {
|
|
948
1021
|
new URL(url);
|
|
@@ -952,6 +1025,13 @@ const bookmarkService = ({ strapi }) => ({
|
|
|
952
1025
|
}
|
|
953
1026
|
}
|
|
954
1027
|
});
|
|
1028
|
+
let pluginVersion = "2.0.0";
|
|
1029
|
+
try {
|
|
1030
|
+
const pkgPath = path.join(__dirname, "../../../package.json");
|
|
1031
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
1032
|
+
pluginVersion = pkg.version || "2.0.0";
|
|
1033
|
+
} catch (e) {
|
|
1034
|
+
}
|
|
955
1035
|
const LICENSE_SERVER_URL = "https://magicapi.fitlex.me";
|
|
956
1036
|
const licenseGuardService = ({ strapi }) => ({
|
|
957
1037
|
/**
|
|
@@ -1017,7 +1097,8 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1017
1097
|
* Get user agent (server context)
|
|
1018
1098
|
*/
|
|
1019
1099
|
getUserAgent() {
|
|
1020
|
-
|
|
1100
|
+
const strapiVersion = strapi.config.get("info.strapi") || "5.0.0";
|
|
1101
|
+
return `MagicMark/${pluginVersion} Strapi/${strapiVersion} Node/${process.version} ${os__default.default.platform()}/${os__default.default.release()}`;
|
|
1021
1102
|
},
|
|
1022
1103
|
/**
|
|
1023
1104
|
* Create a license
|
|
@@ -1048,14 +1129,14 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1048
1129
|
});
|
|
1049
1130
|
const data = await response.json();
|
|
1050
1131
|
if (data.success) {
|
|
1051
|
-
strapi.log.info("
|
|
1132
|
+
strapi.log.info("[SUCCESS] License created successfully:", data.data.licenseKey);
|
|
1052
1133
|
return data.data;
|
|
1053
1134
|
} else {
|
|
1054
|
-
strapi.log.error("
|
|
1135
|
+
strapi.log.error("[ERROR] License creation failed:", data);
|
|
1055
1136
|
return null;
|
|
1056
1137
|
}
|
|
1057
1138
|
} catch (error) {
|
|
1058
|
-
strapi.log.error("
|
|
1139
|
+
strapi.log.error("[ERROR] Error creating license:", error);
|
|
1059
1140
|
return null;
|
|
1060
1141
|
}
|
|
1061
1142
|
},
|
|
@@ -1084,7 +1165,7 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1084
1165
|
if (data.success) {
|
|
1085
1166
|
const isValid = data.data.isActive && !data.data.isExpired;
|
|
1086
1167
|
const statusInfo = data.data.isExpired ? "EXPIRED" : data.data.isActive ? "ACTIVE" : "INACTIVE";
|
|
1087
|
-
strapi.log.info(
|
|
1168
|
+
strapi.log.info(`[SUCCESS] License verified online: ${statusInfo} (Key: ${licenseKey?.substring(0, 8)}...)`);
|
|
1088
1169
|
if (isValid) {
|
|
1089
1170
|
const pluginStore = strapi.store({
|
|
1090
1171
|
type: "plugin",
|
|
@@ -1097,16 +1178,16 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1097
1178
|
data: data.data
|
|
1098
1179
|
};
|
|
1099
1180
|
} else {
|
|
1100
|
-
strapi.log.warn(
|
|
1181
|
+
strapi.log.warn(`[WARN] License verification failed: ${data.message || "Unknown error"} (Key: ${licenseKey?.substring(0, 8)}...)`);
|
|
1101
1182
|
return { valid: false, data: null };
|
|
1102
1183
|
}
|
|
1103
1184
|
} catch (error) {
|
|
1104
1185
|
if (allowGracePeriod) {
|
|
1105
|
-
strapi.log.warn(
|
|
1106
|
-
strapi.log.info(
|
|
1186
|
+
strapi.log.warn(`[WARN] Cannot verify license online: ${error.message} (Key: ${licenseKey?.substring(0, 8)}...)`);
|
|
1187
|
+
strapi.log.info(`[GRACE] Grace period active - accepting stored license key`);
|
|
1107
1188
|
return { valid: true, data: null, gracePeriod: true };
|
|
1108
1189
|
}
|
|
1109
|
-
strapi.log.error(
|
|
1190
|
+
strapi.log.error(`[ERROR] Error verifying license: ${error.message} (Key: ${licenseKey?.substring(0, 8)}...)`);
|
|
1110
1191
|
return { valid: false, data: null };
|
|
1111
1192
|
}
|
|
1112
1193
|
},
|
|
@@ -1129,10 +1210,10 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1129
1210
|
});
|
|
1130
1211
|
const data = await response.json();
|
|
1131
1212
|
if (data.success) {
|
|
1132
|
-
strapi.log.debug(
|
|
1213
|
+
strapi.log.debug(`[PING] License ping successful: ${data.data?.isActive ? "ACTIVE" : "INACTIVE"} (Key: ${licenseKey?.substring(0, 8)}...)`);
|
|
1133
1214
|
return data.data;
|
|
1134
1215
|
} else {
|
|
1135
|
-
strapi.log.debug(
|
|
1216
|
+
strapi.log.debug(`[WARN] License ping failed: ${data.message || "Unknown error"} (Key: ${licenseKey?.substring(0, 8)}...)`);
|
|
1136
1217
|
return null;
|
|
1137
1218
|
}
|
|
1138
1219
|
} catch (error) {
|
|
@@ -1153,7 +1234,7 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1153
1234
|
}
|
|
1154
1235
|
return null;
|
|
1155
1236
|
} catch (error) {
|
|
1156
|
-
strapi.log.error("
|
|
1237
|
+
strapi.log.error("[ERROR] Error fetching license by key:", error);
|
|
1157
1238
|
return null;
|
|
1158
1239
|
}
|
|
1159
1240
|
},
|
|
@@ -1170,7 +1251,7 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1170
1251
|
}
|
|
1171
1252
|
return null;
|
|
1172
1253
|
} catch (error) {
|
|
1173
|
-
strapi.log.error("
|
|
1254
|
+
strapi.log.error("[ERROR] Error fetching online stats:", error);
|
|
1174
1255
|
return null;
|
|
1175
1256
|
}
|
|
1176
1257
|
},
|
|
@@ -1183,7 +1264,7 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1183
1264
|
const pingInterval = setInterval(async () => {
|
|
1184
1265
|
await this.pingLicense(licenseKey);
|
|
1185
1266
|
}, intervalMs);
|
|
1186
|
-
strapi.log.info(
|
|
1267
|
+
strapi.log.info(`[PING] Started pinging license every ${intervalMinutes} minutes`);
|
|
1187
1268
|
return pingInterval;
|
|
1188
1269
|
},
|
|
1189
1270
|
/**
|
|
@@ -1192,7 +1273,7 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1192
1273
|
*/
|
|
1193
1274
|
async initialize() {
|
|
1194
1275
|
try {
|
|
1195
|
-
strapi.log.info("
|
|
1276
|
+
strapi.log.info("[LICENSE] Initializing License Guard...");
|
|
1196
1277
|
const pluginStore = strapi.store({
|
|
1197
1278
|
type: "plugin",
|
|
1198
1279
|
name: "magic-mark"
|
|
@@ -1208,29 +1289,29 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1208
1289
|
withinGracePeriod = hoursSinceValidation < gracePeriodHours;
|
|
1209
1290
|
}
|
|
1210
1291
|
strapi.log.info("──────────────────────────────────────────────────────────");
|
|
1211
|
-
strapi.log.info(
|
|
1292
|
+
strapi.log.info(`[STORE] Plugin Store Check:`);
|
|
1212
1293
|
if (licenseKey) {
|
|
1213
|
-
strapi.log.info(`
|
|
1214
|
-
strapi.log.info(`
|
|
1294
|
+
strapi.log.info(` [OK] License Key found: ${licenseKey}`);
|
|
1295
|
+
strapi.log.info(` [KEY] Key (short): ${licenseKey.substring(0, 8)}...`);
|
|
1215
1296
|
if (lastValidated) {
|
|
1216
1297
|
const lastValidatedDate = new Date(lastValidated);
|
|
1217
1298
|
const hoursAgo = Math.floor((now.getTime() - lastValidatedDate.getTime()) / (1e3 * 60 * 60));
|
|
1218
|
-
strapi.log.info(`
|
|
1299
|
+
strapi.log.info(` [TIME] Last validated: ${hoursAgo}h ago (Grace: ${withinGracePeriod ? "ACTIVE" : "EXPIRED"})`);
|
|
1219
1300
|
} else {
|
|
1220
|
-
strapi.log.info(`
|
|
1301
|
+
strapi.log.info(` [TIME] Last validated: Never (Grace: ACTIVE for first ${gracePeriodHours}h)`);
|
|
1221
1302
|
}
|
|
1222
1303
|
} else {
|
|
1223
|
-
strapi.log.info(`
|
|
1304
|
+
strapi.log.info(` [NONE] No license key stored`);
|
|
1224
1305
|
}
|
|
1225
1306
|
strapi.log.info("──────────────────────────────────────────────────────────");
|
|
1226
1307
|
if (licenseKey) {
|
|
1227
|
-
strapi.log.info("
|
|
1308
|
+
strapi.log.info("[VERIFY] Verifying stored license key...");
|
|
1228
1309
|
const verification = await this.verifyLicense(licenseKey, true);
|
|
1229
1310
|
if (verification.valid) {
|
|
1230
1311
|
if (verification.gracePeriod) {
|
|
1231
|
-
strapi.log.info("
|
|
1312
|
+
strapi.log.info("[SUCCESS] License accepted (offline mode / grace period)");
|
|
1232
1313
|
} else {
|
|
1233
|
-
strapi.log.info("
|
|
1314
|
+
strapi.log.info("[SUCCESS] License is valid and active");
|
|
1234
1315
|
}
|
|
1235
1316
|
const pingInterval = this.startPinging(licenseKey, 15);
|
|
1236
1317
|
strapi.licenseGuard = {
|
|
@@ -1240,17 +1321,17 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1240
1321
|
};
|
|
1241
1322
|
return { valid: true, data: verification.data };
|
|
1242
1323
|
} else {
|
|
1243
|
-
strapi.log.warn("
|
|
1324
|
+
strapi.log.warn("[WARN] Stored license is invalid or expired");
|
|
1244
1325
|
if (!withinGracePeriod) {
|
|
1245
1326
|
await pluginStore.delete({ key: "licenseKey" });
|
|
1246
1327
|
await pluginStore.delete({ key: "lastValidated" });
|
|
1247
1328
|
}
|
|
1248
1329
|
}
|
|
1249
1330
|
}
|
|
1250
|
-
strapi.log.warn("
|
|
1331
|
+
strapi.log.warn("[WARN] No valid license found. Plugin will run with limited functionality.");
|
|
1251
1332
|
return { valid: false, demo: true };
|
|
1252
1333
|
} catch (error) {
|
|
1253
|
-
strapi.log.error("
|
|
1334
|
+
strapi.log.error("[ERROR] Error initializing license guard:", error);
|
|
1254
1335
|
return { valid: false, error: error.message };
|
|
1255
1336
|
}
|
|
1256
1337
|
},
|
|
@@ -1259,7 +1340,7 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1259
1340
|
*/
|
|
1260
1341
|
async storeLicenseKey(licenseKey) {
|
|
1261
1342
|
try {
|
|
1262
|
-
strapi.log.info(
|
|
1343
|
+
strapi.log.info(`[STORE] Storing license key: ${licenseKey}`);
|
|
1263
1344
|
const pluginStore = strapi.store({
|
|
1264
1345
|
type: "plugin",
|
|
1265
1346
|
name: "magic-mark"
|
|
@@ -1268,14 +1349,14 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1268
1349
|
await pluginStore.set({ key: "lastValidated", value: (/* @__PURE__ */ new Date()).toISOString() });
|
|
1269
1350
|
const stored = await pluginStore.get({ key: "licenseKey" });
|
|
1270
1351
|
if (stored === licenseKey) {
|
|
1271
|
-
strapi.log.info("
|
|
1352
|
+
strapi.log.info("[SUCCESS] License key stored and verified successfully");
|
|
1272
1353
|
return true;
|
|
1273
1354
|
} else {
|
|
1274
|
-
strapi.log.error("
|
|
1355
|
+
strapi.log.error("[ERROR] License key storage verification failed");
|
|
1275
1356
|
return false;
|
|
1276
1357
|
}
|
|
1277
1358
|
} catch (error) {
|
|
1278
|
-
strapi.log.error("
|
|
1359
|
+
strapi.log.error("[ERROR] Error storing license key:", error);
|
|
1279
1360
|
return false;
|
|
1280
1361
|
}
|
|
1281
1362
|
},
|
|
@@ -1286,7 +1367,7 @@ const licenseGuardService = ({ strapi }) => ({
|
|
|
1286
1367
|
const licenseGuard = strapi.licenseGuard;
|
|
1287
1368
|
if (licenseGuard && licenseGuard.pingInterval) {
|
|
1288
1369
|
clearInterval(licenseGuard.pingInterval);
|
|
1289
|
-
strapi.log.info("
|
|
1370
|
+
strapi.log.info("[STOP] License pinging stopped");
|
|
1290
1371
|
}
|
|
1291
1372
|
}
|
|
1292
1373
|
});
|