strapi-plugin-magic-link-v5 5.5.6 → 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.
- package/CHANGELOG.md +14 -0
- package/README.md +28 -47
- package/dist/_chunks/LicenseGuard-CiyjFnrw.js +54 -0
- package/dist/_chunks/LicenseGuard-DJ5fq2UZ.mjs +55 -0
- package/dist/_chunks/{index-PgHpSdc8.js → index-01GHNxSr.js} +6 -35
- package/dist/_chunks/{index-CxCULraY.mjs → index-B9Ch8Jpe.mjs} +2 -2
- package/dist/_chunks/{index-34ICAF9_.mjs → index-Bj-erY7g.mjs} +4 -17
- package/dist/_chunks/{index-BFzW7Xex.js → index-CGxbhJfg.js} +4 -17
- package/dist/_chunks/{index-BZFGxKmY.mjs → index-DF3Edydl.mjs} +1 -1
- package/dist/_chunks/{index-B8urUtiz.mjs → index-Dufv-daf.mjs} +7 -36
- package/dist/_chunks/{index-M5s7QN5m.js → index-I72rBTkL.js} +1 -1
- package/dist/_chunks/{index-ivgYEX37.mjs → index-SCxv154G.mjs} +9 -128
- package/dist/_chunks/{index-CddEy_As.js → index-XYWLmmEs.js} +2 -2
- package/dist/_chunks/{index-CuXnqVl4.js → index-zzoovbM0.js} +9 -128
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +257 -754
- package/dist/server/index.mjs +257 -754
- package/package.json +3 -3
- package/dist/_chunks/LicenseGuard-5sMwgS6j.mjs +0 -646
- package/dist/_chunks/LicenseGuard-DqyOwTlf.js +0 -647
- package/dist/_chunks/LicensePage-2M-vOJX8.js +0 -377
- package/dist/_chunks/LicensePage-CCNW2hT6.mjs +0 -375
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [5.5.8](https://github.com/Schero94/strapi-plugin-magic-link-v5/compare/v5.5.7...v5.5.8) (2026-05-03)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **settings:** declare missing emailTemplates state — closes [#17](https://github.com/Schero94/strapi-plugin-magic-link-v5/issues/17) ([6ee2740](https://github.com/Schero94/strapi-plugin-magic-link-v5/commit/6ee2740c62e7772e5cfa8904416ab64be84bab5e))
|
|
7
|
+
|
|
8
|
+
## [5.5.7](https://github.com/Schero94/strapi-plugin-magic-link-v5/compare/v5.5.6...v5.5.7) (2026-04-26)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **send-link:** use Email Designer 5 template on public endpoint ([8e0abbc](https://github.com/Schero94/strapi-plugin-magic-link-v5/commit/8e0abbc3f479b5a41d5a56c081592c2a2f4daffa)), closes [#17](https://github.com/Schero94/strapi-plugin-magic-link-v5/issues/17) [#17](https://github.com/Schero94/strapi-plugin-magic-link-v5/issues/17)
|
|
14
|
+
|
|
1
15
|
## [5.5.6](https://github.com/Schero94/strapi-plugin-magic-link-v5/compare/v5.5.5...v5.5.6) (2026-04-26)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -10,12 +10,12 @@ Secure, modern, and user-friendly authentication using email-based magic links,
|
|
|
10
10
|
|
|
11
11
|
## Why Magic Link?
|
|
12
12
|
|
|
13
|
-
- **Zero Setup Time** - Install,
|
|
14
|
-
- **Production Ready** - Battle-tested with rate limiting, IP bans, and session management
|
|
15
|
-
- **Multi-Factor Authentication** - Email OTP + TOTP Authenticator support
|
|
16
|
-
- **WhatsApp Integration** - Send magic links via WhatsApp
|
|
17
|
-
- **Beautiful UI** - Modern, responsive admin interface
|
|
18
|
-
- **
|
|
13
|
+
- **Zero Setup Time** - Install, configure SMTP, and start using.
|
|
14
|
+
- **Production Ready** - Battle-tested with rate limiting, IP bans, and session management.
|
|
15
|
+
- **Multi-Factor Authentication** - Email OTP + TOTP Authenticator support, included.
|
|
16
|
+
- **WhatsApp Integration** - Send magic links via WhatsApp messenger.
|
|
17
|
+
- **Beautiful UI** - Modern, responsive admin interface localized in 5 languages.
|
|
18
|
+
- **Free & Open** - MIT license, no paywall, every feature available out of the box.
|
|
19
19
|
|
|
20
20
|
## 📚 Quick Links
|
|
21
21
|
|
|
@@ -45,23 +45,16 @@ Users can switch languages in **Settings → Magic Link → Interface Language**
|
|
|
45
45
|
|
|
46
46
|
## 📜 License
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
MIT-licensed. Free for personal and commercial use. See [LICENSE](./LICENSE).
|
|
49
49
|
|
|
50
|
-
###
|
|
51
|
-
- ✅ Use the plugin freely (personal & commercial)
|
|
52
|
-
- ✅ View and study the source code
|
|
53
|
-
- ✅ Report issues and contribute improvements
|
|
54
|
-
- ✅ Deploy in production without fees
|
|
55
|
-
- ✅ Integrate in your commercial projects
|
|
50
|
+
### Optional license-key activation
|
|
56
51
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
The admin panel offers a "License" tab where you can register an optional
|
|
53
|
+
license key. This is purely cosmetic — it does **not** unlock any
|
|
54
|
+
feature, and the plugin is fully usable without it. Registering a key
|
|
55
|
+
just lets the project track installs and helps us prioritise issues.
|
|
61
56
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
📄 See [LICENSE](./LICENSE) for full terms
|
|
57
|
+
You can ignore the License tab entirely; nothing will be gated.
|
|
65
58
|
|
|
66
59
|
---
|
|
67
60
|
|
|
@@ -69,37 +62,25 @@ This plugin is licensed under the **MIT License** - free for everyone to use!
|
|
|
69
62
|
|
|
70
63
|
### Authentication Modes
|
|
71
64
|
|
|
72
|
-
|
|
65
|
+
All modes are available in every install — pick whichever fits your security profile:
|
|
73
66
|
|
|
74
|
-
| Mode | Description |
|
|
75
|
-
|
|
76
|
-
| **Magic Link Only** | One-click email login
|
|
77
|
-
| **Magic Link via WhatsApp** | Send magic links via WhatsApp messenger |
|
|
78
|
-
| **Magic Link + Email OTP** | 6-digit code after magic link click |
|
|
79
|
-
| **Magic Link + TOTP (MFA)** | Authenticator app (Google
|
|
80
|
-
| **TOTP-Only Login** | Direct login with email + TOTP code |
|
|
67
|
+
| Mode | Description |
|
|
68
|
+
|------|-------------|
|
|
69
|
+
| **Magic Link Only** | One-click email login — fast & user-friendly |
|
|
70
|
+
| **Magic Link via WhatsApp** | Send magic links via the WhatsApp messenger |
|
|
71
|
+
| **Magic Link + Email OTP** | 6-digit code sent after the magic link click |
|
|
72
|
+
| **Magic Link + TOTP (MFA)** | Authenticator app (Google Authenticator, Authy, …) |
|
|
73
|
+
| **TOTP-Only Login** | Direct login with email + TOTP code |
|
|
81
74
|
|
|
82
75
|
### 🛡️ Security Features
|
|
83
76
|
|
|
84
|
-
- **Rate Limiting**
|
|
85
|
-
- **IP Banning**
|
|
86
|
-
- **Session Management**
|
|
87
|
-
- **Login Tracking**
|
|
88
|
-
- **Token Expiration**
|
|
89
|
-
- **Brute Force Protection**
|
|
90
|
-
- **Security Score**
|
|
91
|
-
|
|
92
|
-
### � License Tiers
|
|
93
|
-
|
|
94
|
-
| Feature | Free | Premium | Advanced |
|
|
95
|
-
|---------|------|---------|----------|
|
|
96
|
-
| Magic Link Login | ✅ | ✅ | ✅ |
|
|
97
|
-
| Token Management | ✅ | ✅ | ✅ |
|
|
98
|
-
| IP Banning | ✅ | ✅ | ✅ |
|
|
99
|
-
| Rate Limiting | ✅ | ✅ | ✅ |
|
|
100
|
-
| Email OTP | ❌ | ✅ | ✅ |
|
|
101
|
-
| TOTP Authenticator | ❌ | ❌ | ✅ |
|
|
102
|
-
| TOTP-Only Login | ❌ | ❌ | ✅ |
|
|
77
|
+
- **Rate Limiting** — 5 requests per 15 minutes (configurable)
|
|
78
|
+
- **IP Banning** — Block suspicious addresses with one click
|
|
79
|
+
- **Session Management** — Monitor and revoke active JWT sessions
|
|
80
|
+
- **Login Tracking** — Store IP addresses and user agents
|
|
81
|
+
- **Token Expiration** — Configurable validity periods
|
|
82
|
+
- **Brute Force Protection** — Login attempt limiting
|
|
83
|
+
- **Security Score** — Real-time configuration assessment
|
|
103
84
|
|
|
104
85
|
### 🎨 Admin Interface
|
|
105
86
|
|
|
@@ -0,0 +1,54 @@
|
|
|
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 LanguageContext = react.createContext();
|
|
11
|
+
const usePluginLanguage = () => {
|
|
12
|
+
const context = react.useContext(LanguageContext);
|
|
13
|
+
if (!context) {
|
|
14
|
+
throw new Error("usePluginLanguage must be used within LanguageProvider");
|
|
15
|
+
}
|
|
16
|
+
return context;
|
|
17
|
+
};
|
|
18
|
+
const translations = {
|
|
19
|
+
en: en.default,
|
|
20
|
+
de: de.default,
|
|
21
|
+
fr: fr.default,
|
|
22
|
+
es: es.default,
|
|
23
|
+
pt: pt.default
|
|
24
|
+
};
|
|
25
|
+
const LanguageProvider = ({ children }) => {
|
|
26
|
+
const [currentLanguage, setCurrentLanguage] = react.useState(() => {
|
|
27
|
+
return localStorage.getItem("magic-link-language") || "en";
|
|
28
|
+
});
|
|
29
|
+
const changeLanguage = (newLang) => {
|
|
30
|
+
setCurrentLanguage(newLang);
|
|
31
|
+
localStorage.setItem("magic-link-language", newLang);
|
|
32
|
+
};
|
|
33
|
+
const value = {
|
|
34
|
+
language: currentLanguage,
|
|
35
|
+
changeLanguage,
|
|
36
|
+
t: (key) => {
|
|
37
|
+
const messages = translations[currentLanguage] || translations.en;
|
|
38
|
+
return messages[key] || key;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LanguageContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
42
|
+
reactIntl.IntlProvider,
|
|
43
|
+
{
|
|
44
|
+
locale: currentLanguage,
|
|
45
|
+
messages: translations[currentLanguage],
|
|
46
|
+
defaultLocale: "en",
|
|
47
|
+
children
|
|
48
|
+
}
|
|
49
|
+
) });
|
|
50
|
+
};
|
|
51
|
+
const LicenseGuard = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
52
|
+
exports.LanguageProvider = LanguageProvider;
|
|
53
|
+
exports.LicenseGuard = LicenseGuard;
|
|
54
|
+
exports.usePluginLanguage = usePluginLanguage;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, createContext, useContext } from "react";
|
|
3
|
+
import { IntlProvider } from "react-intl";
|
|
4
|
+
import enTranslations from "./en-gXXgGDV1.mjs";
|
|
5
|
+
import deTranslations from "./de-CwhYs3O3.mjs";
|
|
6
|
+
import frTranslations from "./fr-BQn1OHOR.mjs";
|
|
7
|
+
import esTranslations from "./es-DG5gW3RZ.mjs";
|
|
8
|
+
import ptTranslations from "./pt-trziAOzT.mjs";
|
|
9
|
+
const LanguageContext = createContext();
|
|
10
|
+
const usePluginLanguage = () => {
|
|
11
|
+
const context = useContext(LanguageContext);
|
|
12
|
+
if (!context) {
|
|
13
|
+
throw new Error("usePluginLanguage must be used within LanguageProvider");
|
|
14
|
+
}
|
|
15
|
+
return context;
|
|
16
|
+
};
|
|
17
|
+
const translations = {
|
|
18
|
+
en: enTranslations,
|
|
19
|
+
de: deTranslations,
|
|
20
|
+
fr: frTranslations,
|
|
21
|
+
es: esTranslations,
|
|
22
|
+
pt: ptTranslations
|
|
23
|
+
};
|
|
24
|
+
const LanguageProvider = ({ children }) => {
|
|
25
|
+
const [currentLanguage, setCurrentLanguage] = useState(() => {
|
|
26
|
+
return localStorage.getItem("magic-link-language") || "en";
|
|
27
|
+
});
|
|
28
|
+
const changeLanguage = (newLang) => {
|
|
29
|
+
setCurrentLanguage(newLang);
|
|
30
|
+
localStorage.setItem("magic-link-language", newLang);
|
|
31
|
+
};
|
|
32
|
+
const value = {
|
|
33
|
+
language: currentLanguage,
|
|
34
|
+
changeLanguage,
|
|
35
|
+
t: (key) => {
|
|
36
|
+
const messages = translations[currentLanguage] || translations.en;
|
|
37
|
+
return messages[key] || key;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
return /* @__PURE__ */ jsx(LanguageContext.Provider, { value, children: /* @__PURE__ */ jsx(
|
|
41
|
+
IntlProvider,
|
|
42
|
+
{
|
|
43
|
+
locale: currentLanguage,
|
|
44
|
+
messages: translations[currentLanguage],
|
|
45
|
+
defaultLocale: "en",
|
|
46
|
+
children
|
|
47
|
+
}
|
|
48
|
+
) });
|
|
49
|
+
};
|
|
50
|
+
const LicenseGuard = ({ children }) => /* @__PURE__ */ jsx(Fragment, { children });
|
|
51
|
+
export {
|
|
52
|
+
LicenseGuard as L,
|
|
53
|
+
LanguageProvider as a,
|
|
54
|
+
usePluginLanguage as u
|
|
55
|
+
};
|
|
@@ -176,8 +176,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
176
176
|
if (error) {
|
|
177
177
|
return /* @__PURE__ */ jsxRuntime.jsx(Container, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 8, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "danger", title: "Error", children: error }) }) });
|
|
178
178
|
}
|
|
179
|
-
const isValid = licenseData?.valid;
|
|
180
|
-
const
|
|
179
|
+
const isValid = licenseData?.valid !== false;
|
|
180
|
+
const hasKey = !!licenseData?.hasKey;
|
|
181
181
|
const data = licenseData?.data || {};
|
|
182
182
|
return /* @__PURE__ */ jsxRuntime.jsxs(Container, { children: [
|
|
183
183
|
/* @__PURE__ */ jsxRuntime.jsx(StickySaveBar, { paddingTop: 5, paddingBottom: 5, paddingLeft: 6, paddingRight: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
@@ -202,7 +202,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
202
202
|
)
|
|
203
203
|
] }) }),
|
|
204
204
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingTop: 6, paddingLeft: 6, paddingRight: 6, paddingBottom: 10, children: [
|
|
205
|
-
|
|
205
|
+
hasKey && isValid ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "success", title: "License Active", children: "License key registered. Thanks for supporting the plugin!" }) : hasKey && !isValid ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "warning", title: "License Verification", children: "We couldn't reach the license server right now. The plugin keeps working — try Refresh Status later." }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "default", title: "No license key registered", children: 'All Magic Link features are available without activation. If you want to register a license key, use the form below or run "Auto-Activate" to generate one for your admin email.' }),
|
|
206
206
|
data.licenseKey && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 6, children: /* @__PURE__ */ jsxRuntime.jsx(LicenseKeyBanner, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "flex-start", children: [
|
|
207
207
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: 1 }, children: [
|
|
208
208
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", style: { color: "rgba(255,255,255,0.8)", marginBottom: "12px", textTransform: "uppercase", fontSize: "11px", letterSpacing: "0.5px", display: "block" }, children: "License Key" }),
|
|
@@ -287,45 +287,16 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
287
287
|
] })
|
|
288
288
|
] }) }) })
|
|
289
289
|
] }),
|
|
290
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "features", children: [
|
|
291
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { icon: icons.Sparkle, children: "Features & Capabilities" }) }),
|
|
292
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 8, wrap: "wrap", children: [
|
|
293
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: "1", minWidth: "180px" }, children: [
|
|
294
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Premium Features" }),
|
|
295
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", children: data.features?.premium ? "✓ Enabled" : "✗ Disabled" })
|
|
296
|
-
] }),
|
|
297
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: "1", minWidth: "180px" }, children: [
|
|
298
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Advanced Features" }),
|
|
299
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", children: data.features?.advanced ? "✓ Enabled" : "✗ Disabled" })
|
|
300
|
-
] }),
|
|
301
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: "1", minWidth: "180px" }, children: [
|
|
302
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Enterprise Features" }),
|
|
303
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", children: data.features?.enterprise ? "✓ Enabled" : "✗ Disabled" })
|
|
304
|
-
] })
|
|
305
|
-
] }) }) })
|
|
306
|
-
] }),
|
|
307
290
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "status", children: [
|
|
308
291
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { icon: icons.ChartBubble, children: "System Status" }) }),
|
|
309
292
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 8, wrap: "wrap", children: [
|
|
310
293
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: "1", minWidth: "150px" }, children: [
|
|
311
294
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "License Status" }),
|
|
312
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", children: data.isActive ? "Active" : "Inactive" })
|
|
313
|
-
] }),
|
|
314
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: "1", minWidth: "150px" }, children: [
|
|
315
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Connection" }),
|
|
316
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", children: data.isOnline ? "Online" : "Offline" })
|
|
317
|
-
] }),
|
|
318
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: "1", minWidth: "150px" }, children: [
|
|
319
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Last Sync" }),
|
|
320
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", children: data.lastPingAt ? new Date(data.lastPingAt).toLocaleTimeString() : "Never" })
|
|
295
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", children: hasKey ? data.isActive ? "Active" : "Inactive" : "No key registered" })
|
|
321
296
|
] }),
|
|
322
297
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: "1", minWidth: "150px" }, children: [
|
|
323
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "
|
|
324
|
-
/* @__PURE__ */ jsxRuntime.
|
|
325
|
-
data.currentDevices || 0,
|
|
326
|
-
" / ",
|
|
327
|
-
data.maxDevices || 1
|
|
328
|
-
] })
|
|
298
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Plugin Mode" }),
|
|
299
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", children: "Fully unlocked" })
|
|
329
300
|
] })
|
|
330
301
|
] }) }) })
|
|
331
302
|
] })
|
|
@@ -5,9 +5,9 @@ import styled, { keyframes, css } from "styled-components";
|
|
|
5
5
|
import { useIntl } from "react-intl";
|
|
6
6
|
import { Box, Flex, Typography, Button, TextInput, Textarea, Checkbox, IconButton, Loader, Searchbar, SingleSelect, SingleSelectOption, Thead, Tr, Th, Tbody, Td, Pagination, PreviousLink, PageLink, NextLink, Table, Badge, VisuallyHidden, Main } from "@strapi/design-system";
|
|
7
7
|
import { Cross, Sparkle, Check, Shield, Clock, Lock, Trash, ArrowClockwise, CaretDown, User, Monitor, Calendar, Plus, Earth, WarningCircle, Server, Eye, Mail, Cog, Key, Link } from "@strapi/icons";
|
|
8
|
-
import { g as getTrad, P as PLUGIN_ID } from "./index-
|
|
8
|
+
import { g as getTrad, P as PLUGIN_ID } from "./index-Bj-erY7g.mjs";
|
|
9
9
|
import { useFetchClient, useNotification } from "@strapi/strapi/admin";
|
|
10
|
-
import { L as LicenseGuard, a as LanguageProvider } from "./LicenseGuard-
|
|
10
|
+
import { L as LicenseGuard, a as LanguageProvider } from "./LicenseGuard-DJ5fq2UZ.mjs";
|
|
11
11
|
const CreateTokenModal = ({ isOpen, onClose, onSubmit, formData, setFormData }) => {
|
|
12
12
|
const { formatMessage } = useIntl();
|
|
13
13
|
const [contextText, setContextText] = useState("");
|
|
@@ -60,7 +60,7 @@ const index = {
|
|
|
60
60
|
},
|
|
61
61
|
Component: () => import(
|
|
62
62
|
/* webpackChunkName: "magic-link-tokens" */
|
|
63
|
-
"./index-
|
|
63
|
+
"./index-B9Ch8Jpe.mjs"
|
|
64
64
|
),
|
|
65
65
|
permissions: pluginPermissions.access
|
|
66
66
|
});
|
|
@@ -82,7 +82,7 @@ const index = {
|
|
|
82
82
|
to: `${PLUGIN_ID}/config`,
|
|
83
83
|
Component: () => import(
|
|
84
84
|
/* webpackChunkName: "magic-link-settings" */
|
|
85
|
-
"./index-
|
|
85
|
+
"./index-SCxv154G.mjs"
|
|
86
86
|
),
|
|
87
87
|
permissions: pluginPermissions.readSettings
|
|
88
88
|
},
|
|
@@ -95,20 +95,7 @@ const index = {
|
|
|
95
95
|
to: `${PLUGIN_ID}/license`,
|
|
96
96
|
Component: () => import(
|
|
97
97
|
/* webpackChunkName: "magic-link-license" */
|
|
98
|
-
"./index-
|
|
99
|
-
),
|
|
100
|
-
permissions: pluginPermissions.access
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
intlLabel: {
|
|
104
|
-
id: getTrad("Form.title.Upgrade"),
|
|
105
|
-
defaultMessage: "Upgrade"
|
|
106
|
-
},
|
|
107
|
-
id: "magic-link-upgrade",
|
|
108
|
-
to: `${PLUGIN_ID}/upgrade`,
|
|
109
|
-
Component: () => import(
|
|
110
|
-
/* webpackChunkName: "magic-link-upgrade" */
|
|
111
|
-
"./LicensePage-CCNW2hT6.mjs"
|
|
98
|
+
"./index-Dufv-daf.mjs"
|
|
112
99
|
),
|
|
113
100
|
permissions: pluginPermissions.access
|
|
114
101
|
},
|
|
@@ -121,7 +108,7 @@ const index = {
|
|
|
121
108
|
to: `${PLUGIN_ID}/whatsapp`,
|
|
122
109
|
Component: () => import(
|
|
123
110
|
/* webpackChunkName: "magic-link-whatsapp" */
|
|
124
|
-
"./index-
|
|
111
|
+
"./index-DF3Edydl.mjs"
|
|
125
112
|
),
|
|
126
113
|
permissions: pluginPermissions.access
|
|
127
114
|
}
|
|
@@ -61,7 +61,7 @@ const index = {
|
|
|
61
61
|
},
|
|
62
62
|
Component: () => Promise.resolve().then(() => require(
|
|
63
63
|
/* webpackChunkName: "magic-link-tokens" */
|
|
64
|
-
"./index-
|
|
64
|
+
"./index-XYWLmmEs.js"
|
|
65
65
|
)),
|
|
66
66
|
permissions: pluginPermissions.access
|
|
67
67
|
});
|
|
@@ -83,7 +83,7 @@ const index = {
|
|
|
83
83
|
to: `${PLUGIN_ID}/config`,
|
|
84
84
|
Component: () => Promise.resolve().then(() => require(
|
|
85
85
|
/* webpackChunkName: "magic-link-settings" */
|
|
86
|
-
"./index-
|
|
86
|
+
"./index-zzoovbM0.js"
|
|
87
87
|
)),
|
|
88
88
|
permissions: pluginPermissions.readSettings
|
|
89
89
|
},
|
|
@@ -96,20 +96,7 @@ const index = {
|
|
|
96
96
|
to: `${PLUGIN_ID}/license`,
|
|
97
97
|
Component: () => Promise.resolve().then(() => require(
|
|
98
98
|
/* webpackChunkName: "magic-link-license" */
|
|
99
|
-
"./index-
|
|
100
|
-
)),
|
|
101
|
-
permissions: pluginPermissions.access
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
intlLabel: {
|
|
105
|
-
id: getTrad("Form.title.Upgrade"),
|
|
106
|
-
defaultMessage: "Upgrade"
|
|
107
|
-
},
|
|
108
|
-
id: "magic-link-upgrade",
|
|
109
|
-
to: `${PLUGIN_ID}/upgrade`,
|
|
110
|
-
Component: () => Promise.resolve().then(() => require(
|
|
111
|
-
/* webpackChunkName: "magic-link-upgrade" */
|
|
112
|
-
"./LicensePage-2M-vOJX8.js"
|
|
99
|
+
"./index-01GHNxSr.js"
|
|
113
100
|
)),
|
|
114
101
|
permissions: pluginPermissions.access
|
|
115
102
|
},
|
|
@@ -122,7 +109,7 @@ const index = {
|
|
|
122
109
|
to: `${PLUGIN_ID}/whatsapp`,
|
|
123
110
|
Component: () => Promise.resolve().then(() => require(
|
|
124
111
|
/* webpackChunkName: "magic-link-whatsapp" */
|
|
125
|
-
"./index-
|
|
112
|
+
"./index-I72rBTkL.js"
|
|
126
113
|
)),
|
|
127
114
|
permissions: pluginPermissions.access
|
|
128
115
|
}
|
|
@@ -5,7 +5,7 @@ import { useIntl } from "react-intl";
|
|
|
5
5
|
import { Flex, Loader, Box, Typography, Button, TextInput, Badge } from "@strapi/design-system";
|
|
6
6
|
import { Phone, Check, Message, ArrowClockwise } from "@strapi/icons";
|
|
7
7
|
import { useNotification, useFetchClient } from "@strapi/strapi/admin";
|
|
8
|
-
import { g as getTrad } from "./index-
|
|
8
|
+
import { g as getTrad } from "./index-Bj-erY7g.mjs";
|
|
9
9
|
const theme = {
|
|
10
10
|
colors: {
|
|
11
11
|
primary: { 700: "#075985", 100: "#E0F2FE", 50: "#F0F9FF" },
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useEffect } from "react";
|
|
3
3
|
import { Loader, Box, Alert, Flex, Typography, Button, Badge, Accordion } from "@strapi/design-system";
|
|
4
4
|
import { useFetchClient, useNotification } from "@strapi/strapi/admin";
|
|
5
|
-
import { ArrowClockwise, Duplicate, Download, User, Shield,
|
|
5
|
+
import { ArrowClockwise, Duplicate, Download, User, Shield, ChartBubble } from "@strapi/icons";
|
|
6
6
|
import styled, { keyframes } from "styled-components";
|
|
7
7
|
const theme = {
|
|
8
8
|
colors: {
|
|
@@ -172,8 +172,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
172
172
|
if (error) {
|
|
173
173
|
return /* @__PURE__ */ jsx(Container, { children: /* @__PURE__ */ jsx(Box, { padding: 8, children: /* @__PURE__ */ jsx(Alert, { variant: "danger", title: "Error", children: error }) }) });
|
|
174
174
|
}
|
|
175
|
-
const isValid = licenseData?.valid;
|
|
176
|
-
const
|
|
175
|
+
const isValid = licenseData?.valid !== false;
|
|
176
|
+
const hasKey = !!licenseData?.hasKey;
|
|
177
177
|
const data = licenseData?.data || {};
|
|
178
178
|
return /* @__PURE__ */ jsxs(Container, { children: [
|
|
179
179
|
/* @__PURE__ */ jsx(StickySaveBar, { paddingTop: 5, paddingBottom: 5, paddingLeft: 6, paddingRight: 6, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
@@ -198,7 +198,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
198
198
|
)
|
|
199
199
|
] }) }),
|
|
200
200
|
/* @__PURE__ */ jsxs(Box, { paddingTop: 6, paddingLeft: 6, paddingRight: 6, paddingBottom: 10, children: [
|
|
201
|
-
|
|
201
|
+
hasKey && isValid ? /* @__PURE__ */ jsx(Alert, { variant: "success", title: "License Active", children: "License key registered. Thanks for supporting the plugin!" }) : hasKey && !isValid ? /* @__PURE__ */ jsx(Alert, { variant: "warning", title: "License Verification", children: "We couldn't reach the license server right now. The plugin keeps working — try Refresh Status later." }) : /* @__PURE__ */ jsx(Alert, { variant: "default", title: "No license key registered", children: 'All Magic Link features are available without activation. If you want to register a license key, use the form below or run "Auto-Activate" to generate one for your admin email.' }),
|
|
202
202
|
data.licenseKey && /* @__PURE__ */ jsx(Box, { marginTop: 6, children: /* @__PURE__ */ jsx(LicenseKeyBanner, { children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "flex-start", children: [
|
|
203
203
|
/* @__PURE__ */ jsxs(Box, { style: { flex: 1 }, children: [
|
|
204
204
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", style: { color: "rgba(255,255,255,0.8)", marginBottom: "12px", textTransform: "uppercase", fontSize: "11px", letterSpacing: "0.5px", display: "block" }, children: "License Key" }),
|
|
@@ -283,45 +283,16 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
283
283
|
] })
|
|
284
284
|
] }) }) })
|
|
285
285
|
] }),
|
|
286
|
-
/* @__PURE__ */ jsxs(Accordion.Item, { value: "features", children: [
|
|
287
|
-
/* @__PURE__ */ jsx(Accordion.Header, { children: /* @__PURE__ */ jsx(Accordion.Trigger, { icon: Sparkle, children: "Features & Capabilities" }) }),
|
|
288
|
-
/* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(Box, { padding: 6, children: /* @__PURE__ */ jsxs(Flex, { gap: 8, wrap: "wrap", children: [
|
|
289
|
-
/* @__PURE__ */ jsxs(Box, { style: { flex: "1", minWidth: "180px" }, children: [
|
|
290
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Premium Features" }),
|
|
291
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: data.features?.premium ? "✓ Enabled" : "✗ Disabled" })
|
|
292
|
-
] }),
|
|
293
|
-
/* @__PURE__ */ jsxs(Box, { style: { flex: "1", minWidth: "180px" }, children: [
|
|
294
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Advanced Features" }),
|
|
295
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: data.features?.advanced ? "✓ Enabled" : "✗ Disabled" })
|
|
296
|
-
] }),
|
|
297
|
-
/* @__PURE__ */ jsxs(Box, { style: { flex: "1", minWidth: "180px" }, children: [
|
|
298
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Enterprise Features" }),
|
|
299
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: data.features?.enterprise ? "✓ Enabled" : "✗ Disabled" })
|
|
300
|
-
] })
|
|
301
|
-
] }) }) })
|
|
302
|
-
] }),
|
|
303
286
|
/* @__PURE__ */ jsxs(Accordion.Item, { value: "status", children: [
|
|
304
287
|
/* @__PURE__ */ jsx(Accordion.Header, { children: /* @__PURE__ */ jsx(Accordion.Trigger, { icon: ChartBubble, children: "System Status" }) }),
|
|
305
288
|
/* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(Box, { padding: 6, children: /* @__PURE__ */ jsxs(Flex, { gap: 8, wrap: "wrap", children: [
|
|
306
289
|
/* @__PURE__ */ jsxs(Box, { style: { flex: "1", minWidth: "150px" }, children: [
|
|
307
290
|
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "License Status" }),
|
|
308
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: data.isActive ? "Active" : "Inactive" })
|
|
309
|
-
] }),
|
|
310
|
-
/* @__PURE__ */ jsxs(Box, { style: { flex: "1", minWidth: "150px" }, children: [
|
|
311
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Connection" }),
|
|
312
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: data.isOnline ? "Online" : "Offline" })
|
|
313
|
-
] }),
|
|
314
|
-
/* @__PURE__ */ jsxs(Box, { style: { flex: "1", minWidth: "150px" }, children: [
|
|
315
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Last Sync" }),
|
|
316
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: data.lastPingAt ? new Date(data.lastPingAt).toLocaleTimeString() : "Never" })
|
|
291
|
+
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: hasKey ? data.isActive ? "Active" : "Inactive" : "No key registered" })
|
|
317
292
|
] }),
|
|
318
293
|
/* @__PURE__ */ jsxs(Box, { style: { flex: "1", minWidth: "150px" }, children: [
|
|
319
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "
|
|
320
|
-
/* @__PURE__ */
|
|
321
|
-
data.currentDevices || 0,
|
|
322
|
-
" / ",
|
|
323
|
-
data.maxDevices || 1
|
|
324
|
-
] })
|
|
294
|
+
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: "Plugin Mode" }),
|
|
295
|
+
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: "Fully unlocked" })
|
|
325
296
|
] })
|
|
326
297
|
] }) }) })
|
|
327
298
|
] })
|
|
@@ -7,7 +7,7 @@ const reactIntl = require("react-intl");
|
|
|
7
7
|
const designSystem = require("@strapi/design-system");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
const admin = require("@strapi/strapi/admin");
|
|
10
|
-
const index = require("./index-
|
|
10
|
+
const index = require("./index-CGxbhJfg.js");
|
|
11
11
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
12
12
|
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
13
13
|
const theme = {
|