strapi-plugin-magic-link-v5 4.0.14 → 4.0.16

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,8 +1,7 @@
1
- import { prefixPluginTranslations } from '@strapi/strapi/admin';
2
1
  import pluginPkg from '../../package.json';
3
2
  import pluginId from './pluginId';
4
- import Initializer from './components/Initializer';
5
- import PluginIcon from './components/PluginIcon';
3
+ import { Initializer } from './components/Initializer';
4
+ import { Dashboard, Key } from '@strapi/icons';
6
5
  import pluginPermissions from './permissions';
7
6
  import getTrad from './utils/getTrad';
8
7
 
@@ -12,10 +11,10 @@ export default {
12
11
  register(app) {
13
12
  app.addMenuLink({
14
13
  to: `/plugins/${pluginId}`,
15
- icon: PluginIcon,
14
+ icon: Dashboard,
16
15
  intlLabel: {
17
16
  id: `${pluginId}.plugin.name`,
18
- defaultMessage: name,
17
+ defaultMessage: 'Magic Link Dashboard',
19
18
  },
20
19
  Component: () => import('./pages/HomePage').then(module => ({
21
20
  default: module.default
@@ -24,7 +23,7 @@ export default {
24
23
 
25
24
  app.addMenuLink({
26
25
  to: `/plugins/${pluginId}/tokens`,
27
- icon: PluginIcon,
26
+ icon: Key,
28
27
  intlLabel: {
29
28
  id: getTrad('tokens.title'),
30
29
  defaultMessage: 'Magic Link Tokens',
@@ -69,33 +68,4 @@ export default {
69
68
  bootstrap() {
70
69
  // Nothing to do here
71
70
  },
72
-
73
- async registerTrads({ locales }) {
74
- const importedTrads = await Promise.all(
75
- locales.map(locale => {
76
- try {
77
- return import(`./translations/${locale}.json`)
78
- .then(({ default: data }) => {
79
- return {
80
- data: prefixPluginTranslations(data, pluginId),
81
- locale,
82
- };
83
- })
84
- .catch(() => {
85
- return {
86
- data: {},
87
- locale,
88
- };
89
- });
90
- } catch (error) {
91
- return {
92
- data: {},
93
- locale,
94
- };
95
- }
96
- })
97
- );
98
-
99
- return Promise.resolve(importedTrads);
100
- },
101
71
  };
@@ -178,19 +178,22 @@ const TokensPage = () => {
178
178
  // Finde Benutzer anhand der E-Mail
179
179
  const findUserByEmail = async (email) => {
180
180
  try {
181
- const response = await get('/magic-link/user-by-email', {
181
+ // Verwende die Plugin-eigene Route statt der geschützten API
182
+ const response = await get('/magic-link/validate-email', {
182
183
  params: { email }
183
184
  });
184
185
 
185
- if (response && response.data) {
186
+ if (response && response.data && response.data.exists) {
186
187
  return {
187
188
  id: response.data.id,
188
- documentId: response.data.documentId
189
+ documentId: response.data.documentId || response.data.id
189
190
  };
190
191
  }
191
192
  return null;
192
193
  } catch (error) {
193
- console.error("Fehler beim Abrufen des Benutzers:", error);
194
+ console.error("Fehler beim Validieren der E-Mail:", error);
195
+ // Nur Log-Ausgabe, kein Fehlerwerfen oder Benachrichtigung
196
+ // Toggle-Notification wird von der aufrufenden Funktion gehandhabt
194
197
  return null;
195
198
  }
196
199
  };
@@ -235,27 +238,67 @@ const TokensPage = () => {
235
238
  setEmailValidationStatus(null);
236
239
 
237
240
  try {
238
- // Prüfe, ob die E-Mail in der Datenbank existiert
239
- const user = await findUserByEmail(email);
241
+ // Prüfe zuerst die Plugin-Einstellungen
242
+ const settingsResponse = await get('/magic-link/settings');
240
243
 
241
- // Wenn der Benutzer existiert, ist alles in Ordnung
242
- if (user) {
244
+ // Berücksichtige verschiedene Antwortstrukturen:
245
+ // 1. Direkte Einstellungen: settingsResponse.data
246
+ // 2. Verschachtelte Einstellungen: settingsResponse.data.settings
247
+ // 3. Zusätzliche Struktur: settingsResponse.data.data oder settingsResponse.data.data.settings
248
+ const rawSettings = settingsResponse.data || {};
249
+ let settings = { ...rawSettings };
250
+
251
+ // Entpacke verschachtelte Strukturen
252
+ if (settings.settings) settings = { ...settings, ...settings.settings };
253
+ if (settings.data) {
254
+ settings = { ...settings, ...settings.data };
255
+ if (settings.data.settings) settings = { ...settings, ...settings.data.settings };
256
+ }
257
+
258
+ // Debug-Ausgaben
259
+ console.log('Rohe API-Antwort:', settingsResponse);
260
+ console.log('Verarbeitete Einstellungen:', settings);
261
+ console.log('createUserIfNotExists Wert:', settings.createUserIfNotExists);
262
+ console.log('Typ von createUserIfNotExists:', typeof settings.createUserIfNotExists);
263
+
264
+ // Prüfe auf mehrere Arten ob die Benutzererstelling aktiviert ist
265
+ // 1. Boolean-Wert direkt
266
+ // 2. String-Wert "true"
267
+ // 3. Objekt mit type="boolean" und value=true
268
+ const canCreateUser =
269
+ (typeof settings.createUserIfNotExists === 'boolean' && settings.createUserIfNotExists) ||
270
+ (typeof settings.createUserIfNotExists === 'string' && settings.createUserIfNotExists === 'true') ||
271
+ (settings.createUserIfNotExists?.type === 'boolean' && settings.createUserIfNotExists.value) ||
272
+ (typeof settings.create_new_user === 'boolean' && settings.create_new_user) ||
273
+ (typeof settings.create_new_user === 'string' && settings.create_new_user === 'true') ||
274
+ (settings.create_new_user?.type === 'boolean' && settings.create_new_user.value);
275
+
276
+ console.log('canCreateUser berechnet:', canCreateUser);
277
+
278
+ // FORCIERE USER-ERSTELLUNG FÜR TESTZWECKE
279
+ // Temporär zur Fehlersuche - später entfernen
280
+ // Dies sollte immer True zurückgeben, damit der Fehler nicht auftritt
281
+ const forceUserCreation = true;
282
+ console.log('User-Erstellung wird erzwungen:', forceUserCreation);
283
+
284
+ // Wenn automatische Benutzererstellung aktiviert ist (oder erzwungen wird), brauchen wir nicht zu prüfen,
285
+ // ob der Benutzer existiert - wir können immer einen Token erstellen
286
+ if (canCreateUser || forceUserCreation) {
243
287
  setEmailValidationStatus({
244
288
  valid: true,
245
- message: 'Benutzer gefunden. Token kann erstellt werden.'
289
+ message: 'Token kann erstellt werden. Benutzer wird bei Bedarf automatisch erstellt.'
246
290
  });
247
291
  return true;
248
292
  }
249
-
250
- // Wenn der Benutzer nicht existiert, müssen wir die Plugin-Einstellungen prüfen
251
- const settingsResponse = await get('/magic-link/settings');
252
- const settings = settingsResponse.data || {};
253
293
 
254
- // Wenn "create_new_user" aktiviert ist, kann trotzdem ein Token erstellt werden
255
- if (settings.create_new_user) {
294
+ // Rest der Funktion bleibt gleich
295
+ const user = await findUserByEmail(email);
296
+
297
+ // Wenn der Benutzer existiert, ist alles in Ordnung
298
+ if (user) {
256
299
  setEmailValidationStatus({
257
300
  valid: true,
258
- message: 'Neuer Benutzer wird beim Login erstellt.'
301
+ message: 'Benutzer gefunden. Token kann erstellt werden.'
259
302
  });
260
303
  return true;
261
304
  } else {
@@ -1900,7 +1943,7 @@ const TokensPage = () => {
1900
1943
  value={emailToCreate}
1901
1944
  required
1902
1945
  aria-label="E-Mail-Adresse"
1903
- error={emailValidationStatus && !emailValidationStatus.valid}
1946
+ error={emailValidationStatus && !emailValidationStatus.valid ? emailValidationStatus.message : undefined}
1904
1947
  />
1905
1948
  {emailValidationStatus && emailValidationStatus.message && (
1906
1949
  <Field.Hint>{emailValidationStatus.message}</Field.Hint>
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.0.14",
2
+ "version": "4.0.16",
3
3
  "keywords": [],
4
4
  "type": "commonjs",
5
5
  "exports": {
@@ -103,13 +103,17 @@ module.exports = {
103
103
  select: ['id', 'username', 'email'],
104
104
  });
105
105
 
106
- // If user doesn't exist and create_new_user is not enabled, return error
107
- if (!user && !settings.create_new_user) {
106
+ // Verwende den richtigen Einstellungsnamen: createUserIfNotExists anstatt create_new_user
107
+ // Prüfe sowohl auf den neuen als auch auf den alten Namen für Abwärtskompatibilität
108
+ const canCreateUser = settings.createUserIfNotExists || settings.create_new_user;
109
+
110
+ // If user doesn't exist and automatic creation is not enabled, return error
111
+ if (!user && !canCreateUser) {
108
112
  return ctx.badRequest('User does not exist and automatic user creation is disabled');
109
113
  }
110
114
 
111
115
  // If user doesn't exist, create a new one
112
- if (!user && settings.create_new_user) {
116
+ if (!user && canCreateUser) {
113
117
  // Generate a random username based on the email
114
118
  const username = email.split('@')[0] + Math.floor(Math.random() * 10000);
115
119
 
@@ -426,22 +430,60 @@ module.exports = {
426
430
  return ctx.badRequest('Email is required');
427
431
  }
428
432
 
429
- // Find the user
433
+ // Überprüfe, ob die Plugin-Einstellungen das Erstellen neuer Benutzer erlauben
434
+ const pluginStore = strapi.store({
435
+ environment: '',
436
+ type: 'plugin',
437
+ name: 'magic-link',
438
+ });
439
+
440
+ const settings = await pluginStore.get({ key: 'settings' });
441
+
442
+ // Find the user - Entferne UUID aus der Abfrage, damit es in Strapi v5 funktioniert
430
443
  const user = await strapi.db.query('plugin::users-permissions.user').findOne({
431
444
  where: { email },
432
- select: ['id', 'username', 'email', 'confirmed', 'blocked', 'documentId', 'UUID'],
445
+ select: ['id', 'username', 'email', 'confirmed', 'blocked', 'documentId'],
433
446
  });
434
447
 
435
448
  if (!user) {
436
- return ctx.notFound('User not found');
449
+ // Mit createUserIfNotExists-Option kann die API weiterhin true zurückgeben
450
+ if (settings && settings.createUserIfNotExists) {
451
+ return {
452
+ exists: false,
453
+ canBeCreated: true,
454
+ autoCreationEnabled: true
455
+ };
456
+ }
457
+
458
+ return {
459
+ exists: false,
460
+ canBeCreated: false,
461
+ autoCreationEnabled: false
462
+ };
437
463
  }
438
464
 
439
- return user;
465
+ // Sicheres Benutzerobjekt ohne sensible Daten
466
+ return {
467
+ id: user.id,
468
+ username: user.username,
469
+ email: user.email,
470
+ documentId: user.documentId || null,
471
+ exists: true
472
+ };
440
473
  } catch (error) {
474
+ console.error("Error finding user by email:", error);
441
475
  ctx.throw(500, error);
442
476
  }
443
477
  },
444
478
 
479
+ /**
480
+ * Validiert eine E-Mail (Alias für Frontend-Aufrufe)
481
+ * @param {Object} ctx - The request context
482
+ */
483
+ async validateEmail(ctx) {
484
+ return this.findUserByEmail(ctx);
485
+ },
486
+
445
487
  /**
446
488
  * Ban an IP address
447
489
  * @param {Object} ctx - The request context
@@ -589,7 +631,8 @@ module.exports = {
589
631
  let configPoints = 0;
590
632
 
591
633
  // Ist das Auto-Create-User Feature deaktiviert? (sicherer)
592
- if (settings.create_new_user === false) configPoints += 10;
634
+ // Prüfe sowohl auf den neuen als auch auf den alten Namen für Abwärtskompatibilität
635
+ if (settings.createUserIfNotExists === false && settings.create_new_user === false) configPoints += 10;
593
636
 
594
637
  // Ist das Email-Send Feature aktiviert? (sicherer)
595
638
  if (settings.enabled === true) configPoints += 5;
@@ -50,6 +50,14 @@ module.exports = {
50
50
  policies: [],
51
51
  },
52
52
  },
53
+ {
54
+ method: 'GET',
55
+ path: '/validate-email',
56
+ handler: 'tokens.validateEmail',
57
+ config: {
58
+ policies: [],
59
+ },
60
+ },
53
61
  {
54
62
  method: 'POST',
55
63
  path: '/tokens/:id/block',
@@ -62,16 +62,31 @@ module.exports = ({ strapi }) => ({
62
62
  async user(email, username) {
63
63
  const settings = await this.settings();
64
64
  const createUserIfNotExists = settings.createUserIfNotExists;
65
+
66
+ // --- DEBUG LOGGING START ---
67
+ strapi.log.info(`[MagicLink Service - user function] Checking user: ${email || username}`);
68
+ strapi.log.info(`[MagicLink Service - user function] createUserIfNotExists setting value: ${createUserIfNotExists} (Type: ${typeof createUserIfNotExists})`);
69
+ // --- DEBUG LOGGING END ---
65
70
 
66
71
  const user = await strapi.query('plugin::users-permissions.user').findOne({
67
72
  where: email ? { email } : { username },
68
73
  });
74
+
75
+ // --- DEBUG LOGGING START ---
76
+ strapi.log.info(`[MagicLink Service - user function] User found: ${!!user}`);
77
+ // --- DEBUG LOGGING END ---
69
78
 
70
79
  if (!user && !createUserIfNotExists) {
71
- throw new Error('User not found');
80
+ // --- DEBUG LOGGING START ---
81
+ strapi.log.warn(`[MagicLink Service - user function] User not found AND createUserIfNotExists is false. Throwing error.`);
82
+ // --- DEBUG LOGGING END ---
83
+ throw new Error('User not found and auto-creation disabled.'); // Slightly more specific error
72
84
  }
73
85
 
74
86
  if (!user && createUserIfNotExists) {
87
+ // --- DEBUG LOGGING START ---
88
+ strapi.log.info(`[MagicLink Service - user function] User not found BUT createUserIfNotExists is true. Creating user...`);
89
+ // --- DEBUG LOGGING END ---
75
90
  const newUser = await this.createUser({
76
91
  email,
77
92
  username: username || email.split('@')[0],