strapi-plugin-magic-link-v5 5.5.7 → 5.5.8

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.
@@ -1,647 +0,0 @@
1
- "use strict";
2
- const jsxRuntime = require("react/jsx-runtime");
3
- const react = require("react");
4
- const reactIntl = require("react-intl");
5
- const en = require("./en-DnvSpXvu.js");
6
- const de = require("./de-BSOk5suQ.js");
7
- const fr = require("./fr-BKo8t7Fx.js");
8
- const es = require("./es-B-tnwByt.js");
9
- const pt = require("./pt-CjEkXBAz.js");
10
- const designSystem = require("@strapi/design-system");
11
- const admin = require("@strapi/strapi/admin");
12
- const icons = require("@strapi/icons");
13
- const reactRouterDom = require("react-router-dom");
14
- const styled = require("styled-components");
15
- const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
16
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
17
- const LanguageContext = react.createContext();
18
- const usePluginLanguage = () => {
19
- const context = react.useContext(LanguageContext);
20
- if (!context) {
21
- throw new Error("usePluginLanguage must be used within LanguageProvider");
22
- }
23
- return context;
24
- };
25
- const translations = {
26
- en: en.default,
27
- de: de.default,
28
- fr: fr.default,
29
- es: es.default,
30
- pt: pt.default
31
- };
32
- const LanguageProvider = ({ children }) => {
33
- const [currentLanguage, setCurrentLanguage] = react.useState(() => {
34
- return localStorage.getItem("magic-link-language") || "en";
35
- });
36
- const changeLanguage = (newLang) => {
37
- setCurrentLanguage(newLang);
38
- localStorage.setItem("magic-link-language", newLang);
39
- };
40
- const value = {
41
- language: currentLanguage,
42
- changeLanguage,
43
- t: (key) => {
44
- const messages = translations[currentLanguage] || translations.en;
45
- return messages[key] || key;
46
- }
47
- };
48
- return /* @__PURE__ */ jsxRuntime.jsx(LanguageContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(
49
- reactIntl.IntlProvider,
50
- {
51
- locale: currentLanguage,
52
- messages: translations[currentLanguage],
53
- defaultLocale: "en",
54
- children
55
- }
56
- ) });
57
- };
58
- const fadeIn = styled.keyframes`
59
- from { opacity: 0; }
60
- to { opacity: 1; }
61
- `;
62
- const slideUp = styled.keyframes`
63
- from {
64
- opacity: 0;
65
- transform: translateY(30px);
66
- }
67
- to {
68
- opacity: 1;
69
- transform: translateY(0);
70
- }
71
- `;
72
- const ModalOverlay = styled__default.default.div`
73
- position: fixed;
74
- top: 0;
75
- left: 0;
76
- right: 0;
77
- bottom: 0;
78
- background: rgba(4, 28, 47, 0.85);
79
- backdrop-filter: blur(8px);
80
- z-index: 9999;
81
- display: flex;
82
- align-items: center;
83
- justify-content: center;
84
- animation: ${fadeIn} 0.3s ease-out;
85
- padding: 20px;
86
- `;
87
- const ModalContent = styled__default.default(designSystem.Box)`
88
- background: ${(p) => p.theme.colors.neutral0};
89
- border-radius: 16px;
90
- width: 100%;
91
- max-width: 580px;
92
- box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
93
- animation: ${slideUp} 0.4s cubic-bezier(0.4, 0, 0.2, 1);
94
- overflow: hidden;
95
- `;
96
- const GradientHeader = styled__default.default(designSystem.Box)`
97
- background: linear-gradient(135deg, #4945ff 0%, #7c3aed 100%);
98
- padding: 32px 40px;
99
- position: relative;
100
- overflow: hidden;
101
-
102
- &::before {
103
- content: '';
104
- position: absolute;
105
- top: -50%;
106
- right: -50%;
107
- width: 200%;
108
- height: 200%;
109
- background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
110
- }
111
- `;
112
- const IconWrapper = styled__default.default.div`
113
- width: 72px;
114
- height: 72px;
115
- border-radius: 50%;
116
- background: rgba(255, 255, 255, 0.2);
117
- display: flex;
118
- align-items: center;
119
- justify-content: center;
120
- margin: 0 auto 16px;
121
- backdrop-filter: blur(10px);
122
- border: 2px solid rgba(255, 255, 255, 0.3);
123
-
124
- svg {
125
- width: 36px;
126
- height: 36px;
127
- color: white;
128
- }
129
- `;
130
- const CloseButton = styled__default.default.button`
131
- position: absolute;
132
- top: 16px;
133
- right: 16px;
134
- background: rgba(255, 255, 255, 0.2);
135
- border: 2px solid rgba(255, 255, 255, 0.3);
136
- border-radius: 50%;
137
- width: 36px;
138
- height: 36px;
139
- display: flex;
140
- align-items: center;
141
- justify-content: center;
142
- cursor: pointer;
143
- transition: all 0.2s;
144
- z-index: 10;
145
-
146
- svg {
147
- width: 20px;
148
- height: 20px;
149
- color: white;
150
- }
151
-
152
- &:hover {
153
- background: rgba(255, 255, 255, 0.3);
154
- transform: scale(1.1);
155
- }
156
-
157
- &:active {
158
- transform: scale(0.95);
159
- }
160
- `;
161
- const ToggleButton = styled__default.default.button`
162
- background: none;
163
- border: none;
164
- color: #4945ff;
165
- font-size: 13px;
166
- font-weight: 600;
167
- cursor: pointer;
168
- padding: 8px 0;
169
- text-decoration: underline;
170
- transition: color 0.2s;
171
-
172
- &:hover {
173
- color: #7c3aed;
174
- }
175
-
176
- &:disabled {
177
- opacity: 0.5;
178
- cursor: not-allowed;
179
- }
180
- `;
181
- const GradientButton = styled__default.default(designSystem.Button)`
182
- && {
183
- background: linear-gradient(135deg, #4945ff 0%, #7c3aed 100%);
184
- color: white;
185
- font-weight: 600;
186
- border: none;
187
- box-shadow: 0 4px 12px rgba(73, 69, 255, 0.4);
188
-
189
- &:hover:not(:disabled) {
190
- background: linear-gradient(135deg, #4338ca 0%, #6d28d9 100%);
191
- box-shadow: 0 6px 16px rgba(73, 69, 255, 0.5);
192
- }
193
-
194
- &:disabled {
195
- opacity: 0.6;
196
- cursor: not-allowed;
197
- }
198
- }
199
- `;
200
- styled__default.default(designSystem.Box)`
201
- background: rgba(73, 69, 255, 0.06);
202
- border: 2px solid rgba(73, 69, 255, 0.3);
203
- border-radius: 8px;
204
- padding: 16px;
205
- `;
206
- styled__default.default(designSystem.Typography)`
207
- font-size: 13px;
208
- line-height: 1.6;
209
- color: ${(p) => p.theme.colors.neutral800};
210
- `;
211
- const LicenseGuard = ({ children }) => {
212
- const { get, post } = admin.useFetchClient();
213
- const { toggleNotification } = admin.useNotification();
214
- const navigate = reactRouterDom.useNavigate();
215
- const [isChecking, setIsChecking] = react.useState(true);
216
- const [needsLicense, setNeedsLicense] = react.useState(false);
217
- const [isCreating, setIsCreating] = react.useState(false);
218
- const [useExistingKey, setUseExistingKey] = react.useState(false);
219
- const [useAutoCreate, setUseAutoCreate] = react.useState(true);
220
- const [existingLicenseKey, setExistingLicenseKey] = react.useState("");
221
- const [existingEmail, setExistingEmail] = react.useState("");
222
- const [adminUser, setAdminUser] = react.useState(null);
223
- const [formData, setFormData] = react.useState({
224
- email: "",
225
- firstName: "",
226
- lastName: ""
227
- });
228
- react.useEffect(() => {
229
- checkLicenseStatus();
230
- fetchAdminUser();
231
- }, []);
232
- const fetchAdminUser = async () => {
233
- try {
234
- const response = await get("/admin/users/me");
235
- console.log("Admin user response:", response);
236
- const userData = response.data?.data || response.data;
237
- console.log("User data extracted:", userData);
238
- if (userData) {
239
- setAdminUser(userData);
240
- setFormData({
241
- email: userData.email || "",
242
- firstName: userData.firstname || "",
243
- lastName: userData.lastname || ""
244
- });
245
- console.log("Admin user set:", {
246
- email: userData.email,
247
- firstname: userData.firstname,
248
- lastname: userData.lastname
249
- });
250
- }
251
- } catch (error) {
252
- console.error("Error fetching admin user:", error);
253
- }
254
- };
255
- const checkLicenseStatus = async () => {
256
- setIsChecking(true);
257
- try {
258
- const response = await get("/magic-link/license/status");
259
- if (response.data.valid) {
260
- setNeedsLicense(false);
261
- } else {
262
- setNeedsLicense(true);
263
- }
264
- } catch (error) {
265
- console.error("Error checking license:", error);
266
- setNeedsLicense(true);
267
- } finally {
268
- setIsChecking(false);
269
- }
270
- };
271
- const handleAutoCreateLicense = async (e) => {
272
- e.preventDefault();
273
- setIsCreating(true);
274
- try {
275
- console.log("Auto-creating license with admin user data...");
276
- const response = await post("/magic-link/license/auto-create", {});
277
- console.log("Auto-create response:", response);
278
- if (response.data && response.data.success) {
279
- toggleNotification({
280
- type: "success",
281
- message: `License automatically created! Reloading...`
282
- });
283
- setNeedsLicense(false);
284
- setTimeout(() => {
285
- window.location.reload();
286
- }, 500);
287
- } else {
288
- throw new Error("Failed to auto-create license");
289
- }
290
- } catch (error) {
291
- console.error("Error auto-creating license:", error);
292
- toggleNotification({
293
- type: "danger",
294
- message: error?.response?.data?.error?.message || "Failed to auto-create license. Try manual creation."
295
- });
296
- setIsCreating(false);
297
- setUseAutoCreate(false);
298
- }
299
- };
300
- const handleCreateLicense = async (e) => {
301
- e.preventDefault();
302
- if (!formData.email || !formData.firstName || !formData.lastName) {
303
- toggleNotification({
304
- type: "warning",
305
- message: "Please fill in all fields"
306
- });
307
- return;
308
- }
309
- setIsCreating(true);
310
- try {
311
- console.log("Creating license with data:", formData);
312
- const response = await post("/magic-link/license/create", formData);
313
- console.log("License creation response:", response);
314
- if (response.data && response.data.success) {
315
- toggleNotification({
316
- type: "success",
317
- message: `License created successfully! Reloading...`
318
- });
319
- setNeedsLicense(false);
320
- setTimeout(() => {
321
- window.location.reload();
322
- }, 500);
323
- } else {
324
- throw new Error("Failed to create license");
325
- }
326
- } catch (error) {
327
- console.error("Error creating license:", error);
328
- toggleNotification({
329
- type: "danger",
330
- message: error?.response?.data?.error?.message || "Failed to create license. Please try again."
331
- });
332
- setIsCreating(false);
333
- }
334
- };
335
- const handleValidateExistingKey = async (e) => {
336
- e.preventDefault();
337
- if (!existingLicenseKey.trim() || !existingEmail.trim()) {
338
- toggleNotification({
339
- type: "warning",
340
- message: "Please enter both license key and email address",
341
- title: "Validation Error"
342
- });
343
- return;
344
- }
345
- setIsCreating(true);
346
- try {
347
- console.log("Validating existing license key...");
348
- const pluginStore = await post("/magic-link/license/store-key", {
349
- licenseKey: existingLicenseKey.trim(),
350
- email: existingEmail.trim()
351
- });
352
- if (pluginStore.data && pluginStore.data.success) {
353
- toggleNotification({
354
- type: "success",
355
- message: "License key validated successfully! Reloading...",
356
- title: "✅ License Activated"
357
- });
358
- setNeedsLicense(false);
359
- setTimeout(() => {
360
- window.location.reload();
361
- }, 500);
362
- } else {
363
- throw new Error("Invalid license key or email");
364
- }
365
- } catch (error) {
366
- console.error("Error validating license key:", error);
367
- toggleNotification({
368
- type: "danger",
369
- message: error?.response?.data?.error?.message || "Invalid license key or email address. Please check and try again.",
370
- title: "Validation Error"
371
- });
372
- setIsCreating(false);
373
- }
374
- };
375
- const handleClose = () => {
376
- navigate("/content-manager");
377
- };
378
- if (isChecking) {
379
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 8, style: { textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { children: "Checking license..." }) });
380
- }
381
- if (needsLicense) {
382
- return /* @__PURE__ */ jsxRuntime.jsx(ModalOverlay, { children: /* @__PURE__ */ jsxRuntime.jsxs(ModalContent, { children: [
383
- /* @__PURE__ */ jsxRuntime.jsxs(GradientHeader, { children: [
384
- /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { onClick: handleClose, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}) }),
385
- /* @__PURE__ */ jsxRuntime.jsx(IconWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.Key, {}) }),
386
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { textAlign: "center", position: "relative" }, children: [
387
- /* @__PURE__ */ jsxRuntime.jsx(
388
- designSystem.Typography,
389
- {
390
- variant: "alpha",
391
- style: {
392
- color: "white",
393
- fontSize: "24px",
394
- fontWeight: "700",
395
- marginBottom: "12px",
396
- display: "block"
397
- },
398
- children: "🔐 Activate Magic Link Plugin"
399
- }
400
- ),
401
- /* @__PURE__ */ jsxRuntime.jsx(
402
- designSystem.Typography,
403
- {
404
- variant: "epsilon",
405
- style: {
406
- color: "rgba(255, 255, 255, 0.9)",
407
- fontSize: "14px",
408
- display: "block"
409
- },
410
- children: useExistingKey ? "Enter your existing license key" : "Create a license to start using the plugin"
411
- }
412
- )
413
- ] })
414
- ] }),
415
- /* @__PURE__ */ jsxRuntime.jsx(
416
- designSystem.Box,
417
- {
418
- as: "form",
419
- onSubmit: useExistingKey ? handleValidateExistingKey : useAutoCreate ? handleAutoCreateLicense : handleCreateLicense,
420
- padding: 6,
421
- paddingLeft: 8,
422
- paddingRight: 8,
423
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 5, style: { width: "100%" }, children: [
424
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { textAlign: "center", width: "100%" }, children: [
425
- !useExistingKey && /* @__PURE__ */ jsxRuntime.jsx(
426
- ToggleButton,
427
- {
428
- type: "button",
429
- onClick: () => setUseAutoCreate(!useAutoCreate),
430
- disabled: isCreating,
431
- style: { marginBottom: "8px", display: "block", margin: "0 auto" },
432
- children: useAutoCreate ? "→ Manual entry" : "← Auto-create with my account"
433
- }
434
- ),
435
- /* @__PURE__ */ jsxRuntime.jsx(
436
- ToggleButton,
437
- {
438
- type: "button",
439
- onClick: () => {
440
- setUseExistingKey(!useExistingKey);
441
- if (!useExistingKey) setUseAutoCreate(false);
442
- },
443
- disabled: isCreating,
444
- children: useExistingKey ? "← Create new license" : "Have a license key? →"
445
- }
446
- )
447
- ] }),
448
- /* @__PURE__ */ jsxRuntime.jsx(
449
- designSystem.Box,
450
- {
451
- background: "primary100",
452
- padding: 4,
453
- style: {
454
- borderRadius: "8px",
455
- border: "2px solid #BAE6FD",
456
- width: "100%"
457
- },
458
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { fontSize: "13px", lineHeight: "1.6" }, children: useExistingKey ? "🔑 Enter your email and license key to activate." : useAutoCreate && adminUser && adminUser.email ? `✨ Click "Activate" to auto-create a license with your account (${adminUser.email})` : useAutoCreate ? '✨ Click "Activate" to auto-create a license with your admin account' : "💡 A license will be created with the details below." })
459
- }
460
- ),
461
- useExistingKey ? (
462
- // Existing License Key Input
463
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
464
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { width: "100%" }, children: [
465
- /* @__PURE__ */ jsxRuntime.jsx(
466
- designSystem.Typography,
467
- {
468
- variant: "pi",
469
- fontWeight: "bold",
470
- style: { marginBottom: "8px", display: "block" },
471
- children: "Email Address *"
472
- }
473
- ),
474
- /* @__PURE__ */ jsxRuntime.jsx(
475
- designSystem.TextInput,
476
- {
477
- placeholder: "admin@example.com",
478
- type: "email",
479
- value: existingEmail,
480
- onChange: (e) => setExistingEmail(e.target.value),
481
- required: true,
482
- disabled: isCreating,
483
- style: { width: "100%" }
484
- }
485
- ),
486
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", style: { fontSize: "11px", marginTop: "4px" }, children: "Enter the email address associated with this license" })
487
- ] }),
488
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { width: "100%" }, children: [
489
- /* @__PURE__ */ jsxRuntime.jsx(
490
- designSystem.Typography,
491
- {
492
- variant: "pi",
493
- fontWeight: "bold",
494
- style: { marginBottom: "8px", display: "block" },
495
- children: "License Key *"
496
- }
497
- ),
498
- /* @__PURE__ */ jsxRuntime.jsx(
499
- designSystem.TextInput,
500
- {
501
- placeholder: "67C5-40D2-7695-718C",
502
- value: existingLicenseKey,
503
- onChange: (e) => setExistingLicenseKey(e.target.value),
504
- required: true,
505
- disabled: isCreating,
506
- style: { width: "100%", fontFamily: "monospace" }
507
- }
508
- ),
509
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", style: { fontSize: "11px", marginTop: "4px" }, children: "Enter the license key in the format: XXXX-XXXX-XXXX-XXXX" })
510
- ] })
511
- ] })
512
- ) : useAutoCreate && adminUser ? (
513
- // Auto-create mode - Show user info
514
- /* @__PURE__ */ jsxRuntime.jsxs(
515
- designSystem.Box,
516
- {
517
- background: "success100",
518
- padding: 5,
519
- style: {
520
- borderRadius: "8px",
521
- border: "2px solid #DCFCE7",
522
- textAlign: "center"
523
- },
524
- children: [
525
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", style: { marginBottom: "12px", display: "block" }, children: "Ready to activate with your account:" }),
526
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", style: { marginBottom: "4px", display: "block" }, children: [
527
- "👤 ",
528
- adminUser.firstname || "Admin",
529
- " ",
530
- adminUser.lastname || "User"
531
- ] }),
532
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: [
533
- "📧 ",
534
- adminUser.email || "Loading..."
535
- ] })
536
- ]
537
- }
538
- )
539
- ) : (
540
- // Manual Create License Fields
541
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
542
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { width: "100%" }, children: [
543
- /* @__PURE__ */ jsxRuntime.jsx(
544
- designSystem.Typography,
545
- {
546
- variant: "pi",
547
- fontWeight: "bold",
548
- style: { marginBottom: "8px", display: "block" },
549
- children: "Email Address *"
550
- }
551
- ),
552
- /* @__PURE__ */ jsxRuntime.jsx(
553
- designSystem.TextInput,
554
- {
555
- placeholder: "admin@example.com",
556
- type: "email",
557
- value: formData.email,
558
- onChange: (e) => setFormData({ ...formData, email: e.target.value }),
559
- required: true,
560
- disabled: isCreating,
561
- style: { width: "100%" }
562
- }
563
- )
564
- ] }),
565
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { width: "100%" }, children: [
566
- /* @__PURE__ */ jsxRuntime.jsx(
567
- designSystem.Typography,
568
- {
569
- variant: "pi",
570
- fontWeight: "bold",
571
- style: { marginBottom: "8px", display: "block" },
572
- children: "First Name *"
573
- }
574
- ),
575
- /* @__PURE__ */ jsxRuntime.jsx(
576
- designSystem.TextInput,
577
- {
578
- placeholder: "John",
579
- value: formData.firstName,
580
- onChange: (e) => setFormData({ ...formData, firstName: e.target.value }),
581
- required: true,
582
- disabled: isCreating,
583
- style: { width: "100%" }
584
- }
585
- )
586
- ] }),
587
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { width: "100%" }, children: [
588
- /* @__PURE__ */ jsxRuntime.jsx(
589
- designSystem.Typography,
590
- {
591
- variant: "pi",
592
- fontWeight: "bold",
593
- style: { marginBottom: "8px", display: "block" },
594
- children: "Last Name *"
595
- }
596
- ),
597
- /* @__PURE__ */ jsxRuntime.jsx(
598
- designSystem.TextInput,
599
- {
600
- placeholder: "Doe",
601
- value: formData.lastName,
602
- onChange: (e) => setFormData({ ...formData, lastName: e.target.value }),
603
- required: true,
604
- disabled: isCreating,
605
- style: { width: "100%" }
606
- }
607
- )
608
- ] })
609
- ] })
610
- ),
611
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 3, justifyContent: "center", style: { marginTop: "16px" }, children: useExistingKey ? (
612
- // Validate Button
613
- /* @__PURE__ */ jsxRuntime.jsx(
614
- GradientButton,
615
- {
616
- type: "submit",
617
- size: "L",
618
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}),
619
- loading: isCreating,
620
- disabled: isCreating || !existingLicenseKey.trim() || !existingEmail.trim(),
621
- children: "Validate License"
622
- }
623
- )
624
- ) : (
625
- // Create/Auto-Create License Button
626
- /* @__PURE__ */ jsxRuntime.jsx(
627
- GradientButton,
628
- {
629
- type: "submit",
630
- size: "L",
631
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}),
632
- loading: isCreating,
633
- disabled: isCreating || !useAutoCreate && (!formData.email || !formData.firstName || !formData.lastName),
634
- children: useAutoCreate ? "Activate License" : "Create License"
635
- }
636
- )
637
- ) })
638
- ] })
639
- }
640
- )
641
- ] }) });
642
- }
643
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
644
- };
645
- exports.LanguageProvider = LanguageProvider;
646
- exports.LicenseGuard = LicenseGuard;
647
- exports.usePluginLanguage = usePluginLanguage;