strapi-plugin-magic-link-v5 4.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/.eslintignore +1 -0
- package/.github/workflows/semantic-release.yml +27 -0
- package/README.md +318 -0
- package/admin/jsconfig.json +10 -0
- package/admin/src/components/Initializer/index.jsx +20 -0
- package/admin/src/components/Initializer.jsx +18 -0
- package/admin/src/components/LazyComponentLoader.jsx +27 -0
- package/admin/src/components/PluginIcon/index.jsx +6 -0
- package/admin/src/components/PluginIcon.jsx +5 -0
- package/admin/src/index.js +101 -0
- package/admin/src/pages/App/index.jsx +50 -0
- package/admin/src/pages/App.jsx +15 -0
- package/admin/src/pages/HomePage/index.js +2 -0
- package/admin/src/pages/HomePage/index.jsx +228 -0
- package/admin/src/pages/HomePage.jsx +655 -0
- package/admin/src/pages/Settings/index.jsx +1289 -0
- package/admin/src/pages/Settings/utils/api.js +13 -0
- package/admin/src/pages/Settings/utils/index.js +5 -0
- package/admin/src/pages/Settings/utils/layout.js +100 -0
- package/admin/src/pages/Settings/utils/schema.js +18 -0
- package/admin/src/pages/Tokens/index.jsx +2250 -0
- package/admin/src/permissions.js +7 -0
- package/admin/src/pluginId.js +3 -0
- package/admin/src/routes.js +40 -0
- package/admin/src/translations/de.json +188 -0
- package/admin/src/translations/en.json +189 -0
- package/admin/src/utils/getRequestURL.js +5 -0
- package/admin/src/utils/getTrad.js +17 -0
- package/admin/src/utils/getTranslation.js +3 -0
- package/admin/src/utils/index.js +4 -0
- package/build.js +75 -0
- package/package.json +59 -0
- package/server/bootstrap.js +127 -0
- package/server/controllers/settings.js +122 -0
- package/server/jsconfig.json +10 -0
- package/server/services/store.js +35 -0
- package/server/src/bootstrap.js +110 -0
- package/server/src/config/index.js +6 -0
- package/server/src/content-types/index.js +7 -0
- package/server/src/content-types/token/index.js +5 -0
- package/server/src/content-types/token/schema.json +47 -0
- package/server/src/controllers/auth.js +211 -0
- package/server/src/controllers/controller.js +213 -0
- package/server/src/controllers/index.js +16 -0
- package/server/src/controllers/jwt.js +261 -0
- package/server/src/controllers/tokens.js +654 -0
- package/server/src/destroy.js +5 -0
- package/server/src/index.js +33 -0
- package/server/src/middlewares/index.js +3 -0
- package/server/src/policies/index.js +3 -0
- package/server/src/register.js +5 -0
- package/server/src/routes/admin.js +160 -0
- package/server/src/routes/content-api.js +27 -0
- package/server/src/routes/index.js +9 -0
- package/server/src/services/index.js +11 -0
- package/server/src/services/magic-link.js +356 -0
- package/server/src/services/service.js +13 -0
- package/server/utils/index.js +14 -0
- package/strapi-admin.js +82 -0
- package/strapi-server.js +4 -0
- package/vite.config.js +36 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const pluginPermissions = {
|
|
2
|
+
accessSettings: [{ action: 'plugin::magic-link.settings.read', subject: null }],
|
|
3
|
+
readSettings: [{ action: 'plugin::magic-link.settings.read', subject: null }],
|
|
4
|
+
updateSettings: [{ action: 'plugin::magic-link.settings.update', subject: null }],
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default pluginPermissions;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import pluginId from './pluginId';
|
|
3
|
+
|
|
4
|
+
const routes = [
|
|
5
|
+
{
|
|
6
|
+
path: `/plugins/${pluginId}`,
|
|
7
|
+
async Component() {
|
|
8
|
+
const { default: Component } = await import('./pages/HomePage');
|
|
9
|
+
return (
|
|
10
|
+
<React.Suspense fallback={<div>Loading...</div>}>
|
|
11
|
+
<Component />
|
|
12
|
+
</React.Suspense>
|
|
13
|
+
);
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
path: `/plugins/${pluginId}/tokens`,
|
|
18
|
+
async Component() {
|
|
19
|
+
const { default: Component } = await import('./pages/Tokens');
|
|
20
|
+
return (
|
|
21
|
+
<React.Suspense fallback={<div>Loading...</div>}>
|
|
22
|
+
<Component />
|
|
23
|
+
</React.Suspense>
|
|
24
|
+
);
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
path: `/settings/${pluginId}`,
|
|
29
|
+
async Component() {
|
|
30
|
+
const { default: Component } = await import('./pages/Settings');
|
|
31
|
+
return (
|
|
32
|
+
<React.Suspense fallback={<div>Loading...</div>}>
|
|
33
|
+
<Component />
|
|
34
|
+
</React.Suspense>
|
|
35
|
+
);
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export default routes;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugin.name": "Magic Link",
|
|
3
|
+
"Header.Settings": "Magic Link",
|
|
4
|
+
"Form.title.Settings": "Einstellungen",
|
|
5
|
+
"pages.HomePage.header.description": "Konfigurieren Sie Ihren passwortlosen Login über die Einstellungsseite.",
|
|
6
|
+
"pages.HomePage.content": "Dieses Plugin ermöglicht Benutzern, sich ohne Passwort anzumelden, indem ein Magic Link an ihre E-Mail gesendet wird.",
|
|
7
|
+
"pages.HomePage.tokens": "Token-Verwaltung",
|
|
8
|
+
"pages.HomePage.tokens.description": "Verwalten Sie aktive Anmelde-Tokens",
|
|
9
|
+
"pages.HomePage.tokens.cta": "Tokens verwalten",
|
|
10
|
+
"pages.HomePage.settings": "Einstellungen",
|
|
11
|
+
"pages.HomePage.settings.description": "Konfigurieren Sie die Magic-Link-Plugin-Einstellungen",
|
|
12
|
+
"pages.HomePage.settings.cta": "Zu den Einstellungen",
|
|
13
|
+
"pages.HomePage.users": "Benutzer",
|
|
14
|
+
"pages.HomePage.users.description": "Verwalten Sie Ihre Benutzer im Benutzerverwaltungsbereich",
|
|
15
|
+
"pages.HomePage.users.cta": "Benutzer verwalten",
|
|
16
|
+
"pages.HomePage.welcome": "Willkommen beim Magic Link Plugin",
|
|
17
|
+
|
|
18
|
+
"Settings.enabled.label": "Magic Link aktivieren",
|
|
19
|
+
"Settings.enabled.description": "Ermöglicht eine sichere und nahtlose Authentifizierung per E-Mail-Link.",
|
|
20
|
+
"Settings.createUser.label": "Neue Benutzer erstellen",
|
|
21
|
+
"Settings.createUser.description": "Erstellen Sie einen neuen Benutzer per E-Mail, wenn er nicht existiert.",
|
|
22
|
+
"Settings.expirePeriod.label": "Ablaufzeit (Sekunden)",
|
|
23
|
+
"Settings.expirePeriod.description": "Zeit in Sekunden, bis der Magic Link abläuft.",
|
|
24
|
+
"Settings.tokenLength.label": "Token-Länge",
|
|
25
|
+
"Settings.tokenLength.description": "Länge des generierten Tokens.",
|
|
26
|
+
"Settings.staysValid.label": "Token bleibt nach Verwendung gültig",
|
|
27
|
+
"Settings.staysValid.description": "Wenn aktiviert, bleibt das Token nach der Verwendung gültig.",
|
|
28
|
+
"Settings.confirmationUrl.label": "Bestätigungs-URL",
|
|
29
|
+
"Settings.confirmationUrl.description": "Die URL, zu der Benutzer nach dem Klicken auf den Magic Link weitergeleitet werden.",
|
|
30
|
+
|
|
31
|
+
"Settings.general.title": "Allgemeine Einstellungen",
|
|
32
|
+
"Settings.authentication.title": "Authentifizierungseinstellungen",
|
|
33
|
+
"Settings.email.title": "E-Mail-Einstellungen",
|
|
34
|
+
|
|
35
|
+
"Settings.maxLoginAttempts.label": "Maximale Anmeldeversuche",
|
|
36
|
+
"Settings.maxLoginAttempts.description": "Maximale Anzahl von Anmeldeversuchen, bevor die Blockierung erfolgt.",
|
|
37
|
+
"Settings.loginPath.label": "Login-API-Pfad",
|
|
38
|
+
"Settings.loginPath.description": "API-Pfad für den Login-Endpunkt.",
|
|
39
|
+
"Settings.callbackUrl.label": "Callback-URL",
|
|
40
|
+
"Settings.callbackUrl.description": "Die URL, zu der Benutzer nach erfolgreicher Authentifizierung weitergeleitet werden.",
|
|
41
|
+
|
|
42
|
+
"Settings.userCreationStrategy.label": "Benutzererstellungsstrategie",
|
|
43
|
+
"Settings.userCreationStrategy.email": "Nur E-Mail",
|
|
44
|
+
"Settings.userCreationStrategy.emailUsername": "E-Mail + Benutzername (aus E-Mail)",
|
|
45
|
+
"Settings.userCreationStrategy.manual": "Keine automatische Erstellung",
|
|
46
|
+
|
|
47
|
+
"Settings.verifyEmail.label": "E-Mail verifizieren",
|
|
48
|
+
"Settings.verifyEmail.description": "E-Mail des Benutzers vor der Authentifizierung verifizieren.",
|
|
49
|
+
"Settings.welcomeEmail.label": "Willkommens-E-Mail senden",
|
|
50
|
+
"Settings.welcomeEmail.description": "Sendet eine Willkommens-E-Mail an neue Benutzer.",
|
|
51
|
+
"Settings.useJwtToken.label": "JWT-Token verwenden",
|
|
52
|
+
"Settings.useJwtToken.description": "JWT-Token für die Authentifizierung verwenden.",
|
|
53
|
+
"Settings.jwtTokenExpiresIn.label": "JWT-Token-Ablaufzeit",
|
|
54
|
+
"Settings.jwtTokenExpiresIn.description": "Ablaufzeit für JWT-Tokens (z.B. \"1h\", \"7d\").",
|
|
55
|
+
"Settings.allowMagicLinksOnPublicRegistration.label": "Magic Links bei öffentlicher Registrierung erlauben",
|
|
56
|
+
"Settings.allowMagicLinksOnPublicRegistration.description": "Erlaubt die Verwendung von Magic Links bei öffentlichen Registrierungsformularen.",
|
|
57
|
+
|
|
58
|
+
"Settings.fromName.label": "Absendername",
|
|
59
|
+
"Settings.fromName.description": "Name, der im Absenderfeld der E-Mail angezeigt wird.",
|
|
60
|
+
"Settings.fromEmail.label": "Absender-E-Mail",
|
|
61
|
+
"Settings.fromEmail.description": "E-Mail-Adresse, die zum Senden des Magic Links verwendet wird.",
|
|
62
|
+
"Settings.responseEmail.label": "Antwort-E-Mail",
|
|
63
|
+
"Settings.responseEmail.description": "E-Mail-Adresse für Antworten (optional).",
|
|
64
|
+
"Settings.object.label": "E-Mail-Betreff",
|
|
65
|
+
"Settings.object.description": "Betreffzeile der Magic-Link-E-Mail.",
|
|
66
|
+
"Settings.messageHtml.label": "HTML-Nachricht",
|
|
67
|
+
"Settings.messageHtml.description": "HTML-Inhalt der E-Mail. Verwenden Sie <%= URL %> für die Basis-URL und <%= CODE %> für das Token.",
|
|
68
|
+
"Settings.messageText.label": "Textnachricht",
|
|
69
|
+
"Settings.messageText.description": "Klartext-Inhalt der E-Mail. Verwenden Sie <%= URL %> für die Basis-URL und <%= CODE %> für das Token.",
|
|
70
|
+
|
|
71
|
+
"Settings.description": "Konfigurieren Sie das Magic Link Plugin",
|
|
72
|
+
|
|
73
|
+
"settings": {
|
|
74
|
+
"header": {
|
|
75
|
+
"title": "Magic Link Einstellungen",
|
|
76
|
+
"description": "Konfigurieren Sie eine sichere passwortlose Authentifizierung für Ihre Benutzer"
|
|
77
|
+
},
|
|
78
|
+
"general": {
|
|
79
|
+
"title": "Allgemeine Einstellungen",
|
|
80
|
+
"description": "Grundlegende Konfiguration für die Magic Link-Funktionalität",
|
|
81
|
+
"featureToggles": "FUNKTIONSSCHALTER",
|
|
82
|
+
"enableMagicLink": "Magic Link aktivieren",
|
|
83
|
+
"enableMagicLink.hint": "Ermöglicht eine sichere und nahtlose Authentifizierung über E-Mail-Links.",
|
|
84
|
+
"createNewUsers": "Neue Benutzer erstellen",
|
|
85
|
+
"createNewUsers.hint": "Erstellt einen neuen Benutzer anhand der E-Mail, wenn dieser nicht existiert.",
|
|
86
|
+
"tokenStaysValid": "Token bleibt nach Verwendung gültig",
|
|
87
|
+
"tokenStaysValid.hint": "Wenn aktiviert, bleibt der Token nach der Verwendung gültig. Weniger sicher, aber komfortabler.",
|
|
88
|
+
"expirationPeriod": "Ablaufzeitraum",
|
|
89
|
+
"expirationPeriod.label": "Ablaufzeitraum in Sekunden",
|
|
90
|
+
"expirationPeriod.hint": "Zeit in Sekunden, bis der Magic Link abläuft. Standard: 3600 (1 Stunde)",
|
|
91
|
+
"tokenLength": "Token-Länge",
|
|
92
|
+
"tokenLength.label": "Token-Länge",
|
|
93
|
+
"tokenLength.hint": "Länge des generierten Tokens. Empfohlen: 20-40 Zeichen",
|
|
94
|
+
"maxLoginAttempts": "Maximale Anmeldeversuche",
|
|
95
|
+
"maxLoginAttempts.label": "Maximale Anmeldeversuche",
|
|
96
|
+
"maxLoginAttempts.hint": "Maximale Anzahl an Anmeldeversuchen, bevor die Blockierung erfolgt. Auf 0 setzen, um zu deaktivieren.",
|
|
97
|
+
"loginPath": "Login-API-Pfad",
|
|
98
|
+
"loginPath.label": "Login-API-Pfad",
|
|
99
|
+
"loginPath.hint": "API-Pfad für den Login-Endpunkt. Standard: /passwordless-login",
|
|
100
|
+
"confirmationUrl": "Bestätigungs-URL",
|
|
101
|
+
"confirmationUrl.label": "Bestätigungs-URL",
|
|
102
|
+
"confirmationUrl.hint": "Die URL, zu der Benutzer nach dem Klicken auf den Magic Link weitergeleitet werden.",
|
|
103
|
+
"callbackUrl": "Callback-URL",
|
|
104
|
+
"callbackUrl.label": "Callback-URL",
|
|
105
|
+
"callbackUrl.hint": "Die URL, zu der Benutzer nach erfolgreicher Authentifizierung weitergeleitet werden."
|
|
106
|
+
},
|
|
107
|
+
"authentication": {
|
|
108
|
+
"title": "Authentifizierungseinstellungen",
|
|
109
|
+
"description": "Konfigurieren Sie, wie Benutzer authentifiziert und erstellt werden",
|
|
110
|
+
"options": "Authentifizierungsoptionen",
|
|
111
|
+
"verifyEmail": "E-Mail verifizieren",
|
|
112
|
+
"verifyEmail.hint": "Verifizieren Sie die Benutzer-E-Mail, bevor Sie die Authentifizierung zulassen. Erhöht die Sicherheit.",
|
|
113
|
+
"welcomeEmail": "Willkommens-E-Mail senden",
|
|
114
|
+
"welcomeEmail.hint": "Sendet eine Willkommens-E-Mail an neue Benutzer, wenn sie erstellt werden.",
|
|
115
|
+
"useJwtToken": "JWT-Token verwenden",
|
|
116
|
+
"useJwtToken.hint": "Verwenden Sie JWT-Token für die Authentifizierung anstelle von Session-Cookies.",
|
|
117
|
+
"allowOnPublicRegistration": "Bei öffentlicher Registrierung erlauben",
|
|
118
|
+
"allowOnPublicRegistration.hint": "Erlaubt die Verwendung von Magic Links bei der öffentlichen Registrierung.",
|
|
119
|
+
"storeLoginInfo": "Login-Informationen speichern",
|
|
120
|
+
"storeLoginInfo.hint": "Speichert User-Agent und IP-Adresse für jeden Anmeldeversuch. Verbessert die Sicherheitsüberwachung.",
|
|
121
|
+
"userCreationStrategy": "Benutzer-Erstellungsstrategie",
|
|
122
|
+
"userCreationStrategy.label": "Wählen Sie aus, wie Benutzer erstellt werden",
|
|
123
|
+
"userCreationStrategy.placeholder": "Wählen Sie eine Strategie",
|
|
124
|
+
"userCreationStrategy.email": "Nur E-Mail - Benutzer nur mit E-Mail erstellen",
|
|
125
|
+
"userCreationStrategy.emailUsername": "E-Mail + Benutzername - Benutzer mit E-Mail erstellen und Benutzernamen daraus generieren",
|
|
126
|
+
"userCreationStrategy.manual": "Keine automatische Erstellung - Benutzer müssen zuerst manuell erstellt werden",
|
|
127
|
+
"jwtTokenExpiration": "JWT-Token-Ablauf",
|
|
128
|
+
"jwtTokenExpiration.label": "JWT-Token-Ablaufzeit",
|
|
129
|
+
"jwtTokenExpiration.hint": "Beispiele: '1h' (1 Stunde), '7d' (7 Tage), '30d' (30 Tage)"
|
|
130
|
+
},
|
|
131
|
+
"email": {
|
|
132
|
+
"title": "E-Mail-Einstellungen",
|
|
133
|
+
"description": "Konfigurieren Sie E-Mail-Vorlagen und Absenderinformationen",
|
|
134
|
+
"template": {
|
|
135
|
+
"placeholder": "Beispiel: <a href=\"<%= URL %>?code=<%= CODE %>\">Hier klicken, um sich anzumelden</a>"
|
|
136
|
+
},
|
|
137
|
+
"senderName": "Absendername",
|
|
138
|
+
"senderName.label": "Absendername",
|
|
139
|
+
"senderName.hint": "Name, der im Absenderfeld der E-Mail angezeigt wird.",
|
|
140
|
+
"senderEmail": "Absender-E-Mail",
|
|
141
|
+
"senderEmail.label": "Absender-E-Mail",
|
|
142
|
+
"senderEmail.hint": "E-Mail-Adresse, die zum Senden des Magic Links verwendet wird.",
|
|
143
|
+
"replyToEmail": "Antwort-E-Mail",
|
|
144
|
+
"replyToEmail.label": "Antwort-E-Mail (optional)",
|
|
145
|
+
"replyToEmail.hint": "E-Mail-Adresse für Antworten.",
|
|
146
|
+
"subject": "E-Mail-Betreff",
|
|
147
|
+
"subject.label": "E-Mail-Betreffzeile",
|
|
148
|
+
"subject.hint": "Betreffzeile der Magic-Link-E-Mail.",
|
|
149
|
+
"templates": "E-Mail-Vorlagen",
|
|
150
|
+
"htmlTemplate": "HTML-E-Mail-Vorlage",
|
|
151
|
+
"htmlTemplate.description": "HTML-formatierte E-Mail, die an Benutzer gesendet wird",
|
|
152
|
+
"htmlTemplate.label": "HTML-Nachrichtenvorlage",
|
|
153
|
+
"htmlTemplate.hint": "Verwenden Sie <%= URL %> für die Basis-URL und <%= CODE %> für den Token. Sie können HTML-Formatierung verwenden, um Ihre E-Mail ansprechender zu gestalten.",
|
|
154
|
+
"textTemplate": "Nur-Text-E-Mail-Vorlage",
|
|
155
|
+
"textTemplate.description": "Nur-Text-Alternative für E-Mail-Clients, die kein HTML unterstützen",
|
|
156
|
+
"textTemplate.label": "Text-Nachrichtenvorlage",
|
|
157
|
+
"textTemplate.hint": "Verwenden Sie <%= URL %> für die Basis-URL und <%= CODE %> für den Token. Diese Version wird für E-Mail-Clients verwendet, die kein HTML anzeigen können."
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
"tokens.title": "Magic Link Tokens",
|
|
162
|
+
"tokens.subtitle": "Verwalten Sie aktive Anmelde-Tokens",
|
|
163
|
+
"tokens.refresh": "Aktualisieren",
|
|
164
|
+
"tokens.active.title": "Aktive Tokens",
|
|
165
|
+
"tokens.active.description": "Sehen und verwalten Sie alle aktiven Anmelde-Tokens. Sie können verdächtige Logins oder Tokens blockieren.",
|
|
166
|
+
"tokens.loading": "Tokens werden geladen...",
|
|
167
|
+
"tokens.empty": "Keine aktiven Tokens gefunden. Alle Ihre Magic Links sind entweder abgelaufen oder wurden bereits verwendet.",
|
|
168
|
+
"tokens.email": "E-Mail",
|
|
169
|
+
"tokens.user": "Benutzer",
|
|
170
|
+
"tokens.status": "Status",
|
|
171
|
+
"tokens.created": "Erstellt",
|
|
172
|
+
"tokens.expires": "Läuft ab",
|
|
173
|
+
"tokens.lastUsed": "Zuletzt verwendet",
|
|
174
|
+
"tokens.actions": "Aktionen",
|
|
175
|
+
"tokens.view": "Details anzeigen",
|
|
176
|
+
"tokens.block": "Token blockieren",
|
|
177
|
+
"tokens.status.active": "Aktiv",
|
|
178
|
+
"tokens.status.expired": "Abgelaufen",
|
|
179
|
+
"tokens.status.blocked": "Blockiert",
|
|
180
|
+
"tokens.loading.user": "Wird geladen...",
|
|
181
|
+
"tokens.fetch.error": "Fehler beim Abrufen der Tokens",
|
|
182
|
+
"tokens.block.success": "Token erfolgreich blockiert",
|
|
183
|
+
"tokens.block.error": "Fehler beim Blockieren des Tokens",
|
|
184
|
+
|
|
185
|
+
"app.error": "Ein Fehler ist aufgetreten",
|
|
186
|
+
"app.error.message": "Es scheint ein Problem in Ihrer Instanz zu geben. Bitte benachrichtigen Sie Ihr technisches Team.",
|
|
187
|
+
"app.error.copy": "In Zwischenablage kopieren"
|
|
188
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugin.name": "Magic Link",
|
|
3
|
+
"Header.Settings": "Magic Link",
|
|
4
|
+
"Form.title.Settings": "Settings",
|
|
5
|
+
"pages.HomePage.header.description": "Configure your passwordless login through the Settings page.",
|
|
6
|
+
"pages.HomePage.content": "This plugin allows users to log in without a password using a magic link sent to their email.",
|
|
7
|
+
"pages.HomePage.tokens": "Token Management",
|
|
8
|
+
"pages.HomePage.tokens.description": "View and manage active login tokens",
|
|
9
|
+
"pages.HomePage.tokens.cta": "Manage Tokens",
|
|
10
|
+
"pages.HomePage.settings": "Settings",
|
|
11
|
+
"pages.HomePage.settings.description": "Configure the Magic Link plugin settings",
|
|
12
|
+
"pages.HomePage.settings.cta": "Go to Settings",
|
|
13
|
+
"pages.HomePage.users": "Users",
|
|
14
|
+
"pages.HomePage.users.description": "Manage your users in the User Management section",
|
|
15
|
+
"pages.HomePage.users.cta": "Manage Users",
|
|
16
|
+
"pages.HomePage.welcome": "Welcome to the Magic Link Plugin",
|
|
17
|
+
"Settings.enabled.description": "Enables a secure and seamless emailed link authentication.",
|
|
18
|
+
"Settings.createUser.description": "Create new user by email if it doesn't exist.",
|
|
19
|
+
"Settings.createUser.label": "Create new users",
|
|
20
|
+
"Settings.expirePeriod.label": "Expiration period (seconds)",
|
|
21
|
+
"Settings.expirePeriod.description": "Time in seconds until the magic link expires.",
|
|
22
|
+
"Settings.tokenLength.label": "Token length",
|
|
23
|
+
"Settings.tokenLength.description": "Length of the generated token.",
|
|
24
|
+
"Settings.staysValid.label": "Token stays valid after use",
|
|
25
|
+
"Settings.staysValid.description": "If enabled, the token will remain valid after being used.",
|
|
26
|
+
"Settings.confirmationUrl.label": "Confirmation URL",
|
|
27
|
+
"Settings.confirmationUrl.description": "The URL where users will be redirected after clicking the magic link.",
|
|
28
|
+
"Settings.general.title": "General Settings",
|
|
29
|
+
"Settings.authentication.title": "Authentication Settings",
|
|
30
|
+
"Settings.email.title": "Email Settings",
|
|
31
|
+
"Settings.maxLoginAttempts.label": "Max login attempts",
|
|
32
|
+
"Settings.maxLoginAttempts.description": "Maximum number of login attempts before blocking.",
|
|
33
|
+
"Settings.loginPath.label": "Login API path",
|
|
34
|
+
"Settings.loginPath.description": "API path for the login endpoint.",
|
|
35
|
+
"Settings.callbackUrl.label": "Callback URL",
|
|
36
|
+
"Settings.callbackUrl.description": "The URL users will be redirected to after successful authentication.",
|
|
37
|
+
"Settings.userCreationStrategy.label": "User creation strategy",
|
|
38
|
+
"Settings.userCreationStrategy.email": "Email only",
|
|
39
|
+
"Settings.userCreationStrategy.emailUsername": "Email + Username (from email)",
|
|
40
|
+
"Settings.userCreationStrategy.manual": "No automatic creation",
|
|
41
|
+
"Settings.verifyEmail.label": "Verify email",
|
|
42
|
+
"Settings.verifyEmail.description": "Verify user email before allowing authentication.",
|
|
43
|
+
"Settings.welcomeEmail.label": "Send welcome email",
|
|
44
|
+
"Settings.welcomeEmail.description": "Send a welcome email to new users.",
|
|
45
|
+
"Settings.useJwtToken.label": "Use JWT token",
|
|
46
|
+
"Settings.useJwtToken.description": "Use JWT token for authentication.",
|
|
47
|
+
"Settings.jwtTokenExpiresIn.label": "JWT token expiration",
|
|
48
|
+
"Settings.jwtTokenExpiresIn.description": "Expiration time for JWT tokens (e.g., \"1h\", \"7d\").",
|
|
49
|
+
"Settings.allowMagicLinksOnPublicRegistration.label": "Allow magic links on public registration",
|
|
50
|
+
"Settings.allowMagicLinksOnPublicRegistration.description": "Allow magic links to be used on public registration forms.",
|
|
51
|
+
"Settings.fromName.label": "From name",
|
|
52
|
+
"Settings.fromName.description": "Name displayed in the from field of the email.",
|
|
53
|
+
"Settings.fromEmail.label": "From email",
|
|
54
|
+
"Settings.fromEmail.description": "Email address used to send the magic link.",
|
|
55
|
+
"Settings.responseEmail.label": "Response email",
|
|
56
|
+
"Settings.responseEmail.description": "Email address for replies (optional).",
|
|
57
|
+
"Settings.object.label": "Email subject",
|
|
58
|
+
"Settings.object.description": "Subject line of the magic link email.",
|
|
59
|
+
"Settings.messageHtml.label": "HTML message",
|
|
60
|
+
"Settings.messageHtml.description": "HTML content of the email. Use <%= URL %> for the base URL and <%= CODE %> for the token.",
|
|
61
|
+
"Settings.messageText.label": "Text message",
|
|
62
|
+
"Settings.messageText.description": "Plain text content of the email. Use <%= URL %> for the base URL and <%= CODE %> for the token.",
|
|
63
|
+
"Settings.description": "Configure the Magic Link plugin",
|
|
64
|
+
"Email.options.from.email.label": "Sender email",
|
|
65
|
+
"Email.options.from.email.placeholder": "example@domain.com",
|
|
66
|
+
"Email.options.from.name.label": "Sender name",
|
|
67
|
+
"Email.options.from.name.placeholder": "Your Name",
|
|
68
|
+
"Email.options.message_text.label": "Message (text)",
|
|
69
|
+
"Email.options.message_html.label": "Message (html)",
|
|
70
|
+
"Email.options.object.label": "Subject",
|
|
71
|
+
"Email.options.object.placeholder": "Magic Link Login for your site",
|
|
72
|
+
"Email.options.response_email.label": "Reply-to email",
|
|
73
|
+
"Email.options.response_email.placeholder": "replies@domain.com",
|
|
74
|
+
"Warning.button.cancel": "Cancel",
|
|
75
|
+
"Warning.button.confirm": "Confirm",
|
|
76
|
+
"Warning.title": "Please confirm",
|
|
77
|
+
"Warning.warning.cancel": "Are you sure you want to cancel your modifications?",
|
|
78
|
+
"notification.success.submit": "Settings have been updated",
|
|
79
|
+
"settings": {
|
|
80
|
+
"header": {
|
|
81
|
+
"title": "Magic Link Settings",
|
|
82
|
+
"description": "Configure secure passwordless authentication for your users"
|
|
83
|
+
},
|
|
84
|
+
"general": {
|
|
85
|
+
"title": "General Settings",
|
|
86
|
+
"description": "Basic configuration for the Magic Link functionality",
|
|
87
|
+
"featureToggles": "FEATURE TOGGLES",
|
|
88
|
+
"enableMagicLink": "Enable Magic Link",
|
|
89
|
+
"enableMagicLink.hint": "Enables a secure and seamless emailed link authentication.",
|
|
90
|
+
"createNewUsers": "Create New Users",
|
|
91
|
+
"createNewUsers.hint": "Create new user by email if it doesn't exist.",
|
|
92
|
+
"tokenStaysValid": "Token Stays Valid After Use",
|
|
93
|
+
"tokenStaysValid.hint": "If enabled, the token will remain valid after being used. Less secure but more convenient.",
|
|
94
|
+
"expirationPeriod": "Expiration Period",
|
|
95
|
+
"expirationPeriod.label": "Expiration period in seconds",
|
|
96
|
+
"expirationPeriod.hint": "Time in seconds until the magic link expires. Default: 3600 (1 hour)",
|
|
97
|
+
"tokenLength": "Token Length",
|
|
98
|
+
"tokenLength.label": "Token length",
|
|
99
|
+
"tokenLength.hint": "Length of the generated token. Recommended: 20-40 characters",
|
|
100
|
+
"maxLoginAttempts": "Maximum Login Attempts",
|
|
101
|
+
"maxLoginAttempts.label": "Max login attempts",
|
|
102
|
+
"maxLoginAttempts.hint": "Maximum number of login attempts before blocking. Set to 0 to disable.",
|
|
103
|
+
"loginPath": "Login API Path",
|
|
104
|
+
"loginPath.label": "Login API path",
|
|
105
|
+
"loginPath.hint": "API path for the login endpoint. Default: /passwordless-login",
|
|
106
|
+
"confirmationUrl": "Confirmation URL",
|
|
107
|
+
"confirmationUrl.label": "Confirmation URL",
|
|
108
|
+
"confirmationUrl.hint": "The URL where users will be redirected after clicking the magic link.",
|
|
109
|
+
"callbackUrl": "Callback URL",
|
|
110
|
+
"callbackUrl.label": "Callback URL",
|
|
111
|
+
"callbackUrl.hint": "The URL users will be redirected to after successful authentication."
|
|
112
|
+
},
|
|
113
|
+
"authentication": {
|
|
114
|
+
"title": "Authentication Settings",
|
|
115
|
+
"description": "Configure how users are authenticated and created",
|
|
116
|
+
"options": "Authentication Options",
|
|
117
|
+
"verifyEmail": "Verify Email",
|
|
118
|
+
"verifyEmail.hint": "Verify user email before allowing authentication. Enhances security.",
|
|
119
|
+
"welcomeEmail": "Send Welcome Email",
|
|
120
|
+
"welcomeEmail.hint": "Send a welcome email to new users when they are created.",
|
|
121
|
+
"useJwtToken": "Use JWT Token",
|
|
122
|
+
"useJwtToken.hint": "Use JWT token for authentication instead of session cookies.",
|
|
123
|
+
"allowOnPublicRegistration": "Allow on Public Registration",
|
|
124
|
+
"allowOnPublicRegistration.hint": "Allow magic links to be used on public registration forms.",
|
|
125
|
+
"userCreationStrategy": "User Creation Strategy",
|
|
126
|
+
"userCreationStrategy.label": "Select how users are created",
|
|
127
|
+
"userCreationStrategy.placeholder": "Select a strategy",
|
|
128
|
+
"userCreationStrategy.email": "Email only - Create user with email only",
|
|
129
|
+
"userCreationStrategy.emailUsername": "Email + Username - Create user with email and generate username from it",
|
|
130
|
+
"userCreationStrategy.manual": "No automatic creation - Users must be created manually first",
|
|
131
|
+
"jwtTokenExpiration": "JWT Token Expiration",
|
|
132
|
+
"jwtTokenExpiration.label": "JWT token expiration time",
|
|
133
|
+
"jwtTokenExpiration.hint": "Examples: '1h' (1 hour), '7d' (7 days), '30d' (30 days)",
|
|
134
|
+
"storeLoginInfo": "Store Login Information",
|
|
135
|
+
"storeLoginInfo.hint": "Store User-Agent and IP address for each login attempt. Enhances security monitoring."
|
|
136
|
+
},
|
|
137
|
+
"email": {
|
|
138
|
+
"title": "Email Settings",
|
|
139
|
+
"description": "Configure email templates and sender information",
|
|
140
|
+
"template": {
|
|
141
|
+
"placeholder": "Example: <a href=\"<%= URL %>?code=<%= CODE %>\">Click here to login</a>"
|
|
142
|
+
},
|
|
143
|
+
"senderName": "Sender Name",
|
|
144
|
+
"senderName.label": "From name",
|
|
145
|
+
"senderName.hint": "Name displayed in the from field of the email.",
|
|
146
|
+
"senderEmail": "Sender Email",
|
|
147
|
+
"senderEmail.label": "From email",
|
|
148
|
+
"senderEmail.hint": "Email address used to send the magic link.",
|
|
149
|
+
"replyToEmail": "Reply-To Email",
|
|
150
|
+
"replyToEmail.label": "Response email (optional)",
|
|
151
|
+
"replyToEmail.hint": "Email address for replies.",
|
|
152
|
+
"subject": "Email Subject",
|
|
153
|
+
"subject.label": "Email subject line",
|
|
154
|
+
"subject.hint": "Subject line of the magic link email.",
|
|
155
|
+
"templates": "Email Templates",
|
|
156
|
+
"htmlTemplate": "HTML Email Template",
|
|
157
|
+
"htmlTemplate.description": "HTML formatted email that will be sent to users",
|
|
158
|
+
"htmlTemplate.label": "HTML message template",
|
|
159
|
+
"htmlTemplate.hint": "Use <%= URL %> for base URL and <%= CODE %> for token. You can use HTML formatting to make your email look better.",
|
|
160
|
+
"textTemplate": "Plain Text Email Template",
|
|
161
|
+
"textTemplate.description": "Plain text alternative for email clients that don't support HTML",
|
|
162
|
+
"textTemplate.label": "Text message template",
|
|
163
|
+
"textTemplate.hint": "Use <%= URL %> for base URL and <%= CODE %> for token. This version is used for email clients that can't display HTML."
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"tokens.title": "Magic Link Tokens",
|
|
167
|
+
"tokens.subtitle": "Manage active login tokens",
|
|
168
|
+
"tokens.refresh": "Refresh",
|
|
169
|
+
"tokens.active.title": "Active Tokens",
|
|
170
|
+
"tokens.active.description": "View and manage all active login tokens. You can block any suspicious login or token.",
|
|
171
|
+
"tokens.loading": "Loading tokens...",
|
|
172
|
+
"tokens.empty": "No active tokens found. All your magic links have either expired or been used.",
|
|
173
|
+
"tokens.email": "Email",
|
|
174
|
+
"tokens.user": "User",
|
|
175
|
+
"tokens.status": "Status",
|
|
176
|
+
"tokens.created": "Created",
|
|
177
|
+
"tokens.expires": "Expires",
|
|
178
|
+
"tokens.lastUsed": "Last Used",
|
|
179
|
+
"tokens.actions": "Actions",
|
|
180
|
+
"tokens.view": "View details",
|
|
181
|
+
"tokens.block": "Block token",
|
|
182
|
+
"tokens.status.active": "Active",
|
|
183
|
+
"tokens.status.expired": "Expired",
|
|
184
|
+
"tokens.status.blocked": "Blocked",
|
|
185
|
+
"tokens.loading.user": "Loading...",
|
|
186
|
+
"tokens.fetch.error": "Failed to fetch tokens",
|
|
187
|
+
"tokens.block.success": "Token blocked successfully",
|
|
188
|
+
"tokens.block.error": "Failed to block token"
|
|
189
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PLUGIN_ID } from '../pluginId';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fügt das Plugin-Präfix zum Übersetzungsschlüssel hinzu
|
|
5
|
+
* @param {string} id - Übersetzungsschlüssel
|
|
6
|
+
* @returns {string} - Vollständiger Übersetzungsschlüssel mit Plugin-Präfix
|
|
7
|
+
*/
|
|
8
|
+
const getTrad = (id) => {
|
|
9
|
+
// Wenn der Schlüssel bereits das Plugin-Präfix enthält, füge es nicht nochmal hinzu
|
|
10
|
+
if (id.startsWith(`${PLUGIN_ID}.`)) {
|
|
11
|
+
return id;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return `${PLUGIN_ID}.${id}`;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default getTrad;
|
package/build.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// build.js
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { build } = require('vite');
|
|
5
|
+
|
|
6
|
+
async function main() {
|
|
7
|
+
console.log('Starting Strapi plugin build for Magic Link...');
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
// Clean and prepare dist directory
|
|
11
|
+
await fs.emptyDir(path.resolve(__dirname, 'dist'));
|
|
12
|
+
await fs.ensureDir(path.resolve(__dirname, 'dist/admin'));
|
|
13
|
+
await fs.ensureDir(path.resolve(__dirname, 'dist/server'));
|
|
14
|
+
|
|
15
|
+
// Build admin panel
|
|
16
|
+
await build({
|
|
17
|
+
configFile: path.resolve(__dirname, 'vite.config.js'),
|
|
18
|
+
root: path.resolve(__dirname, 'admin/src'),
|
|
19
|
+
build: {
|
|
20
|
+
outDir: path.resolve(__dirname, 'dist/admin'),
|
|
21
|
+
emptyOutDir: true,
|
|
22
|
+
lib: {
|
|
23
|
+
entry: path.resolve(__dirname, 'admin/src/index.js'),
|
|
24
|
+
formats: ['es'],
|
|
25
|
+
fileName: () => 'index.js',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Copy server components
|
|
31
|
+
await fs.copy(
|
|
32
|
+
path.resolve(__dirname, 'server/src'),
|
|
33
|
+
path.resolve(__dirname, 'dist/server')
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// Generate minimal package.json
|
|
37
|
+
const packageJson = require('./package.json');
|
|
38
|
+
const distPackageJson = {
|
|
39
|
+
name: packageJson.name,
|
|
40
|
+
version: packageJson.version,
|
|
41
|
+
description: packageJson.description,
|
|
42
|
+
strapi: packageJson.strapi,
|
|
43
|
+
dependencies: packageJson.dependencies,
|
|
44
|
+
files: [
|
|
45
|
+
"admin",
|
|
46
|
+
"server",
|
|
47
|
+
"strapi-admin.js",
|
|
48
|
+
"strapi-server.js"
|
|
49
|
+
]
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
await fs.writeJson(
|
|
53
|
+
path.resolve(__dirname, 'dist/package.json'),
|
|
54
|
+
distPackageJson,
|
|
55
|
+
{ spaces: 2 }
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// Copy strapi integration files
|
|
59
|
+
await fs.copy(
|
|
60
|
+
path.resolve(__dirname, 'strapi-admin.js'),
|
|
61
|
+
path.resolve(__dirname, 'dist/strapi-admin.js')
|
|
62
|
+
);
|
|
63
|
+
await fs.copy(
|
|
64
|
+
path.resolve(__dirname, 'strapi-server.js'),
|
|
65
|
+
path.resolve(__dirname, 'dist/strapi-server.js')
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
console.log('Strapi plugin build completed successfully!');
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error('Build failed:', err);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "4.0.0",
|
|
3
|
+
"keywords": [],
|
|
4
|
+
"type": "commonjs",
|
|
5
|
+
"exports": {
|
|
6
|
+
"./package.json": "./package.json",
|
|
7
|
+
"./strapi-admin": "./admin/src/index.js",
|
|
8
|
+
"./strapi-server": "./server/src/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "strapi-plugin build",
|
|
12
|
+
"dev": "strapi-plugin watch",
|
|
13
|
+
"watch": "strapi-plugin watch"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@fortawesome/react-fontawesome": "^0.2.2",
|
|
17
|
+
"ci": "^2.3.0",
|
|
18
|
+
"lodash": "^4.17.21",
|
|
19
|
+
"nanoid": "^3.3.4"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@strapi/sdk-plugin": "^5.3.2",
|
|
23
|
+
"@strapi/strapi": "^5.11.2",
|
|
24
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
25
|
+
"fs-extra": "^11.2.0",
|
|
26
|
+
"prettier": "^3.5.3",
|
|
27
|
+
"react": "^18.3.1",
|
|
28
|
+
"react-dom": "^18.3.1",
|
|
29
|
+
"react-router-dom": "^6.30.0",
|
|
30
|
+
"semantic-release": "^24.2.3",
|
|
31
|
+
"styled-components": "^6.1.15",
|
|
32
|
+
"vite": "^5.0.0"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@strapi/design-system": "^2.0.0-rc.18",
|
|
36
|
+
"@strapi/helper-plugin": "^5.11.2",
|
|
37
|
+
"@strapi/icons": "^2.0.0-rc.18",
|
|
38
|
+
"@strapi/strapi": "^5.11.2",
|
|
39
|
+
"formik": "^2.4.5",
|
|
40
|
+
"prop-types": "^15.8.1",
|
|
41
|
+
"react": "^18.3.1",
|
|
42
|
+
"react-dom": "^18.3.1",
|
|
43
|
+
"react-intl": "^7.1.6",
|
|
44
|
+
"react-query": "^3.39.3",
|
|
45
|
+
"react-router-dom": "^6.30.0",
|
|
46
|
+
"styled-components": "^6.1.15",
|
|
47
|
+
"yup": "^1.3.3"
|
|
48
|
+
},
|
|
49
|
+
"strapi": {
|
|
50
|
+
"kind": "plugin",
|
|
51
|
+
"name": "strapi-plugin-magic-link-v5",
|
|
52
|
+
"displayName": "Magic Link Authentication",
|
|
53
|
+
"description": "This plugin provides passwordless authentication via magic links sent to email"
|
|
54
|
+
},
|
|
55
|
+
"name": "strapi-plugin-magic-link-v5",
|
|
56
|
+
"description": "This plugin provides passwordless authentication via magic links sent to email",
|
|
57
|
+
"license": "MIT",
|
|
58
|
+
"author": "Scherwan Al-Ahmad <scherwan.al-ahmad@joulee.de>"
|
|
59
|
+
}
|