@vivinkv28/strapi-2fa-admin-plugin 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/README.md +183 -3
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -15,8 +15,9 @@ This package does **not** replace the Strapi admin login UI by itself. You still
15
15
 
16
16
  ## Documentation
17
17
 
18
- - [Integration guide](./docs/INTEGRATION.md)
19
- - [Architecture guide](./docs/ARCHITECTURE.md)
18
+ - [Integration Guide](#integration-guide)
19
+ - [Architecture Guide](#architecture-guide)
20
+ - [Admin UI Integration](#admin-ui-integration)
20
21
 
21
22
  ## Endpoints
22
23
 
@@ -26,7 +27,7 @@ The plugin exposes these content API routes:
26
27
  - `POST /api/admin-2fa/verify`
27
28
  - `POST /api/admin-2fa/resend`
28
29
 
29
- See the full request and response flow in [docs/INTEGRATION.md](./docs/INTEGRATION.md).
30
+ See the detailed request and response flow in the `Integration Guide` section below.
30
31
 
31
32
  ## Requirements
32
33
 
@@ -128,6 +129,185 @@ This plugin is backend-only. To use it for real admin login 2FA, your project mu
128
129
  - optionally call `POST /api/admin-2fa/resend`
129
130
 
130
131
  The expected frontend flow, payloads, and response handling are documented in [docs/INTEGRATION.md](./docs/INTEGRATION.md).
132
+ The expected frontend flow, payloads, and response handling are documented in the `Integration Guide` and `Admin UI Integration` sections below.
133
+
134
+ ## Integration Guide
135
+
136
+ This plugin is intended to be used as the backend engine for an admin OTP login flow.
137
+
138
+ The normal integration flow is:
139
+
140
+ 1. collect admin email and password
141
+ 2. call `POST /api/admin-2fa/login`
142
+ 3. display an OTP entry screen
143
+ 4. call `POST /api/admin-2fa/verify`
144
+ 5. optionally call `POST /api/admin-2fa/resend`
145
+
146
+ ### Login request
147
+
148
+ ```http
149
+ POST /api/admin-2fa/login
150
+ Content-Type: application/json
151
+ ```
152
+
153
+ Example payload:
154
+
155
+ ```json
156
+ {
157
+ "email": "admin@example.com",
158
+ "password": "super-secret-password",
159
+ "rememberMe": true,
160
+ "deviceId": "browser-device-id"
161
+ }
162
+ ```
163
+
164
+ Example success response:
165
+
166
+ ```json
167
+ {
168
+ "data": {
169
+ "challengeId": "0d3af6fd-b351-4d1e-bb81-2a8201d8a0f4",
170
+ "expiresAt": "2026-04-05T18:30:00.000Z",
171
+ "maskedEmail": "admin@example.com",
172
+ "rememberMe": true
173
+ }
174
+ }
175
+ ```
176
+
177
+ ### Verify request
178
+
179
+ ```http
180
+ POST /api/admin-2fa/verify
181
+ Content-Type: application/json
182
+ ```
183
+
184
+ Example payload:
185
+
186
+ ```json
187
+ {
188
+ "challengeId": "0d3af6fd-b351-4d1e-bb81-2a8201d8a0f4",
189
+ "code": "123456"
190
+ }
191
+ ```
192
+
193
+ Example success response:
194
+
195
+ ```json
196
+ {
197
+ "data": {
198
+ "token": "<access-token>",
199
+ "accessToken": "<access-token>",
200
+ "user": {
201
+ "id": 1,
202
+ "email": "admin@example.com"
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ ### Resend request
209
+
210
+ ```http
211
+ POST /api/admin-2fa/resend
212
+ Content-Type: application/json
213
+ ```
214
+
215
+ Example payload:
216
+
217
+ ```json
218
+ {
219
+ "challengeId": "0d3af6fd-b351-4d1e-bb81-2a8201d8a0f4"
220
+ }
221
+ ```
222
+
223
+ ### UI error states to handle
224
+
225
+ - invalid email or password
226
+ - OTP expired
227
+ - OTP session not found
228
+ - invalid OTP code
229
+ - too many authentication attempts
230
+ - resend limit exceeded
231
+
232
+ ## Admin UI Integration
233
+
234
+ This package is backend-focused. To make it usable in a real Strapi admin login flow, the host project must provide an admin-side integration.
235
+
236
+ A typical admin UI integration has two screens or states:
237
+
238
+ ### 1. Credentials step
239
+
240
+ - collect email and password
241
+ - send them to `/api/admin-2fa/login`
242
+ - if successful, store `challengeId` in memory and switch the UI into OTP mode
243
+
244
+ ### 2. OTP step
245
+
246
+ - collect the OTP code
247
+ - submit it to `/api/admin-2fa/verify`
248
+ - if successful, continue the normal authenticated admin flow
249
+ - provide a resend button that calls `/api/admin-2fa/resend`
250
+
251
+ ### Recommended UI behavior
252
+
253
+ - keep login and OTP as separate form states
254
+ - do not create a session after password validation alone
255
+ - only treat the login as complete after `/verify` succeeds
256
+ - if resend or verify says the challenge expired, restart from the credentials step
257
+
258
+ ### Current integration approach used by the example project
259
+
260
+ In the companion Strapi app used during development, the admin login UI is integrated by patching Strapi's admin login screen and auth service so they call:
261
+
262
+ - `/api/admin-2fa/login`
263
+ - `/api/admin-2fa/verify`
264
+ - `/api/admin-2fa/resend`
265
+
266
+ This plugin itself does not inject that UI automatically. That choice is left to the host app because Strapi admin login customization is more app-specific than the backend OTP engine.
267
+
268
+ ## Architecture Guide
269
+
270
+ The plugin has a minimal admin entry and a backend-focused server implementation.
271
+
272
+ ### Main files
273
+
274
+ ```text
275
+ admin/src/index.js
276
+ server/src/index.js
277
+ server/src/routes/index.js
278
+ server/src/controllers/auth.js
279
+ server/src/services/auth.js
280
+ server/src/utils/strapi-session-auth.js
281
+ ```
282
+
283
+ ### Responsibilities
284
+
285
+ - `admin/src/index.js`
286
+ Minimal admin plugin stub required by the Strapi Plugin SDK.
287
+
288
+ - `server/src/routes/index.js`
289
+ Declares the plugin routes for login, verify, and resend.
290
+
291
+ - `server/src/controllers/auth.js`
292
+ Reads requests, extracts client IP, delegates to the service, and sets the admin refresh cookie after successful verification.
293
+
294
+ - `server/src/services/auth.js`
295
+ Core OTP logic: credential validation, challenge lifecycle, resend/verify rules, rate limiting, email sending, and final session creation.
296
+
297
+ - `server/src/utils/strapi-session-auth.js`
298
+ Runtime helper that resolves Strapi's internal admin session utility needed to create the final admin session.
299
+
300
+ ### Security model
301
+
302
+ - password-only login is not enough
303
+ - raw OTP values are never stored
304
+ - OTPs expire
305
+ - verify/resend/login are rate-limited
306
+ - the final Strapi admin session is created only after OTP verification
307
+
308
+ ### Important limitation
309
+
310
+ This is email OTP, not TOTP or WebAuthn. It improves admin security substantially, but it is still weaker than authenticator-app or passkey-based 2FA.
131
311
 
132
312
  If you already maintain a patched Strapi admin login screen, point it to:
133
313
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vivinkv28/strapi-2fa-admin-plugin",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Reusable Strapi admin 2FA plugin",
5
5
  "type": "commonjs",
6
6
  "keywords": [