strapi-plugin-magic-link-v5 4.3.1 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COPYRIGHT_NOTICE.txt +9 -10
- package/LICENSE +27 -48
- package/README.md +208 -296
- package/admin/src/pages/Tokens/TokensProfessional.jsx +19 -8
- package/admin/src/pages/Tokens/TokensRedesign.jsx +9 -3
- package/package.json +2 -2
- package/LICENSE-DUAL.md +0 -37
- package/LICENSE_GUARD.md +0 -323
- package/SECURITY.md +0 -79
package/COPYRIGHT_NOTICE.txt
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Magic Link - Passwordless Authentication for Strapi
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c) 2025
|
|
5
|
-
* All Rights Reserved.
|
|
4
|
+
* Copyright (c) 2025 Schero A. (begservice)
|
|
6
5
|
*
|
|
7
|
-
*
|
|
6
|
+
* Licensed under the MIT License
|
|
8
7
|
*
|
|
9
|
-
* This
|
|
8
|
+
* This plugin is free to use for personal and commercial projects.
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* IMPORTANT RESTRICTION:
|
|
11
|
+
* The license validation system (license-guard.js and related components)
|
|
12
|
+
* must remain intact and functional. Removing or bypassing this system
|
|
13
|
+
* is strictly prohibited.
|
|
13
14
|
*
|
|
14
|
-
* This software is licensed under a proprietary commercial license.
|
|
15
15
|
* See LICENSE file for full terms.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Repository: https://github.com/begservice/strapi-plugin-magic-link-v5
|
|
18
|
+
* Issues: https://github.com/begservice/strapi-plugin-magic-link-v5/issues
|
|
19
19
|
*/
|
|
20
|
-
|
package/LICENSE
CHANGED
|
@@ -1,48 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
and
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
4. TERMINATION
|
|
30
|
-
This license is effective until terminated. Your rights under this license
|
|
31
|
-
will terminate automatically without notice if you fail to comply with any
|
|
32
|
-
term of this license.
|
|
33
|
-
|
|
34
|
-
5. WARRANTY DISCLAIMER
|
|
35
|
-
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
36
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
37
|
-
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
38
|
-
|
|
39
|
-
6. LIMITATION OF LIABILITY
|
|
40
|
-
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
41
|
-
OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE.
|
|
42
|
-
|
|
43
|
-
7. LICENSE PURCHASE
|
|
44
|
-
To obtain a valid license, visit: [Deine Website]
|
|
45
|
-
Each license is subject to separate terms and pricing.
|
|
46
|
-
|
|
47
|
-
For licensing inquiries, contact: [Deine Email]
|
|
48
|
-
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Schero A. (begservice)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
**ADDITIONAL CONDITION:**
|
|
16
|
+
The license validation system (including but not limited to license-guard.js,
|
|
17
|
+
license controller, and related API endpoints) must remain intact and functional.
|
|
18
|
+
Removing, bypassing, or disabling the license validation system is strictly
|
|
19
|
+
prohibited.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,39 +1,69 @@
|
|
|
1
|
-
# Magic Link - Passwordless Authentication for Strapi
|
|
1
|
+
# Magic Link - Passwordless Authentication for Strapi v5
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Secure passwordless authentication for Strapi using email-based magic links. No passwords required.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.npmjs.com/package/strapi-plugin-magic-link-v5)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
---
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
## 📜 License
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
- ❌ **NOT** licensed under MIT, Apache, or similar permissive licenses
|
|
13
|
-
- ✅ Requires a **valid commercial license** for production use
|
|
14
|
-
- ✅ Source code is visible for transparency and evaluation only
|
|
12
|
+
This plugin is licensed under the **MIT License** - free for everyone to use!
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
### What you CAN do:
|
|
15
|
+
- ✅ Use the plugin freely (personal & commercial)
|
|
16
|
+
- ✅ View and study the source code
|
|
17
|
+
- ✅ Report issues and contribute improvements
|
|
18
|
+
- ✅ Deploy in production without fees
|
|
19
|
+
- ✅ Integrate in your commercial projects
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
### What you CANNOT do:
|
|
22
|
+
- ❌ Remove or bypass the license validation system
|
|
23
|
+
- ❌ Modify `license-guard.js` or license-related endpoints
|
|
24
|
+
- ❌ Disable license activation requirements
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
**Important:** The license validation system must remain intact and functional. This ensures quality, support, and continued development. Users must activate the plugin (free) through the admin interface.
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
📄 See [LICENSE](./LICENSE) for full terms
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
---
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
32
|
+
## ✨ Features
|
|
33
|
+
|
|
34
|
+
### Core Authentication
|
|
35
|
+
- 🔐 **Passwordless Login** - Users log in via secure email links
|
|
36
|
+
- 🎫 **Magic Link Tokens** - Cryptographically secure, time-limited tokens
|
|
37
|
+
- 🔑 **JWT Session Management** - Monitor and manage active user sessions
|
|
38
|
+
- 👤 **Auto User Creation** - Optionally create users automatically on first login
|
|
39
|
+
- 🌍 **Multi-language Support** - English and German translations included
|
|
40
|
+
|
|
41
|
+
### Security & Control
|
|
42
|
+
- 🛡️ **IP Banning** - Block suspicious IP addresses
|
|
43
|
+
- 🔒 **Session Revocation** - Instantly revoke any active JWT session
|
|
44
|
+
- ⏰ **Token Expiration** - Configurable expiration periods
|
|
45
|
+
- 🎯 **Login Attempt Limiting** - Prevent brute force attacks
|
|
46
|
+
- 📊 **Security Score** - Real-time security configuration assessment
|
|
47
|
+
- 📝 **Login Info Tracking** - Store IP addresses and user agents for audit
|
|
48
|
+
|
|
49
|
+
### Admin Interface
|
|
50
|
+
- 📱 **Modern Dashboard** - Beautiful statistics and monitoring interface
|
|
51
|
+
- 🎨 **Professional Token Management** - Create, extend, and manage tokens
|
|
52
|
+
- 🔍 **Search & Filter** - Find tokens and sessions quickly
|
|
53
|
+
- 📄 **Pagination** - Handle large datasets efficiently
|
|
54
|
+
- 🎭 **Bulk Operations** - Select and manage multiple tokens at once
|
|
55
|
+
- 🌐 **License Management** - Built-in license activation interface
|
|
56
|
+
|
|
57
|
+
### Customization
|
|
58
|
+
- ✉️ **Email Templates** - Customize HTML and plain text email templates
|
|
59
|
+
- 🎨 **Template Variables** - Use `<%= URL %>` and `<%= CODE %>` placeholders
|
|
60
|
+
- ⚙️ **Flexible Configuration** - Configure via admin panel
|
|
61
|
+
- 🔄 **Token Reusability** - Choose between one-time or reusable tokens
|
|
62
|
+
- 📧 **Email Designer Support** - Integrates with Email Designer 5 plugin
|
|
33
63
|
|
|
34
|
-
|
|
64
|
+
---
|
|
35
65
|
|
|
36
|
-
## Installation
|
|
66
|
+
## 🚀 Installation
|
|
37
67
|
|
|
38
68
|
```bash
|
|
39
69
|
# Using npm
|
|
@@ -42,334 +72,216 @@ npm install strapi-plugin-magic-link-v5
|
|
|
42
72
|
# Using yarn
|
|
43
73
|
yarn add strapi-plugin-magic-link-v5
|
|
44
74
|
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
# or
|
|
48
|
-
yarn add begservice/strapi-magic-link
|
|
75
|
+
# Using pnpm
|
|
76
|
+
pnpm add strapi-plugin-magic-link-v5
|
|
49
77
|
```
|
|
50
78
|
|
|
51
|
-
After installation, restart your Strapi server
|
|
79
|
+
After installation, **restart your Strapi server**. The plugin will appear in your admin panel.
|
|
52
80
|
|
|
53
|
-
|
|
81
|
+
---
|
|
54
82
|
|
|
55
|
-
|
|
83
|
+
## 🎯 Quick Start
|
|
56
84
|
|
|
57
|
-
###
|
|
85
|
+
### 1️⃣ Activate License
|
|
58
86
|
|
|
59
|
-
|
|
60
|
-
- License keys are validated against this server
|
|
61
|
-
- The server URL is hardcoded for security (cannot be changed by end users)
|
|
62
|
-
- Supports **24-hour grace period** for offline operation
|
|
87
|
+
After installing, navigate to **Settings → Magic Link → License** in your Strapi admin panel and activate the plugin (free).
|
|
63
88
|
|
|
64
|
-
###
|
|
89
|
+
### 2️⃣ Configure Settings
|
|
65
90
|
|
|
66
|
-
|
|
91
|
+
Go to **Settings → Magic Link → Settings** and configure:
|
|
67
92
|
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
```javascript
|
|
94
|
+
{
|
|
95
|
+
"enabled": true,
|
|
96
|
+
"createUserIfNotExists": true, // Auto-create users
|
|
97
|
+
"expire_period": 3600, // Token valid for 1 hour
|
|
98
|
+
"token_length": 20, // Token security level
|
|
99
|
+
"from_email": "noreply@yourdomain.com",
|
|
100
|
+
"from_name": "Your App",
|
|
101
|
+
"object": "Your Magic Link Login",
|
|
102
|
+
"confirmationUrl": "https://yourdomain.com/auth/callback"
|
|
103
|
+
}
|
|
72
104
|
```
|
|
73
105
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
## How It Works
|
|
77
|
-
|
|
78
|
-
### Email User with Login Link
|
|
79
|
-
|
|
80
|
-
1. **Request Process**:
|
|
81
|
-
|
|
82
|
-
- User requests a login link by entering their email
|
|
83
|
-
- System generates a secure token and sends an email
|
|
84
|
-
- Email contains a magic link with the token
|
|
85
|
-
|
|
86
|
-
2. **Token Details**:
|
|
87
|
-
- Cryptographically secure random tokens
|
|
88
|
-
- Configurable expiration time
|
|
89
|
-
- Option for one-time use or reusable tokens
|
|
90
|
-
- Tracks IP address and user agent information
|
|
91
|
-
|
|
92
|
-
### Login with Token
|
|
93
|
-
|
|
94
|
-
1. **Authentication Process**:
|
|
95
|
-
|
|
96
|
-
- User clicks the link in their email
|
|
97
|
-
- System verifies the token is valid and not expired
|
|
98
|
-
- User is automatically authenticated
|
|
99
|
-
- JWT token is generated for the session
|
|
100
|
-
|
|
101
|
-
2. **Security Measures**:
|
|
102
|
-
- IP address validation (optional)
|
|
103
|
-
- Token expiration
|
|
104
|
-
- One-time use tokens (configurable)
|
|
105
|
-
- Automatic blocking after failed attempts
|
|
106
|
-
|
|
107
|
-

|
|
108
|
-
|
|
109
|
-
## Configuration
|
|
110
|
-
|
|
111
|
-
Configure the plugin through **Settings > Magic Link** in the Strapi admin panel:
|
|
112
|
-
|
|
113
|
-

|
|
114
|
-
|
|
115
|
-
### General Settings
|
|
116
|
-
|
|
117
|
-
- **Enable Magic Link**: Turn the feature on/off
|
|
118
|
-
- **Create New Users**: Automatically create users if they don't exist
|
|
119
|
-
- **Token Stays Valid**: Configure one-time use or reusable tokens
|
|
120
|
-
- **Expiration Period**: Set how long tokens remain valid
|
|
121
|
-
- **Token Length**: Configure the security level of tokens
|
|
122
|
-
|
|
123
|
-
### Authentication Settings
|
|
124
|
-
|
|
125
|
-
- **Default Role**: Select which user role is assigned to new users
|
|
126
|
-
- **JWT Token Expiration**: Define how long JWT tokens remain valid (e.g., 30d, 24h)
|
|
127
|
-
- **Store Login Info**: Enable tracking of user agents and IP addresses
|
|
128
|
-
- **Remember Me**: Allow users to stay logged in for extended periods
|
|
129
|
-
|
|
130
|
-
### Email Settings
|
|
131
|
-
|
|
132
|
-
- **Sender Information**: Configure the email sender details (name, email)
|
|
133
|
-
- **Reply-To Address**: Set a reply-to email address for support inquiries
|
|
134
|
-
- **Email Subject**: Customize the subject line of the magic link emails
|
|
135
|
-
- **Email Templates**: Customize HTML and text templates
|
|
136
|
-
- **Email Designer Integration**: Use with Email Designer 5 if installed
|
|
137
|
-
|
|
138
|
-
## Dashboard & Admin Interface
|
|
139
|
-
|
|
140
|
-
Magic Link provides a comprehensive admin interface with several key sections:
|
|
141
|
-
|
|
142
|
-

|
|
143
|
-
|
|
144
|
-
### Dashboard Overview
|
|
145
|
-
|
|
146
|
-
- **Security Score**: Dynamic score (0-100) showing your current security configuration
|
|
147
|
-
- **Active Tokens**: Count and management of currently active tokens
|
|
148
|
-
- **Token Usage**: Metrics on token creation and usage patterns
|
|
149
|
-
- **Users Using Magic Link**: Number of unique users authenticating via magic links
|
|
150
|
-
- **Tokens About to Expire**: Warning system for tokens expiring soon
|
|
151
|
-
|
|
152
|
-
### Token Management
|
|
153
|
-
|
|
154
|
-
- **Token List View**: Sortable and filterable list of all tokens
|
|
155
|
-
- **Token Status Indicators**: Visual indicators showing token status (active, expired, used)
|
|
156
|
-
- **Token Details**: Inspect complete token information including:
|
|
157
|
-
- Creation and expiration dates
|
|
158
|
-
- IP address and user agent information
|
|
159
|
-
- Usage history and context data
|
|
160
|
-
- **Bulk Actions**: Select multiple tokens for batch operations
|
|
161
|
-
- **Search & Filter**: Find tokens by email, status, or creation date
|
|
162
|
-
- **Token Operations**:
|
|
163
|
-
- Block/deactivate tokens
|
|
164
|
-
- Extend token expiration
|
|
165
|
-
- Delete tokens
|
|
166
|
-
|
|
167
|
-
### JWT Session Management
|
|
168
|
-
|
|
169
|
-
- **Active Sessions**: Monitor all active JWT sessions across your application
|
|
170
|
-
- **Session Revocation**: Ability to revoke any active session immediately
|
|
171
|
-
- **Session Details**: View complete session information including:
|
|
172
|
-
- User details
|
|
173
|
-
- Creation and expiration time
|
|
174
|
-
- Last activity
|
|
175
|
-
- IP address and device information
|
|
106
|
+
### 3️⃣ Frontend Implementation
|
|
176
107
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
- **Context Injection**: Add custom JSON context data to tokens
|
|
189
|
-
- **Email Validation**: Verify email existence before token creation
|
|
190
|
-
|
|
191
|
-
## Admin Features
|
|
192
|
-
|
|
193
|
-
### Token Management
|
|
194
|
-
|
|
195
|
-
- View all active/inactive tokens
|
|
196
|
-
- Block or activate individual tokens
|
|
197
|
-
- Delete expired tokens
|
|
198
|
-
- See token usage statistics
|
|
199
|
-
|
|
200
|
-
### Security Dashboard
|
|
201
|
-
|
|
202
|
-
- Security score based on your configuration
|
|
203
|
-
- IP banning for suspicious activity
|
|
204
|
-
- JWT session monitoring and management
|
|
205
|
-
- Token expiration warnings
|
|
206
|
-
|
|
207
|
-
## API Endpoints
|
|
208
|
-
|
|
209
|
-
- `POST /api/magic-link/send` - Generate and send a magic link
|
|
210
|
-
- `GET /api/magic-link/login?loginToken=xxx` - Authenticate with token
|
|
211
|
-
- `GET /api/magic-link/tokens` - List tokens (admin only)
|
|
212
|
-
- `GET /api/magic-link/jwt-sessions` - List active sessions (admin only)
|
|
213
|
-
- `POST /api/magic-link/tokens/:id/block` - Block a specific token
|
|
214
|
-
- `POST /api/magic-link/ban-ip` - Ban an IP address
|
|
215
|
-
|
|
216
|
-
## Frontend Implementation
|
|
108
|
+
**Request a magic link:**
|
|
109
|
+
```javascript
|
|
110
|
+
const response = await fetch('/api/magic-link/send-link', {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: { 'Content-Type': 'application/json' },
|
|
113
|
+
body: JSON.stringify({
|
|
114
|
+
email: 'user@example.com',
|
|
115
|
+
context: { redirectTo: '/dashboard' } // Optional
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
```
|
|
217
119
|
|
|
120
|
+
**Verify token on callback page:**
|
|
218
121
|
```javascript
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (token) {
|
|
233
|
-
try {
|
|
234
|
-
const response = await axios.get(
|
|
235
|
-
`/api/magic-link/login?loginToken=${token}`
|
|
236
|
-
);
|
|
237
|
-
// Store JWT and redirect user
|
|
238
|
-
localStorage.setItem("token", response.data.jwt);
|
|
239
|
-
window.location.href = "/dashboard";
|
|
240
|
-
} catch (error) {
|
|
241
|
-
// Handle invalid token
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
};
|
|
122
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
123
|
+
const loginToken = urlParams.get('loginToken');
|
|
124
|
+
|
|
125
|
+
if (loginToken) {
|
|
126
|
+
const response = await fetch(`/api/magic-link/login?loginToken=${loginToken}`);
|
|
127
|
+
const { jwt, user } = await response.json();
|
|
128
|
+
|
|
129
|
+
// Store JWT for authenticated requests
|
|
130
|
+
localStorage.setItem('token', jwt);
|
|
131
|
+
|
|
132
|
+
// Redirect to dashboard
|
|
133
|
+
window.location.href = '/dashboard';
|
|
134
|
+
}
|
|
245
135
|
```
|
|
246
136
|
|
|
247
|
-
|
|
137
|
+
---
|
|
248
138
|
|
|
249
|
-
|
|
139
|
+
## 📡 API Endpoints
|
|
250
140
|
|
|
251
|
-
|
|
252
|
-
await axios.post("/api/magic-link/send", {
|
|
253
|
-
email: "user@example.com",
|
|
254
|
-
context: {
|
|
255
|
-
redirectUrl: "/dashboard",
|
|
256
|
-
source: "registration",
|
|
257
|
-
},
|
|
258
|
-
});
|
|
259
|
-
```
|
|
141
|
+
### Public Endpoints (No Auth Required)
|
|
260
142
|
|
|
261
|
-
|
|
143
|
+
| Method | Endpoint | Description |
|
|
144
|
+
|--------|----------|-------------|
|
|
145
|
+
| `POST` | `/api/magic-link/send-link` | Generate and send magic link to email |
|
|
146
|
+
| `GET` | `/api/magic-link/login?loginToken=xxx` | Authenticate user with token |
|
|
262
147
|
|
|
263
|
-
|
|
264
|
-
- Use one-time tokens for sensitive operations
|
|
265
|
-
- Regularly monitor the security dashboard
|
|
266
|
-
- Ban suspicious IP addresses promptly
|
|
148
|
+
### Admin Endpoints (Admin Auth Required)
|
|
267
149
|
|
|
268
|
-
|
|
150
|
+
| Method | Endpoint | Description |
|
|
151
|
+
|--------|----------|-------------|
|
|
152
|
+
| `GET` | `/magic-link/tokens` | List all tokens |
|
|
153
|
+
| `POST` | `/magic-link/tokens` | Create a new token |
|
|
154
|
+
| `DELETE` | `/magic-link/tokens/:id` | Delete a token |
|
|
155
|
+
| `POST` | `/magic-link/tokens/:id/block` | Block a token |
|
|
156
|
+
| `POST` | `/magic-link/tokens/:id/extend` | Extend token validity |
|
|
157
|
+
| `GET` | `/magic-link/jwt-sessions` | List active JWT sessions |
|
|
158
|
+
| `POST` | `/magic-link/revoke-jwt` | Revoke a JWT session |
|
|
159
|
+
| `POST` | `/magic-link/ban-ip` | Ban an IP address |
|
|
160
|
+
| `GET` | `/magic-link/banned-ips` | List banned IPs |
|
|
269
161
|
|
|
270
|
-
|
|
271
|
-
| ---------------------- | ---------------------------------------------- |
|
|
272
|
-
| Emails not sending | Check your Strapi email provider configuration |
|
|
273
|
-
| Token validation fails | Verify token expiration settings |
|
|
274
|
-
| User not found errors | Check "Create New Users" setting |
|
|
162
|
+
---
|
|
275
163
|
|
|
276
|
-
##
|
|
164
|
+
## ⚙️ Configuration
|
|
277
165
|
|
|
278
|
-
|
|
166
|
+
### General Settings
|
|
167
|
+
- `enabled` - Enable/disable magic link authentication
|
|
168
|
+
- `createUserIfNotExists` - Auto-create users on first login
|
|
169
|
+
- `expire_period` - Token expiration time (seconds)
|
|
170
|
+
- `token_length` - Security level (20-40 recommended)
|
|
171
|
+
- `stays_valid` - Token reusable after first use
|
|
172
|
+
- `max_login_attempts` - Limit failed login attempts
|
|
279
173
|
|
|
280
|
-
|
|
174
|
+
### Email Settings
|
|
175
|
+
- `from_name` - Sender name
|
|
176
|
+
- `from_email` - Sender email address
|
|
177
|
+
- `response_email` - Reply-to email
|
|
178
|
+
- `object` - Email subject line
|
|
179
|
+
- `message_html` - HTML email template
|
|
180
|
+
- `message_text` - Plain text email template
|
|
181
|
+
|
|
182
|
+
### JWT Settings
|
|
183
|
+
- `use_jwt_token` - Use JWT for authentication
|
|
184
|
+
- `jwt_token_expires_in` - JWT validity period (e.g., '30d', '7d')
|
|
185
|
+
- `store_login_info` - Track IP and user agent
|
|
186
|
+
|
|
187
|
+
### Advanced
|
|
188
|
+
- `user_creation_strategy` - `email` | `emailUsername` | `manual`
|
|
189
|
+
- `verify_email` - Require email verification
|
|
190
|
+
- `callback_url` - Post-login redirect URL
|
|
281
191
|
|
|
282
|
-
|
|
192
|
+
---
|
|
283
193
|
|
|
284
|
-
|
|
194
|
+
## 🎨 Email Templates
|
|
285
195
|
|
|
286
|
-
|
|
196
|
+
Customize your magic link emails using template variables:
|
|
287
197
|
|
|
288
|
-
```
|
|
289
|
-
|
|
198
|
+
```html
|
|
199
|
+
<!-- HTML Template -->
|
|
200
|
+
<h1>Welcome!</h1>
|
|
201
|
+
<p>Click to login:</p>
|
|
202
|
+
<a href="<%= URL %>?loginToken=<%= CODE %>">
|
|
203
|
+
Login to Your Account
|
|
204
|
+
</a>
|
|
290
205
|
```
|
|
291
206
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
2. Determine the appropriate version bump (major, minor, or patch)
|
|
296
|
-
3. Generate release notes
|
|
297
|
-
4. Update the version in package.json
|
|
298
|
-
5. Create a new Git tag
|
|
299
|
-
6. Publish the package to npm
|
|
207
|
+
**Available Variables:**
|
|
208
|
+
- `<%= URL %>` - Your confirmation URL
|
|
209
|
+
- `<%= CODE %>` - The generated token
|
|
300
210
|
|
|
301
|
-
|
|
211
|
+
---
|
|
302
212
|
|
|
303
|
-
|
|
213
|
+
## 🔒 Security Features
|
|
304
214
|
|
|
305
|
-
|
|
215
|
+
- **Token Expiration** - Configurable expiration periods
|
|
216
|
+
- **One-time Tokens** - Optional single-use tokens
|
|
217
|
+
- **IP Tracking** - Monitor login locations
|
|
218
|
+
- **IP Banning** - Block suspicious addresses
|
|
219
|
+
- **JWT Blacklist** - Revoke compromised sessions
|
|
220
|
+
- **Login Attempt Limiting** - Prevent brute force
|
|
221
|
+
- **User Agent Tracking** - Device fingerprinting
|
|
306
222
|
|
|
307
|
-
|
|
223
|
+
---
|
|
308
224
|
|
|
309
|
-
|
|
310
|
-
<type>(<scope>): <subject>
|
|
311
|
-
<BLANK LINE>
|
|
312
|
-
<body>
|
|
313
|
-
<BLANK LINE>
|
|
314
|
-
<footer>
|
|
315
|
-
```
|
|
225
|
+
## 🎯 Use Cases
|
|
316
226
|
|
|
317
|
-
|
|
227
|
+
- **SaaS Applications** - Simplify user onboarding
|
|
228
|
+
- **Customer Portals** - Secure, password-free access
|
|
229
|
+
- **Multi-tenant Systems** - Easy user management
|
|
230
|
+
- **Mobile Apps** - Seamless authentication flow
|
|
231
|
+
- **Content Platforms** - Reduce password fatigue
|
|
318
232
|
|
|
319
|
-
|
|
233
|
+
---
|
|
320
234
|
|
|
321
|
-
|
|
322
|
-
- `fix`: A bug fix (triggers a patch release)
|
|
323
|
-
- `docs`: Documentation changes only
|
|
324
|
-
- `style`: Changes that don't affect code functionality (formatting, etc.)
|
|
325
|
-
- `refactor`: Code changes that neither fix a bug nor add a feature
|
|
326
|
-
- `perf`: Performance improvements
|
|
327
|
-
- `test`: Adding or updating tests
|
|
328
|
-
- `chore`: Changes to build process or auxiliary tools
|
|
329
|
-
- `ci`: Changes to CI configuration files and scripts
|
|
235
|
+
## 🐛 Troubleshooting
|
|
330
236
|
|
|
331
|
-
|
|
237
|
+
| Issue | Solution |
|
|
238
|
+
|-------|----------|
|
|
239
|
+
| Emails not sending | Check Strapi email provider configuration |
|
|
240
|
+
| Token invalid errors | Verify token hasn't expired |
|
|
241
|
+
| User not found | Enable `createUserIfNotExists` setting |
|
|
242
|
+
| License activation fails | Check network connectivity |
|
|
243
|
+
| npm install fails | Use `npm install --legacy-peer-deps` |
|
|
332
244
|
|
|
333
|
-
|
|
245
|
+
---
|
|
334
246
|
|
|
335
|
-
|
|
247
|
+
## 🤝 Contributing
|
|
336
248
|
|
|
337
|
-
|
|
249
|
+
Contributions are welcome! Please:
|
|
338
250
|
|
|
339
|
-
|
|
340
|
-
|
|
251
|
+
1. Fork the repository
|
|
252
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
253
|
+
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
|
|
254
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
255
|
+
5. Open a Pull Request
|
|
341
256
|
|
|
342
|
-
|
|
343
|
-
|
|
257
|
+
**Commit Convention:** Follow [Conventional Commits](https://www.conventionalcommits.org/)
|
|
258
|
+
- `feat:` - New features
|
|
259
|
+
- `fix:` - Bug fixes
|
|
260
|
+
- `docs:` - Documentation changes
|
|
261
|
+
- `chore:` - Maintenance tasks
|
|
344
262
|
|
|
345
|
-
|
|
263
|
+
---
|
|
346
264
|
|
|
347
|
-
|
|
265
|
+
## 📝 Changelog
|
|
348
266
|
|
|
349
|
-
|
|
350
|
-
feat(auth): add support for multiple roles
|
|
267
|
+
This project uses [semantic-release](https://github.com/semantic-release/semantic-release) for automated versioning and releases. See [GitHub Releases](https://github.com/begservice/strapi-plugin-magic-link-v5/releases) for version history.
|
|
351
268
|
|
|
352
|
-
|
|
269
|
+
---
|
|
353
270
|
|
|
354
|
-
|
|
271
|
+
## 📄 License
|
|
355
272
|
|
|
356
|
-
|
|
273
|
+
This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.
|
|
357
274
|
|
|
358
|
-
|
|
359
|
-
```
|
|
275
|
+
**Important:** While the code is open source, the license validation system must remain intact. This ensures quality, security, and continued development of the plugin.
|
|
360
276
|
|
|
361
|
-
|
|
277
|
+
---
|
|
362
278
|
|
|
363
|
-
|
|
364
|
-
- `develop`: Integration branch for features
|
|
365
|
-
- `feature/*`: New features
|
|
366
|
-
- `fix/*`: Bug fixes
|
|
367
|
-
- `docs/*`: Documentation changes
|
|
279
|
+
## 💬 Support
|
|
368
280
|
|
|
369
|
-
|
|
281
|
+
- 🐛 **Issues**: [GitHub Issues](https://github.com/begservice/strapi-plugin-magic-link-v5/issues)
|
|
282
|
+
- 📧 **Contact**: 124470865+begservice@users.noreply.github.com
|
|
283
|
+
- 📦 **npm**: [strapi-plugin-magic-link-v5](https://www.npmjs.com/package/strapi-plugin-magic-link-v5)
|
|
370
284
|
|
|
371
285
|
---
|
|
372
286
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
If you encounter issues or have questions, please check the admin documentation or open an issue.
|
|
287
|
+
Made with ❤️ by [begservice](https://github.com/begservice)
|
|
@@ -683,9 +683,15 @@ const TokensProfessional = () => {
|
|
|
683
683
|
// Stats berechnen
|
|
684
684
|
const stats = useMemo(() => ({
|
|
685
685
|
total: tokens.length,
|
|
686
|
-
active: tokens.filter(t =>
|
|
687
|
-
|
|
688
|
-
|
|
686
|
+
active: tokens.filter(t => {
|
|
687
|
+
const isExpired = t.expires_at && new Date(t.expires_at) < new Date();
|
|
688
|
+
return t.is_active && !isExpired;
|
|
689
|
+
}).length,
|
|
690
|
+
expired: tokens.filter(t => {
|
|
691
|
+
const isExpired = t.expires_at && new Date(t.expires_at) < new Date();
|
|
692
|
+
return isExpired;
|
|
693
|
+
}).length,
|
|
694
|
+
used: tokens.filter(t => !t.is_active).length,
|
|
689
695
|
}), [tokens]);
|
|
690
696
|
|
|
691
697
|
// Gefilterte und sortierte Tokens
|
|
@@ -703,13 +709,14 @@ const TokensProfessional = () => {
|
|
|
703
709
|
// Status Filter
|
|
704
710
|
if (filterStatus !== 'all') {
|
|
705
711
|
filtered = filtered.filter(token => {
|
|
712
|
+
const isExpired = token.expires_at && new Date(token.expires_at) < new Date();
|
|
706
713
|
switch (filterStatus) {
|
|
707
714
|
case 'active':
|
|
708
|
-
return
|
|
715
|
+
return token.is_active && !isExpired;
|
|
709
716
|
case 'expired':
|
|
710
|
-
return
|
|
717
|
+
return isExpired;
|
|
711
718
|
case 'used':
|
|
712
|
-
return token.
|
|
719
|
+
return !token.is_active;
|
|
713
720
|
default:
|
|
714
721
|
return true;
|
|
715
722
|
}
|
|
@@ -939,12 +946,16 @@ const TokensProfessional = () => {
|
|
|
939
946
|
};
|
|
940
947
|
|
|
941
948
|
const getStatusBadge = (token) => {
|
|
942
|
-
|
|
949
|
+
// Prüfe zuerst is_active - wenn false, wurde der Token verwendet oder blockiert
|
|
950
|
+
if (!token.is_active) {
|
|
943
951
|
return <AnimatedBadge variant="secondary">{formatMessage({ id: getTrad('tokens.status.used') })}</AnimatedBadge>;
|
|
944
952
|
}
|
|
945
|
-
|
|
953
|
+
// Prüfe ob abgelaufen
|
|
954
|
+
const isExpired = token.expires_at && new Date(token.expires_at) < new Date();
|
|
955
|
+
if (isExpired) {
|
|
946
956
|
return <AnimatedBadge variant="warning">{formatMessage({ id: getTrad('tokens.status.expired') })}</AnimatedBadge>;
|
|
947
957
|
}
|
|
958
|
+
// Token ist aktiv und nicht abgelaufen
|
|
948
959
|
return <AnimatedBadge variant="success">{formatMessage({ id: getTrad('tokens.status.active') })}</AnimatedBadge>;
|
|
949
960
|
};
|
|
950
961
|
|
|
@@ -369,9 +369,15 @@ const TokensRedesign = () => {
|
|
|
369
369
|
// Stats berechnen
|
|
370
370
|
const stats = {
|
|
371
371
|
total: tokens.length,
|
|
372
|
-
active: tokens.filter(t =>
|
|
373
|
-
|
|
374
|
-
|
|
372
|
+
active: tokens.filter(t => {
|
|
373
|
+
const isExpired = t.expires_at && new Date(t.expires_at) < new Date();
|
|
374
|
+
return t.is_active && !isExpired;
|
|
375
|
+
}).length,
|
|
376
|
+
expired: tokens.filter(t => {
|
|
377
|
+
const isExpired = t.expires_at && new Date(t.expires_at) < new Date();
|
|
378
|
+
return isExpired;
|
|
379
|
+
}).length,
|
|
380
|
+
used: tokens.filter(t => !t.is_active).length,
|
|
375
381
|
};
|
|
376
382
|
|
|
377
383
|
// Stat Cards Konfiguration
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.
|
|
2
|
+
"version": "4.4.1",
|
|
3
3
|
"keywords": [],
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"exports": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"name": "strapi-plugin-magic-link-v5",
|
|
62
62
|
"description": "This plugin provides passwordless authentication via magic links sent to email",
|
|
63
|
-
"license": "
|
|
63
|
+
"license": "MIT",
|
|
64
64
|
"private": false,
|
|
65
65
|
"author": "Schero A. <124470865+begservice@users.noreply.github.com>",
|
|
66
66
|
"repository": {
|
package/LICENSE-DUAL.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# DUAL LICENSE
|
|
2
|
-
|
|
3
|
-
This software is available under a dual licensing model.
|
|
4
|
-
|
|
5
|
-
## 1. GNU AFFERO GENERAL PUBLIC LICENSE (AGPL-3.0)
|
|
6
|
-
|
|
7
|
-
If you are creating an open-source application under a license compatible with
|
|
8
|
-
the GNU AGPL-3.0, you may use this software under those terms.
|
|
9
|
-
|
|
10
|
-
**Key Requirements:**
|
|
11
|
-
- You MUST make your complete source code available
|
|
12
|
-
- You MUST license your application under AGPL-3.0
|
|
13
|
-
- Network use counts as distribution (you must share code even for SaaS)
|
|
14
|
-
- You MUST provide prominent notice and attribution
|
|
15
|
-
|
|
16
|
-
See: https://www.gnu.org/licenses/agpl-3.0.html
|
|
17
|
-
|
|
18
|
-
## 2. COMMERCIAL LICENSE
|
|
19
|
-
|
|
20
|
-
If you want to use this software in a proprietary/commercial application
|
|
21
|
-
WITHOUT the obligations of AGPL-3.0, you must purchase a commercial license.
|
|
22
|
-
|
|
23
|
-
**Commercial License Benefits:**
|
|
24
|
-
- No obligation to open-source your code
|
|
25
|
-
- Can be used in proprietary/closed-source applications
|
|
26
|
-
- Can be used in SaaS without sharing code
|
|
27
|
-
- Priority support and updates
|
|
28
|
-
- No copyleft requirements
|
|
29
|
-
|
|
30
|
-
**Purchase:** [Deine Website]
|
|
31
|
-
**Contact:** [Deine Email]
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
**Note:** Using this software without a valid license (either AGPL-3.0 compliance
|
|
36
|
-
or commercial license) is copyright infringement and will be prosecuted.
|
|
37
|
-
|
package/LICENSE_GUARD.md
DELETED
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
# Magic Link License Guard
|
|
2
|
-
|
|
3
|
-
Der License Guard schützt und verwaltet das Magic Link Plugin über das bestehende License API System.
|
|
4
|
-
|
|
5
|
-
## 🚀 Features
|
|
6
|
-
|
|
7
|
-
- ✅ **Automatische Lizenz-Initialisierung** beim Plugin-Start
|
|
8
|
-
- ✅ **Auto-Ping alle 15 Minuten** für Online-Tracking
|
|
9
|
-
- ✅ **Geräteerkennung** (DeviceID, DeviceName, IP, UserAgent)
|
|
10
|
-
- ✅ **Grace Period Support** (24h Offline-Nutzung)
|
|
11
|
-
- ✅ **Admin-Endpoints** für Lizenzverwaltung
|
|
12
|
-
- ✅ **Automatisches Cleanup** beim Plugin-Stop
|
|
13
|
-
|
|
14
|
-
## 📋 Wie es funktioniert
|
|
15
|
-
|
|
16
|
-
### 1. Beim Plugin-Start
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
Plugin startet → License Guard initialisiert
|
|
20
|
-
↓
|
|
21
|
-
Lizenzschlüssel im Store?
|
|
22
|
-
↓ JA ↓ NEIN
|
|
23
|
-
Verifizieren Demo-Mode
|
|
24
|
-
↓ ↓
|
|
25
|
-
Gültig? Warnung anzeigen
|
|
26
|
-
↓ JA ↓ NEIN
|
|
27
|
-
Ping starten Demo-Mode
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### 2. Automatisches Pinging
|
|
31
|
-
|
|
32
|
-
Alle 15 Minuten sendet der Guard automatisch:
|
|
33
|
-
```json
|
|
34
|
-
POST /api/licenses/ping
|
|
35
|
-
{
|
|
36
|
-
"licenseKey": "A1B2-C3D4-E5F6-G7H8"
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Dies aktualisiert:
|
|
41
|
-
- `lastPingAt` - Aktueller Zeitstempel
|
|
42
|
-
- `lastActiveAt` - Aktivitäts-Tracker
|
|
43
|
-
- `isOnline` - Online-Status basierend auf Grace Period
|
|
44
|
-
|
|
45
|
-
## 🎯 Verwendung
|
|
46
|
-
|
|
47
|
-
### Option 1: Lizenz über API erstellen
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
curl -X POST http://localhost:1337/api/licenses/create \
|
|
51
|
-
-H "Content-Type: application/json" \
|
|
52
|
-
-d '{
|
|
53
|
-
"email": "admin@example.com",
|
|
54
|
-
"firstName": "Admin",
|
|
55
|
-
"lastName": "User",
|
|
56
|
-
"deviceName": "Server-01",
|
|
57
|
-
"deviceId": "device-abc-123",
|
|
58
|
-
"ipAddress": "192.168.1.100",
|
|
59
|
-
"userAgent": "Strapi/5.11.2"
|
|
60
|
-
}'
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
**Response:**
|
|
64
|
-
```json
|
|
65
|
-
{
|
|
66
|
-
"success": true,
|
|
67
|
-
"message": "License created successfully",
|
|
68
|
-
"data": {
|
|
69
|
-
"id": 1,
|
|
70
|
-
"licenseKey": "A1B2-C3D4-E5F6-G7H8",
|
|
71
|
-
"email": "admin@example.com",
|
|
72
|
-
"isActive": true,
|
|
73
|
-
...
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Der License Guard erkennt automatisch die neue Lizenz beim nächsten Start!
|
|
79
|
-
|
|
80
|
-
### Option 2: Auto-Create über Admin-Endpoint
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
curl -X POST http://localhost:1337/magic-link/license/auto-create
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Erstellt automatisch eine Lizenz mit Standard-Daten und aktiviert sie sofort.
|
|
87
|
-
|
|
88
|
-
### Option 3: Programmatisch erstellen
|
|
89
|
-
|
|
90
|
-
```javascript
|
|
91
|
-
// Im Strapi-Code oder Terminal
|
|
92
|
-
await strapi
|
|
93
|
-
.plugin('magic-link')
|
|
94
|
-
.service('license-guard')
|
|
95
|
-
.autoCreateLicense('your@email.com', 'First', 'Last');
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## 📡 Admin-Endpoints
|
|
99
|
-
|
|
100
|
-
Alle Endpoints sind unter `/magic-link/...` verfügbar:
|
|
101
|
-
|
|
102
|
-
| Endpoint | Methode | Beschreibung |
|
|
103
|
-
|----------|---------|--------------|
|
|
104
|
-
| `/license/status` | GET | Aktueller Lizenz-Status |
|
|
105
|
-
| `/license/create` | POST | Lizenz erstellen & aktivieren |
|
|
106
|
-
| `/license/auto-create` | POST | Auto-Lizenz mit Defaults |
|
|
107
|
-
| `/license/ping` | POST | Manueller Ping |
|
|
108
|
-
| `/license/stats` | GET | Online-Statistiken |
|
|
109
|
-
| `/license/deactivate` | POST | Lizenz deaktivieren |
|
|
110
|
-
|
|
111
|
-
### Beispiele
|
|
112
|
-
|
|
113
|
-
**Status abfragen:**
|
|
114
|
-
```bash
|
|
115
|
-
curl http://localhost:1337/magic-link/license/status
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**Response:**
|
|
119
|
-
```json
|
|
120
|
-
{
|
|
121
|
-
"success": true,
|
|
122
|
-
"valid": true,
|
|
123
|
-
"data": {
|
|
124
|
-
"licenseKey": "A1B2-C3D4-E5F6-G7H8",
|
|
125
|
-
"isActive": true,
|
|
126
|
-
"isExpired": false,
|
|
127
|
-
"isOnline": true,
|
|
128
|
-
"expiresAt": "2026-10-13T10:00:00.000Z",
|
|
129
|
-
"lastPingAt": "2025-10-13T21:00:00.000Z",
|
|
130
|
-
"deviceName": "MacBook-Pro.local",
|
|
131
|
-
"features": {
|
|
132
|
-
"premium": true,
|
|
133
|
-
"advanced": false,
|
|
134
|
-
"enterprise": false,
|
|
135
|
-
"custom": false
|
|
136
|
-
},
|
|
137
|
-
"maxDevices": 1,
|
|
138
|
-
"currentDevices": 1
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
**Manuelle Ping:**
|
|
144
|
-
```bash
|
|
145
|
-
curl -X POST http://localhost:1337/magic-link/license/ping
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
**Online-Statistiken:**
|
|
149
|
-
```bash
|
|
150
|
-
curl http://localhost:1337/magic-link/license/stats
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## 🔧 Gesammelte Daten
|
|
154
|
-
|
|
155
|
-
Der License Guard sammelt automatisch:
|
|
156
|
-
|
|
157
|
-
### Device Information
|
|
158
|
-
- **DeviceID**: SHA256-Hash von MAC-Adressen + Hostname
|
|
159
|
-
- **DeviceName**: System-Hostname (z.B. "MacBook-Pro.local")
|
|
160
|
-
- **IP Address**: Server-IP (erste nicht-interne IPv4)
|
|
161
|
-
- **User Agent**: "Strapi/{version} Node/{version} {platform}/{release}"
|
|
162
|
-
|
|
163
|
-
### Beispiel gesammelte Daten:
|
|
164
|
-
```javascript
|
|
165
|
-
{
|
|
166
|
-
deviceId: "a3f8e92c1d4b5e6f7a8b9c0d1e2f3a4b",
|
|
167
|
-
deviceName: "MacBook-Pro.local",
|
|
168
|
-
ipAddress: "192.168.1.100",
|
|
169
|
-
userAgent: "Strapi/5.11.2 Node/v20.11.0 darwin/23.0.0"
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## 📊 Console Output
|
|
174
|
-
|
|
175
|
-
Beim Plugin-Start siehst du eine dieser Meldungen:
|
|
176
|
-
|
|
177
|
-
### ✅ Lizenz aktiv:
|
|
178
|
-
```
|
|
179
|
-
╔════════════════════════════════════════════════════════════════╗
|
|
180
|
-
║ ✅ MAGIC LINK PLUGIN LICENSE ACTIVE ║
|
|
181
|
-
║ ║
|
|
182
|
-
║ License: A1B2-C3D4-E5F6-G7H8 ║
|
|
183
|
-
║ User: Max Mustermann ║
|
|
184
|
-
║ Email: max@example.com ║
|
|
185
|
-
║ ║
|
|
186
|
-
║ 🔄 Auto-pinging every 15 minutes ║
|
|
187
|
-
╚════════════════════════════════════════════════════════════════╝
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### ⚠️ Demo-Mode:
|
|
191
|
-
```
|
|
192
|
-
╔════════════════════════════════════════════════════════════════╗
|
|
193
|
-
║ ⚠️ MAGIC LINK PLUGIN RUNNING IN DEMO MODE ║
|
|
194
|
-
║ ║
|
|
195
|
-
║ To activate, create a license: ║
|
|
196
|
-
║ POST http://localhost:1337/api/licenses/create ║
|
|
197
|
-
║ ║
|
|
198
|
-
║ Or auto-create with: ║
|
|
199
|
-
║ strapi.plugin("magic-link").service("license-guard") ║
|
|
200
|
-
║ .autoCreateLicense("your@email.com", "First", "Last") ║
|
|
201
|
-
╚════════════════════════════════════════════════════════════════╝
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
## 🔄 Lifecycle
|
|
205
|
-
|
|
206
|
-
### Bootstrap (Plugin Start)
|
|
207
|
-
1. License Guard Service wird geladen
|
|
208
|
-
2. Nach 3 Sekunden: Initialize()
|
|
209
|
-
3. Prüfe auf gespeicherten Lizenzschlüssel
|
|
210
|
-
4. Verifiziere Lizenz
|
|
211
|
-
5. Starte Auto-Ping (alle 15 Min)
|
|
212
|
-
|
|
213
|
-
### Destroy (Plugin Stop)
|
|
214
|
-
1. Stoppe Ping-Interval
|
|
215
|
-
2. Cleanup-Log
|
|
216
|
-
|
|
217
|
-
## 💻 Integration in dein Plugin
|
|
218
|
-
|
|
219
|
-
### Lizenz-Status im Admin-Panel anzeigen
|
|
220
|
-
|
|
221
|
-
Erstelle eine Settings-Seite mit Lizenz-Info:
|
|
222
|
-
|
|
223
|
-
```javascript
|
|
224
|
-
// In deiner Settings-Component
|
|
225
|
-
const { data: licenseStatus } = await get('/magic-link/license/status');
|
|
226
|
-
|
|
227
|
-
if (licenseStatus.valid) {
|
|
228
|
-
console.log('✅ License active:', licenseStatus.data.licenseKey);
|
|
229
|
-
console.log('Features:', licenseStatus.data.features);
|
|
230
|
-
} else {
|
|
231
|
-
console.log('⚠️ Demo mode or invalid license');
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Lizenz erstellen aus dem Admin-Panel
|
|
236
|
-
|
|
237
|
-
```javascript
|
|
238
|
-
const createLicense = async () => {
|
|
239
|
-
const response = await post('/magic-link/license/create', {
|
|
240
|
-
email: 'user@example.com',
|
|
241
|
-
firstName: 'John',
|
|
242
|
-
lastName: 'Doe',
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
if (response.data.success) {
|
|
246
|
-
console.log('License created:', response.data.data.licenseKey);
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
## 🔐 Sicherheit
|
|
252
|
-
|
|
253
|
-
- ✅ **DeviceID ist persistent** - Basiert auf Hardware
|
|
254
|
-
- ✅ **Eindeutige Identifikation** - SHA256-Hash
|
|
255
|
-
- ✅ **Keine Speicherung sensibler Daten** - Nur Hashes
|
|
256
|
-
- ✅ **GDPR-konform** - User-Daten anonymisiert
|
|
257
|
-
|
|
258
|
-
## 🛠 Troubleshooting
|
|
259
|
-
|
|
260
|
-
### Plugin startet im Demo-Mode
|
|
261
|
-
|
|
262
|
-
**Ursache:** Keine Lizenz gefunden oder Lizenz ungültig
|
|
263
|
-
|
|
264
|
-
**Lösung:**
|
|
265
|
-
```bash
|
|
266
|
-
# Option 1: Auto-Create
|
|
267
|
-
curl -X POST http://localhost:1337/magic-link/license/auto-create
|
|
268
|
-
|
|
269
|
-
# Option 2: Manuell über License API
|
|
270
|
-
curl -X POST http://localhost:1337/api/licenses/create \
|
|
271
|
-
-H "Content-Type: application/json" \
|
|
272
|
-
-d '{"email":"admin@localhost","firstName":"Admin","lastName":"User"}'
|
|
273
|
-
|
|
274
|
-
# Option 3: Im Strapi Terminal
|
|
275
|
-
await strapi.plugin('magic-link').service('license-guard')
|
|
276
|
-
.autoCreateLicense('admin@example.com', 'Admin', 'User');
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Pinging funktioniert nicht
|
|
280
|
-
|
|
281
|
-
**Prüfen:**
|
|
282
|
-
```bash
|
|
283
|
-
# Manueller Ping
|
|
284
|
-
curl -X POST http://localhost:1337/magic-link/license/ping
|
|
285
|
-
|
|
286
|
-
# Status prüfen
|
|
287
|
-
curl http://localhost:1337/magic-link/license/status
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### Lizenz als "offline" markiert
|
|
291
|
-
|
|
292
|
-
- Grace Period ist abgelaufen (>24h kein Ping)
|
|
293
|
-
- Pinging wurde gestoppt
|
|
294
|
-
- Netzwerk-Probleme
|
|
295
|
-
|
|
296
|
-
**Lösung:** Einmal pingen → `isOnline` wird wieder auf `true` gesetzt
|
|
297
|
-
|
|
298
|
-
## 📚 Logs
|
|
299
|
-
|
|
300
|
-
Der License Guard loggt:
|
|
301
|
-
|
|
302
|
-
```
|
|
303
|
-
[INFO] 🔐 Initializing License Guard...
|
|
304
|
-
[INFO] 📄 Found existing license key: A1B2-C3D4-E5F6-G7H8
|
|
305
|
-
[INFO] ✅ License is valid and active
|
|
306
|
-
[INFO] 📡 Started pinging license every 15 minutes
|
|
307
|
-
[DEBUG] 📡 License ping successful: A1B2-C3D4-E5F6-G7H8
|
|
308
|
-
[INFO] 🛑 License pinging stopped
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
## 🎉 Fertig!
|
|
312
|
-
|
|
313
|
-
Der License Guard läuft nun automatisch im Hintergrund:
|
|
314
|
-
- ✅ Verifiziert beim Start
|
|
315
|
-
- ✅ Pingt alle 15 Minuten
|
|
316
|
-
- ✅ Tracked Online-Status
|
|
317
|
-
- ✅ Bereit für Production
|
|
318
|
-
|
|
319
|
-
Für weitere Informationen siehe:
|
|
320
|
-
- `/src/api/license/README.md` - License API Dokumentation
|
|
321
|
-
- `/src/api/license/TRACKING.md` - Tracking-Details
|
|
322
|
-
- `/src/api/license/SUMMARY.md` - Zusammenfassung
|
|
323
|
-
|
package/SECURITY.md
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# Security & License Protection
|
|
2
|
-
|
|
3
|
-
## License Enforcement
|
|
4
|
-
|
|
5
|
-
This software includes multiple layers of license protection:
|
|
6
|
-
|
|
7
|
-
### 1. Backend License Check
|
|
8
|
-
- API endpoints are protected by `license-check` policy
|
|
9
|
-
- All requests are validated against active license
|
|
10
|
-
- Invalid/expired licenses are rejected with 401 status
|
|
11
|
-
|
|
12
|
-
### 2. Frontend License Guard
|
|
13
|
-
- Admin UI displays activation modal without valid license
|
|
14
|
-
- Prevents unauthorized UI access
|
|
15
|
-
- Requires license activation before use
|
|
16
|
-
|
|
17
|
-
### 3. License Verification
|
|
18
|
-
- License keys are validated against central license database
|
|
19
|
-
- Regular "ping" mechanism ensures license is active
|
|
20
|
-
- Offline grace period for temporary network issues
|
|
21
|
-
|
|
22
|
-
## Anti-Piracy Measures
|
|
23
|
-
|
|
24
|
-
### Current Protection:
|
|
25
|
-
1. **License Key Validation**: Server-side verification
|
|
26
|
-
2. **Device Binding**: License tied to specific server instances
|
|
27
|
-
3. **Online Checks**: Regular validation against license server
|
|
28
|
-
4. **IP Tracking**: Monitor and limit license usage by IP
|
|
29
|
-
5. **Audit Logging**: All license operations are logged
|
|
30
|
-
|
|
31
|
-
### Additional Recommendations:
|
|
32
|
-
|
|
33
|
-
#### Code Obfuscation (Optional)
|
|
34
|
-
Consider obfuscating critical parts of the code:
|
|
35
|
-
```bash
|
|
36
|
-
npm install javascript-obfuscator --save-dev
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
#### API Key Protection
|
|
40
|
-
Never commit license server API credentials to git:
|
|
41
|
-
```bash
|
|
42
|
-
# Add to .env
|
|
43
|
-
LICENSE_SERVER_URL=https://your-license-server.com
|
|
44
|
-
LICENSE_API_KEY=your-secret-key
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
#### Monitoring
|
|
48
|
-
Set up monitoring for:
|
|
49
|
-
- Unusual license activation patterns
|
|
50
|
-
- Multiple IPs using same license
|
|
51
|
-
- Attempts to bypass license checks
|
|
52
|
-
|
|
53
|
-
## Reporting License Violations
|
|
54
|
-
|
|
55
|
-
If you discover unauthorized use of this software:
|
|
56
|
-
|
|
57
|
-
**Email:** [Your Email]
|
|
58
|
-
**Subject:** License Violation Report
|
|
59
|
-
|
|
60
|
-
Include:
|
|
61
|
-
- URL or location where unauthorized use was found
|
|
62
|
-
- Screenshots/evidence
|
|
63
|
-
- Any relevant information
|
|
64
|
-
|
|
65
|
-
We take license violations seriously and will pursue legal action when necessary.
|
|
66
|
-
|
|
67
|
-
## Legal Notice
|
|
68
|
-
|
|
69
|
-
Unauthorized use, copying, or distribution of this software constitutes:
|
|
70
|
-
- Copyright infringement
|
|
71
|
-
- Breach of software license agreement
|
|
72
|
-
- Potential criminal violation under applicable laws
|
|
73
|
-
|
|
74
|
-
Violators will be prosecuted to the fullest extent of the law.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
**Last Updated:** 2025-01-13
|
|
79
|
-
|