mulguard 1.1.5 → 1.1.7

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 (61) hide show
  1. package/README.md +210 -706
  2. package/dist/actions-CMtg7FGv.js +1 -0
  3. package/dist/{actions-DeCfLtHA.mjs → actions-CjQUKaXF.mjs} +54 -38
  4. package/dist/client/index.js +1 -1
  5. package/dist/client/index.mjs +84 -78
  6. package/dist/core/auth/email-password.d.ts +145 -0
  7. package/dist/core/auth/oauth/index.d.ts +14 -0
  8. package/dist/core/auth/oauth/oauth-handler.d.ts +172 -0
  9. package/dist/core/auth/oauth/pkce.d.ts +168 -0
  10. package/dist/core/auth/{oauth-providers.d.ts → oauth/providers.d.ts} +8 -7
  11. package/dist/core/auth/{oauth-state-store-cookie.d.ts → oauth/state-store-cookie.d.ts} +4 -4
  12. package/dist/core/auth/{oauth-state-store-redis.d.ts → oauth/state-store-redis.d.ts} +1 -1
  13. package/dist/core/auth/{oauth-state-store.d.ts → oauth/state-store.d.ts} +4 -1
  14. package/dist/core/auth/otp.d.ts +184 -0
  15. package/dist/core/errors/index.d.ts +269 -0
  16. package/dist/core/index.d.ts +1 -3
  17. package/dist/core/logger/index.d.ts +147 -0
  18. package/dist/core/mulguard/integration.d.ts +104 -0
  19. package/dist/core/mulguard/oauth-handler.d.ts +1 -1
  20. package/dist/core/security/security-manager.d.ts +236 -0
  21. package/dist/core/session/session-manager.d.ts +235 -0
  22. package/dist/core/types/index.d.ts +27 -5
  23. package/dist/index/index.js +1 -1
  24. package/dist/index/index.mjs +1383 -869
  25. package/dist/index.d.ts +3 -6
  26. package/dist/{client → nextjs/client}/hooks.d.ts +2 -2
  27. package/dist/nextjs/client/index.d.ts +13 -0
  28. package/dist/{client → nextjs/client}/provider.d.ts +1 -1
  29. package/dist/{client → nextjs/client}/server-actions-helper.d.ts +2 -2
  30. package/dist/{handlers → nextjs/handlers}/api.d.ts +1 -1
  31. package/dist/nextjs/handlers/index.d.ts +9 -0
  32. package/dist/{handlers → nextjs/handlers}/route.d.ts +1 -1
  33. package/dist/nextjs/index.d.ts +15 -0
  34. package/dist/nextjs/proxy/index.d.ts +149 -0
  35. package/dist/nextjs/server/actions.d.ts +30 -0
  36. package/dist/{server → nextjs/server}/auth.d.ts +6 -6
  37. package/dist/{server → nextjs/server}/cookies.d.ts +5 -6
  38. package/dist/nextjs/server/index.d.ts +18 -0
  39. package/dist/{server → nextjs/server}/oauth-state.d.ts +5 -3
  40. package/dist/{server → nextjs/server}/session-helpers.d.ts +1 -3
  41. package/dist/nextjs/server/session.d.ts +144 -0
  42. package/dist/oauth-state-Drwz6fES.js +1 -0
  43. package/dist/oauth-state-pdypStuS.mjs +210 -0
  44. package/dist/server/index.js +1 -1
  45. package/dist/server/index.mjs +27 -29
  46. package/package.json +64 -11
  47. package/dist/actions-CExpv_dD.js +0 -1
  48. package/dist/client/index.d.ts +0 -5
  49. package/dist/core/auth/index.d.ts +0 -40
  50. package/dist/core/auth/oauth.d.ts +0 -20
  51. package/dist/middleware/index.d.ts +0 -28
  52. package/dist/middleware/proxy.d.ts +0 -53
  53. package/dist/oauth-state-CzIWQq3s.js +0 -1
  54. package/dist/oauth-state-LE-qeq-K.mjs +0 -282
  55. package/dist/server/actions.d.ts +0 -86
  56. package/dist/server/helpers.d.ts +0 -10
  57. package/dist/server/index.d.ts +0 -14
  58. package/dist/server/middleware.d.ts +0 -39
  59. package/dist/server/session.d.ts +0 -28
  60. package/dist/server/utils.d.ts +0 -10
  61. /package/dist/{middleware → nextjs/proxy}/security.d.ts +0 -0
package/README.md CHANGED
@@ -1,76 +1,66 @@
1
1
  # Mulguard
2
2
 
3
- > A modern, backend-first authentication library for Next.js applications
3
+ > A modern, production-ready authentication library for Next.js 16+ (App Router)
4
4
 
5
5
  [![License: MUV](https://img.shields.io/badge/License-MUV-blue.svg)](LICENSE)
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.3+-blue.svg)](https://www.typescriptlang.org/)
7
- [![Next.js](https://img.shields.io/badge/Next.js-14.0+-black.svg)](https://nextjs.org/)
7
+ [![Next.js](https://img.shields.io/badge/Next.js-16.0+-black.svg)](https://nextjs.org/)
8
8
 
9
- **Mulguard** is a powerful, flexible authentication library designed specifically for Next.js applications. Built with a backend-first architecture, it gives you complete control over your authentication logic while providing a simple, intuitive API similar to popular libraries like `better-auth` and `auth.js`.
9
+ **Mulguard** is a powerful, flexible authentication library designed specifically for Next.js 16+ applications. Built with a **backend-first architecture**, it gives you complete control over your authentication logic while providing a simple, intuitive API.
10
10
 
11
11
  **Part of the [Mulverse](https://mulverse.com) ecosystem** - Empowering modern web applications with robust, secure authentication.
12
12
 
13
13
  ---
14
14
 
15
- ## Table of Contents
16
-
17
- - [Features](#-features)
18
- - [Installation](#-installation)
19
- - [Quick Start](#-quick-start)
20
- - [Core Concepts](#-core-concepts)
21
- - [Authentication Methods](#-authentication-methods)
22
- - [Configuration](#-configuration)
23
- - [Server-Side Usage](#-server-side-usage)
24
- - [Client-Side Usage](#-client-side-usage)
25
- - [Components](#-components)
26
- - [Security](#-security)
27
- - [Backend Integration](#-backend-integration)
28
- - [Advanced Features](#-advanced-features)
29
- - [API Reference](#-api-reference)
30
- - [Examples](#-examples)
31
- - [Testing](#-testing)
32
- - [Contributing](#-contributing)
33
- - [License](#-license)
34
- - [Support](#-support)
35
-
36
- ---
37
-
38
15
  ## ✨ Features
39
16
 
40
17
  ### 🔐 Multiple Authentication Methods
41
- - **Email/Password** - Traditional credential-based authentication
42
- - **OAuth 2.1** - Support for Google, GitHub, and other OAuth providers
43
- - **PassKey/WebAuthn** - Passwordless authentication with biometric support
44
- - **Two-Factor Authentication (2FA/TOTP)** - Time-based one-time passwords with backup codes
18
+ - **Email/Password** - Traditional email and password authentication
19
+ - **OAuth 2.0 with PKCE** - Support for Google, GitHub, and other OAuth providers with automatic PKCE
45
20
  - **OTP** - One-time password authentication
21
+ - **PassKey/WebAuthn** - Passwordless authentication (coming soon)
22
+ - **Two-Factor Authentication (2FA/TOTP)** - Multi-factor authentication support
46
23
 
47
- ### 🎯 Account Picker
48
- - Remember last logged-in users
49
- - Quick re-login experience
50
- - Encrypted local storage for security
51
- - Configurable account limits
24
+ ### Performance
25
+ - **Edge Runtime Support** - Optimized for Edge Runtime where possible
26
+ - **Session Caching** - Built-in session caching for improved performance
27
+ - **Optimized Bundle Size** - Tree-shakeable with minimal bundle impact
28
+ - **Server Actions First** - Leverages Next.js Server Actions for optimal performance
52
29
 
53
30
  ### 🔒 Security First
54
- - **CSRF Protection** - Token-based cross-site request forgery protection
55
- - **XSS Prevention** - Input sanitization and HTML escaping
56
- - **Security Headers** - Automatic security headers configuration
57
- - **Input Validation** - Comprehensive validation and sanitization
58
- - **Rate Limiting** - Built-in rate limiting utilities
59
- - **Secure Cookies** - HttpOnly, Secure, SameSite cookie configuration
60
-
61
- ### Next.js Optimized
62
- - **Server Components** - Full support for React Server Components
63
- - **Client Hooks** - `useAuth`, `useSession` for client-side state management
64
- - **Middleware Integration** - Seamless Next.js middleware support
65
- - **API Route Handlers** - Pre-built route handlers for authentication endpoints
66
- - **Server Actions** - Native support for Next.js Server Actions
67
-
68
- ### 🔌 Backend-First Architecture
69
- - **No Database Adapter Required** - Works with your existing backend API
70
- - **Custom Actions** - Implement your own authentication logic
71
- - **Flexible Integration** - Works with any backend (REST, GraphQL, etc.)
72
- - **Mulink Integration** - Optional integration with Mulink API client
73
- - **Full TypeScript Support** - Complete type safety throughout
31
+ - **HttpOnly Cookies** - Secure cookie handling prevents XSS attacks
32
+ - **PKCE for OAuth** - Automatic PKCE implementation for OAuth flows
33
+ - **CSRF Protection** - Built-in CSRF token validation
34
+ - **Rate Limiting** - Configurable rate limiting to prevent brute force attacks
35
+ - **Input Validation** - Comprehensive input validation and sanitization
36
+ - **XSS Prevention** - Automatic XSS protection for user inputs
37
+
38
+ ### 🎯 Developer Experience
39
+ - **Type-Safe** - Full TypeScript support with generics and type inference
40
+ - **Simple Setup** - Get started in minutes with minimal configuration
41
+ - **Clear Errors** - Descriptive error messages with error codes
42
+ - **Centralized Logging** - Professional logging system (no manual `console.log` needed)
43
+ - **Unified API** - Single, consistent interface for all authentication methods
44
+
45
+ ### 🔌 Flexible & Extensible
46
+ - **Backend-First** - Works with any backend or database (Prisma, Drizzle, MongoDB, etc.)
47
+ - **Custom Actions** - Implement your own authentication logic without adapters
48
+ - **Plugin System** - Extensible architecture for additional features
49
+ - **Next.js 16+ Proxy** - Uses Proxy pattern instead of middleware (Next.js 16+)
50
+
51
+ ---
52
+
53
+ ## 🎯 Why Mulguard?
54
+
55
+ ### Problems We Solve
56
+
57
+ - ✅ **High Stability** - Production-ready library without common bugs
58
+ - ✅ **Simple Setup** - Quick and easy setup without complexity
59
+ - ✅ **No console.log Needed** - Professional centralized logging system
60
+ - ✅ **No SSR/CSR Issues** - Clear separation between server-side and client-side
61
+ - ✅ **Easy OAuth** - Simple OAuth setup with automatic PKCE
62
+ - ✅ **Excellent Error Handling** - Clear and coded error messages
63
+ - ✅ **Type Safety** - Full TypeScript support with generics
74
64
 
75
65
  ---
76
66
 
@@ -82,10 +72,8 @@ npm install mulguard
82
72
 
83
73
  ### Peer Dependencies
84
74
 
85
- Mulguard requires the following peer dependencies:
86
-
87
75
  ```bash
88
- npm install next@>=14.0.0 react@>=18.0.0 react-dom@>=18.0.0
76
+ npm install next@>=16.0.0 react@>=18.0.0 react-dom@>=18.0.0
89
77
  ```
90
78
 
91
79
  ---
@@ -103,19 +91,18 @@ import { db } from '@/lib/db'
103
91
  import { comparePassword } from '@/lib/password'
104
92
 
105
93
  export const auth = mulguard({
106
- // Session configuration
94
+ // Session configuration (optional)
107
95
  session: {
108
96
  cookieName: '__mulguard_session',
109
97
  expiresIn: 60 * 60 * 24 * 7, // 7 days
110
98
  httpOnly: true,
111
- secure: process.env.NODE_ENV === 'production', // HTTPS only in production
99
+ secure: process.env.NODE_ENV === 'production',
112
100
  sameSite: 'lax',
113
101
  },
114
102
 
115
103
  // Required: Implement your authentication actions
116
104
  actions: {
117
105
  signIn: {
118
- // ✅ Unified interface: auth.signIn('credentials', {...}) or auth.signIn.email({...})
119
106
  email: async (credentials: EmailCredentials): Promise<AuthResult> => {
120
107
  // Your custom sign-in logic
121
108
  const user = await db.user.findUnique({
@@ -146,14 +133,13 @@ export const auth = mulguard({
146
133
 
147
134
  getSession: async (): Promise<Session | null> => {
148
135
  // Your custom session retrieval logic
149
- // Can read from cookie or database
150
- return await db.getSession()
136
+ // The library handles cookie reading automatically
137
+ return null
151
138
  },
152
139
 
153
- signOut: async () => {
140
+ signOut: async (): Promise<void> => {
154
141
  // Your custom sign-out logic
155
- await db.invalidateSession()
156
- return { success: true }
142
+ // The library handles cookie deletion automatically
157
143
  },
158
144
  },
159
145
 
@@ -162,15 +148,10 @@ export const auth = mulguard({
162
148
  oauth: {
163
149
  google: {
164
150
  clientId: process.env.GOOGLE_CLIENT_ID!,
165
- clientSecret: process.env.GOOGLE_CLIENT_SECRET, // Server-side only
151
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET,
166
152
  redirectUri: `${process.env.NEXT_PUBLIC_URL}/api/auth/callback/google`,
167
153
  scopes: ['openid', 'profile', 'email'],
168
- },
169
- github: {
170
- clientId: process.env.GITHUB_CLIENT_ID!,
171
- clientSecret: process.env.GITHUB_CLIENT_SECRET,
172
- redirectUri: `${process.env.NEXT_PUBLIC_URL}/api/auth/callback/github`,
173
- scopes: ['user:email'],
154
+ pkce: true, // Enable PKCE (recommended)
174
155
  },
175
156
  },
176
157
  },
@@ -179,53 +160,26 @@ export const auth = mulguard({
179
160
  callbacks: {
180
161
  onSignIn: async (user, session) => {
181
162
  // Track sign-in analytics, update last login, etc.
182
- console.log('User signed in:', user.email)
183
163
  },
184
164
  onError: async (error, context) => {
185
- // Log errors for monitoring
186
- console.error(`Auth error in ${context}:`, error)
187
- },
188
- // ✅ OAuth callback: receives userInfo with accessToken, refreshToken, profile, etc.
189
- onOAuthUser: async (userInfo, provider) => {
190
- // Backend API example:
191
- // const response = await fetch('/api/v1/auth/oauth/callback', {
192
- // method: 'POST',
193
- // body: JSON.stringify({
194
- // provider,
195
- // access_token: userInfo.accessToken,
196
- // refresh_token: userInfo.refreshToken,
197
- // profile: userInfo,
198
- // email: userInfo.email,
199
- // })
200
- // })
201
- // return await response.json()
202
-
203
- // Database example:
204
- let user = await db.user.findUnique({ where: { email: userInfo.email } })
205
- if (!user) {
206
- user = await db.user.create({
207
- data: {
208
- email: userInfo.email,
209
- name: userInfo.name,
210
- emailVerified: userInfo.emailVerified,
211
- oauthProvider: provider,
212
- }
213
- })
214
- }
215
- return {
216
- id: user.id,
217
- email: user.email,
218
- name: user.name,
219
- emailVerified: user.emailVerified,
220
- }
165
+ // Log errors for monitoring (centralized logging, no console.log needed)
221
166
  },
222
167
  },
223
168
  })
224
169
  ```
225
170
 
226
- > 📖 **For a complete guide with best practices**, see [GUIDE.md](./GUIDE.md)
171
+ ### 2. Create Route Handler
172
+
173
+ Create `app/api/auth/[...mulguard]/route.ts`:
174
+
175
+ ```typescript
176
+ import { toNextJsHandler } from 'mulguard/handlers/route'
177
+ import { auth } from '@/lib/auth'
178
+
179
+ export const { GET, POST } = toNextJsHandler(auth)
180
+ ```
227
181
 
228
- ### 2. Server-Side Usage
182
+ ### 3. Server-Side Usage
229
183
 
230
184
  ```typescript
231
185
  // app/dashboard/page.tsx
@@ -249,7 +203,7 @@ export default async function DashboardPage() {
249
203
  }
250
204
  ```
251
205
 
252
- ### 3. Client-Side Usage
206
+ ### 4. Client-Side Usage
253
207
 
254
208
  ```typescript
255
209
  // app/login/page.tsx
@@ -260,216 +214,112 @@ import { auth } from '@/lib/auth'
260
214
  import { useState } from 'react'
261
215
 
262
216
  export default function LoginPage() {
263
- const { signIn, session, isLoading } = useAuth(auth)
264
- const [email, setEmail] = useState('')
265
- const [password, setPassword] = useState('')
217
+ const { signIn, isLoading } = useAuth(auth)
218
+ const [error, setError] = useState<string | null>(null)
266
219
 
267
- const handleSubmit = async (e: React.FormEvent) => {
220
+ const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
268
221
  e.preventDefault()
222
+ setError(null)
269
223
 
270
- // Unified interface (recommended)
271
- const result = await signIn('credentials', { email, password })
272
-
273
- // Or use direct method:
274
- // const result = await signIn.email({ email, password })
224
+ const formData = new FormData(e.currentTarget)
225
+ const result = await signIn('credentials', {
226
+ email: formData.get('email') as string,
227
+ password: formData.get('password') as string,
228
+ })
275
229
 
276
230
  if (result.success) {
277
- // Redirect to dashboard
278
231
  window.location.href = '/dashboard'
279
232
  } else {
280
- // Handle error
281
- alert(result.error)
233
+ setError(result.error || 'Login failed')
282
234
  }
283
235
  }
284
236
 
285
- if (isLoading) return <div>Loading...</div>
286
- if (session) return <div>Already logged in</div>
287
-
288
237
  return (
289
238
  <form onSubmit={handleSubmit}>
290
- <input
291
- type="email"
292
- value={email}
293
- onChange={(e) => setEmail(e.target.value)}
294
- placeholder="Email"
295
- required
296
- />
297
- <input
298
- type="password"
299
- value={password}
300
- onChange={(e) => setPassword(e.target.value)}
301
- placeholder="Password"
302
- required
303
- />
304
- <button type="submit">Sign In</button>
239
+ <input name="email" type="email" placeholder="Email" required />
240
+ <input name="password" type="password" placeholder="Password" required />
241
+ {error && <p className="error">{error}</p>}
242
+ <button type="submit" disabled={isLoading}>
243
+ {isLoading ? 'Signing in...' : 'Sign In'}
244
+ </button>
305
245
  </form>
306
246
  )
307
247
  }
308
248
  ```
309
249
 
310
- ### 4. Middleware (Optional)
250
+ ### 5. Route Protection (Optional)
251
+
252
+ Create `proxy.ts` in your project root:
311
253
 
312
254
  ```typescript
313
- // middleware.ts
314
- import { createAuthMiddleware } from 'mulguard/middleware'
255
+ // proxy.ts (Next.js 16+)
256
+ import { createProxyMiddleware } from 'mulguard/proxy'
315
257
  import { auth } from '@/lib/auth'
316
258
 
317
- export default createAuthMiddleware(auth, {
259
+ export default createProxyMiddleware(auth, {
318
260
  protectedRoutes: ['/dashboard', '/profile'],
319
261
  redirectTo: '/login',
320
262
  redirectIfAuthenticated: '/dashboard',
321
263
  })
322
264
 
323
265
  export const config = {
324
- matcher: ['/dashboard/:path*', '/profile/:path*'],
266
+ matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
325
267
  }
326
268
  ```
327
269
 
328
- ---
329
-
330
- ## 🎓 Core Concepts
331
-
332
- ### Backend-First Architecture
333
-
334
- Mulguard follows a **backend-first** approach, meaning you implement your own authentication logic through **actions**. This gives you:
335
-
336
- - **Full Control** - Complete control over your authentication flow
337
- - **Flexibility** - Works with any backend architecture
338
- - **No Lock-in** - No database adapter required
339
- - **Custom Logic** - Implement business-specific authentication rules
340
-
341
- ### Actions
342
-
343
- Actions are functions you provide to handle authentication operations:
344
-
345
- ```typescript
346
- actions: {
347
- signIn: {
348
- email: async (credentials) => { /* ... */ },
349
- oauth: async (provider) => { /* ... */ },
350
- passkey: async (options) => { /* ... */ },
351
- },
352
- signUp: async (data) => { /* ... */ },
353
- signOut: async () => { /* ... */ },
354
- getSession: async () => { /* ... */ },
355
- // ... more actions
356
- }
357
- ```
358
-
359
- ### Sessions
360
-
361
- Sessions are stored in HTTP-only cookies and contain:
362
-
363
- ```typescript
364
- interface Session {
365
- user: {
366
- id: string
367
- email: string
368
- name?: string
369
- avatar?: string
370
- emailVerified?: boolean
371
- }
372
- expiresAt: Date
373
- accessToken?: string
374
- refreshToken?: string
375
- tokenType?: string
376
- expiresIn?: number
377
- }
378
- ```
270
+ > **Note**: In Next.js 16+, `middleware.ts` has been replaced with `proxy.ts`. Mulguard uses the Proxy pattern for route protection.
379
271
 
380
272
  ---
381
273
 
382
- ## 🔐 Authentication Methods
274
+ ## 📋 API Overview
383
275
 
384
276
  ### Unified Sign-In Interface
385
277
 
386
- Mulguard provides a **unified interface** for all authentication methods, similar to auth.js:
278
+ Mulguard provides a unified, type-safe API for all authentication methods:
387
279
 
388
280
  ```typescript
389
281
  // ✅ Unified interface (recommended)
390
- await auth.signIn('credentials', { email: 'user@example.com', password: 'password123' })
282
+ await auth.signIn('credentials', { email, password })
391
283
  await auth.signIn('google')
392
- await auth.signIn('otp', { email: 'user@example.com', code: '123456' })
393
- await auth.signIn('passkey', { userId: 'user-id' })
284
+ await auth.signIn('otp', { email, code })
394
285
 
395
- // ✅ Direct methods (for backward compatibility)
396
- await auth.signIn.email({ email: 'user@example.com', password: 'password123' })
286
+ // ✅ Direct methods (also available)
287
+ await auth.signIn.email({ email, password })
397
288
  await auth.signIn.oauth('google')
398
- await auth.signIn.otp('user@example.com', '123456')
399
289
  ```
400
290
 
401
- ### Email/Password Authentication
291
+ ### Type Safety
292
+
293
+ Full TypeScript support with generics:
402
294
 
403
295
  ```typescript
404
- // Using unified interface
405
- const result = await auth.signIn('credentials', {
406
- email: 'user@example.com',
407
- password: 'password123',
408
- })
296
+ import type { User, Session } from 'mulguard'
409
297
 
410
- // Or using direct method
411
- const result = await auth.signIn.email({
412
- email: 'user@example.com',
413
- password: 'password123',
298
+ const auth = mulguard<User, Session>({
299
+ // Type-safe configuration
300
+ actions: {
301
+ signIn: {
302
+ email: async (credentials) => {
303
+ // TypeScript knows the return type
304
+ return { success: true, user, session }
305
+ },
306
+ },
307
+ },
414
308
  })
415
309
 
310
+ // Type-safe results
311
+ const result = await auth.signIn('credentials', { email, password })
416
312
  if (result.success) {
417
- console.log('Signed in:', result.user)
418
- } else {
419
- console.error('Error:', result.error, result.errorCode)
313
+ // result.user and result.session are fully typed
314
+ console.log(result.user.email)
420
315
  }
421
316
  ```
422
317
 
423
- ### OAuth Authentication
424
-
425
- ```typescript
426
- // Initiate OAuth flow (unified interface)
427
- const { url } = await auth.signIn('google')
428
- window.location.href = url
429
-
430
- // Or using direct method
431
- const { url } = await auth.signIn.oauth('google')
432
- window.location.href = url
433
-
434
- // Handle callback (in your API route)
435
- const result = await auth.oauthCallback(provider, code, state)
436
-
437
- // ✅ OAuth providers are auto-configured when you add them to providers.oauth
438
- // No need to implement oauth action manually!
439
- ```
440
-
441
- ### PassKey/WebAuthn Authentication
442
-
443
- ```typescript
444
- // Register PassKey
445
- const result = await auth.passkey.register({
446
- name: 'My iPhone',
447
- userId: 'user-id',
448
- })
449
-
450
- // Authenticate with PassKey
451
- const result = await auth.signIn.passkey({ userId: 'user-id' })
452
- ```
453
-
454
- ### Two-Factor Authentication (2FA)
455
-
456
- ```typescript
457
- // Enable 2FA
458
- const enableResult = await auth.twoFactor.enable()
459
- // Display QR code to user
460
-
461
- // Verify 2FA code
462
- const verifyResult = await auth.twoFactor.verify('123456')
463
-
464
- // Check if 2FA is enabled
465
- const isEnabled = await auth.twoFactor.isEnabled()
466
- ```
467
-
468
318
  ---
469
319
 
470
320
  ## ⚙️ Configuration
471
321
 
472
- ### Full Configuration Options
322
+ ### Complete Configuration Example
473
323
 
474
324
  ```typescript
475
325
  import { mulguard } from 'mulguard'
@@ -478,167 +328,130 @@ export const auth = mulguard({
478
328
  // Session configuration
479
329
  session: {
480
330
  cookieName: '__mulguard_session',
481
- expiresIn: 60 * 60 * 24 * 7, // 7 days in seconds
331
+ expiresIn: 60 * 60 * 24 * 7, // 7 days (in seconds)
482
332
  httpOnly: true,
483
333
  secure: process.env.NODE_ENV === 'production',
484
334
  sameSite: 'lax',
485
335
  path: '/',
486
- domain: undefined,
487
- cacheTtl: 5000, // Session cache TTL in milliseconds
488
336
  },
489
-
490
- // Required: Authentication actions
337
+
338
+ // Required: Custom authentication actions
491
339
  actions: {
492
340
  signIn: {
493
- email: async (credentials) => { /* ... */ },
494
- // Optional: oauth, passkey, otp
341
+ email: async (credentials) => {
342
+ // Your custom logic
343
+ },
344
+ },
345
+ signUp: async (data) => {
346
+ // Your custom logic
347
+ },
348
+ getSession: async () => {
349
+ // Your custom logic
350
+ },
351
+ signOut: async () => {
352
+ // Your custom logic
495
353
  },
496
- getSession: async () => { /* ... */ },
497
- signOut: async () => { /* ... */ },
498
- // Optional: signUp, resetPassword, verifyEmail, refreshSession, etc.
499
354
  },
500
-
355
+
501
356
  // Optional: OAuth providers
502
357
  providers: {
503
358
  oauth: {
504
359
  google: {
505
- clientId: '...',
506
- clientSecret: '...', // Server-side only
507
- redirectUri: '...',
360
+ clientId: process.env.GOOGLE_CLIENT_ID!,
361
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET,
362
+ redirectUri: `${process.env.NEXT_PUBLIC_URL}/api/auth/callback/google`,
508
363
  scopes: ['openid', 'profile', 'email'],
509
- name: 'Google',
364
+ pkce: true,
510
365
  },
511
366
  github: {
512
- clientId: '...',
513
- redirectUri: '...',
367
+ clientId: process.env.GITHUB_CLIENT_ID!,
368
+ clientSecret: process.env.GITHUB_CLIENT_SECRET,
369
+ redirectUri: `${process.env.NEXT_PUBLIC_URL}/api/auth/callback/github`,
514
370
  scopes: ['user:email'],
371
+ pkce: true,
515
372
  },
516
373
  },
517
374
  },
518
-
519
- // Optional: Two-Factor Authentication
520
- twoFactor: {
521
- enabled: true,
522
- },
523
-
524
- // Optional: Account Picker
525
- accountPicker: {
526
- enabled: true,
527
- maxAccounts: 3,
528
- encryptStorage: true,
529
- storageKey: '__mulguard_accounts',
530
- },
531
-
532
- // Optional: Security settings
375
+
376
+ // Optional: Security configuration
533
377
  security: {
534
378
  csrfProtection: true,
535
379
  rateLimiting: {
380
+ enabled: true,
536
381
  maxAttempts: 5,
537
382
  windowMs: 15 * 60 * 1000, // 15 minutes
538
383
  },
539
384
  },
540
-
385
+
541
386
  // Optional: Callbacks
542
387
  callbacks: {
543
388
  onSignIn: async (user, session) => {
544
- // Called after successful sign-in
389
+ // Called after successful sign in
545
390
  },
546
391
  onSignOut: async (user) => {
547
- // Called after sign-out
392
+ // Called after sign out
548
393
  },
549
- onSessionExpired: async (session) => {
550
- // Called when session expires
394
+ onOAuthUser: async (userInfo, provider) => {
395
+ // Handle OAuth user creation/update
396
+ // Return user object for session
551
397
  },
552
398
  onError: async (error, context) => {
553
- // Called on authentication errors
399
+ // Handle errors
554
400
  },
555
401
  },
556
-
557
- // Optional: Token refresh configuration
558
- tokenRefresh: {
559
- enabled: true,
560
- refreshThreshold: 300, // 5 minutes before expiration
561
- maxRetries: 0,
562
- retryDelay: 1000,
563
- rateLimit: 1, // 1 attempt per minute
564
- autoSignOutOnFailure: true,
565
- redirectToLogin: '/login',
566
- },
567
402
  })
568
403
  ```
569
404
 
570
405
  ---
571
406
 
572
- ## 🖥️ Server-Side Usage
407
+ ## 📖 Examples
573
408
 
574
- ### Get Server Session
409
+ ### OAuth Sign-In
575
410
 
576
411
  ```typescript
577
- import { getServerSession } from 'mulguard/server'
412
+ // app/login/page.tsx
413
+ 'use client'
414
+
415
+ import { useAuth } from 'mulguard/client'
578
416
  import { auth } from '@/lib/auth'
579
417
 
580
- // In Server Components
581
- const session = await getServerSession(auth)
418
+ export default function LoginPage() {
419
+ const { signIn } = useAuth(auth)
582
420
 
583
- // In API Routes
584
- export async function GET(request: Request) {
585
- const session = await getServerSession(auth)
586
- if (!session) {
587
- return new Response('Unauthorized', { status: 401 })
421
+ const handleGoogleSignIn = async () => {
422
+ const { url } = await signIn('google')
423
+ window.location.href = url
588
424
  }
589
- return Response.json({ user: session.user })
590
- }
591
- ```
592
-
593
- ### Server Actions
594
-
595
- ```typescript
596
- 'use server'
597
-
598
- import { auth } from '@/lib/auth'
599
425
 
600
- export async function signInAction(email: string, password: string) {
601
- const result = await auth.signIn.email({ email, password })
602
- return result
426
+ return (
427
+ <div>
428
+ <button onClick={handleGoogleSignIn}>
429
+ Sign in with Google
430
+ </button>
431
+ </div>
432
+ )
603
433
  }
604
434
  ```
605
435
 
606
- ### API Route Handlers
436
+ ### Protected Route with Role Check
607
437
 
608
438
  ```typescript
609
- // app/api/auth/[...mulguard]/route.ts
610
- import { createAuthHandler } from 'mulguard/handlers/route'
439
+ // app/admin/page.tsx
440
+ import { requireRole } from 'mulguard/server'
611
441
  import { auth } from '@/lib/auth'
612
442
 
613
- export const { GET, POST } = createAuthHandler(auth)
614
- ```
615
-
616
- ---
617
-
618
- ## 💻 Client-Side Usage
619
-
620
- ### React Hooks
621
-
622
- ```typescript
623
- 'use client'
624
-
625
- import { useAuth, useSession } from 'mulguard/client'
626
- import { auth } from '@/lib/auth'
627
-
628
- export function AuthComponent() {
629
- const { signIn, signOut, isLoading } = useAuth(auth)
630
- const { session, isLoading: sessionLoading } = useSession(auth)
443
+ export default async function AdminPage() {
444
+ const session = await requireRole(auth, 'admin', '/unauthorized')
631
445
 
632
- // Use hooks...
446
+ // If user doesn't have 'admin' role, redirects to /unauthorized
447
+ return <div>Admin Dashboard</div>
633
448
  }
634
449
  ```
635
450
 
636
- ### Mulguard Provider
451
+ ### Using Provider (Recommended)
637
452
 
638
453
  ```typescript
639
454
  // app/layout.tsx
640
- 'use client'
641
-
642
455
  import { MulguardProvider } from 'mulguard/client'
643
456
  import { auth } from '@/lib/auth'
644
457
 
@@ -655,339 +468,57 @@ export default function RootLayout({ children }) {
655
468
  }
656
469
  ```
657
470
 
658
- > **Note:** `AuthProvider` is still available for backward compatibility but is deprecated. Use `MulguardProvider` instead.
659
-
660
- ---
661
-
662
- ## 🎨 Components
663
-
664
- ### Account Picker
665
-
666
- ```typescript
667
- import { AccountPicker } from 'mulguard'
668
-
669
- <AccountPicker
670
- auth={auth}
671
- onSelectUser={(user) => {
672
- // Pre-fill email or handle quick login
673
- setEmail(user.email)
674
- }}
675
- onUseDifferentAccount={() => {
676
- // Show full login form
677
- }}
678
- />
679
- ```
680
-
681
- ### OAuth Button
682
-
683
- ```typescript
684
- import { OAuthButton } from 'mulguard'
685
-
686
- <OAuthButton
687
- auth={auth}
688
- provider="google"
689
- onSuccess={() => {
690
- // Handle success
691
- }}
692
- onError={(error) => {
693
- // Handle error
694
- }}
695
- >
696
- Sign in with Google
697
- </OAuthButton>
698
- ```
699
-
700
- ### Two-Factor Setup
701
-
702
- ```typescript
703
- import { TwoFactorSetup } from 'mulguard'
704
-
705
- <TwoFactorSetup
706
- auth={auth}
707
- onSuccess={() => {
708
- // 2FA enabled
709
- }}
710
- />
711
- ```
712
-
713
- ### PassKey Components
714
-
715
471
  ```typescript
716
- import { PassKeyButton, PassKeyRegister } from 'mulguard'
717
-
718
- // Register PassKey
719
- <PassKeyRegister auth={auth} />
720
-
721
- // Authenticate with PassKey
722
- <PassKeyButton auth={auth} />
723
- ```
724
-
725
- ---
726
-
727
- ## 🔒 Security
728
-
729
- Mulguard implements **comprehensive security features** with automatic input validation and sanitization:
730
-
731
- ### ✅ Built-in Security Features
732
-
733
- #### Input Validation & Sanitization
734
- - **Automatic email validation** - Validates and sanitizes email addresses
735
- - **Password length checks** - Prevents DoS attacks with extremely long passwords
736
- - **Provider validation** - Sanitizes OAuth provider strings to prevent injection
737
- - **OTP code validation** - Validates OTP code format before processing
738
- - **XSS Prevention** - Automatic HTML escaping and input sanitization
739
-
740
- #### CSRF Protection
741
- - Token-based CSRF protection for OAuth flows
742
- - State parameter validation with constant-time comparison
743
- - Secure state storage (pluggable for production - Redis, Database, etc.)
744
-
745
- #### Error Handling
746
- - **Generic error messages** - Prevents information disclosure
747
- - **Error codes** - Programmatic error handling without exposing details
748
- - **Security logging** - Logs authentication events (with sensitive data masked)
749
-
750
- #### Secure Cookies
751
- - HttpOnly cookies (prevents JavaScript access)
752
- - Secure flag in production (HTTPS only)
753
- - SameSite attribute (CSRF protection)
754
- - Configurable expiration
755
-
756
- #### Rate Limiting
757
- - Configurable rate limiting
758
- - Client-side tracking
759
- - Automatic throttling
760
- - Circuit breaker pattern for token refresh
761
-
762
- ### Security Best Practices
472
+ // app/profile/page.tsx
473
+ 'use client'
763
474
 
764
- ```typescript
765
- // ✅ Good: Generic error messages
766
- return {
767
- success: false,
768
- error: 'Invalid credentials',
769
- errorCode: 'INVALID_CREDENTIALS'
770
- }
475
+ import { useAuthFromContext } from 'mulguard/client'
771
476
 
772
- // Bad: Information disclosure
773
- return {
774
- success: false,
775
- error: 'User not found with email: user@example.com'
477
+ export default function ProfilePage() {
478
+ const { session, signOut } = useAuthFromContext()
479
+
480
+ // No need to pass auth instance
481
+ return <div>...</div>
776
482
  }
777
483
  ```
778
484
 
779
- ### Security Logging
780
-
781
- All authentication events are automatically logged with sensitive data masked:
782
-
783
- ```typescript
784
- // Logs show: "Sign in successful" with email: "use***"
785
- // Never logs full email addresses or passwords
786
- ```
787
-
788
- For detailed security documentation, see the [Security Guide](./docs/SECURITY.md) and [Complete Guide](./GUIDE.md).
789
-
790
485
  ---
791
486
 
792
- ## 🔌 Backend Integration
487
+ ## 🏗️ Architecture
793
488
 
794
- Mulguard is designed to work with your existing backend. You implement the authentication logic through **actions**, which can:
489
+ Mulguard follows a **modular, backend-first architecture**:
795
490
 
796
- - Connect to your database
797
- - Call your API endpoints
798
- - Use your existing authentication services
799
- - Integrate with third-party services
491
+ - **Core Layer** - Framework-agnostic authentication logic
492
+ - **Next.js Integration** - Server Actions, Server Components, Proxy middleware
493
+ - **Plugin System** - Extensible features (MFA, Account Picker, etc.)
800
494
 
801
- ### Example: Database Integration
802
-
803
- ```typescript
804
- import { mulguard } from 'mulguard'
805
- import { db } from '@/lib/db'
806
- import { comparePassword, hashPassword } from '@/lib/password'
807
-
808
- export const auth = mulguard({
809
- actions: {
810
- signIn: {
811
- email: async ({ email, password }) => {
812
- const user = await db.user.findUnique({ where: { email } })
813
-
814
- if (!user || !await comparePassword(password, user.password)) {
815
- return { success: false, error: 'Invalid credentials' }
816
- }
817
-
818
- return {
819
- success: true,
820
- user: {
821
- id: user.id,
822
- email: user.email,
823
- name: user.name,
824
- },
825
- session: {
826
- user: { /* ... */ },
827
- expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
828
- },
829
- }
830
- },
831
- },
832
- // ... more actions
833
- },
834
- })
835
- ```
836
-
837
- ### Example: API Integration
838
-
839
- ```typescript
840
- import { mulguard } from 'mulguard'
841
-
842
- export const auth = mulguard({
843
- actions: {
844
- signIn: {
845
- email: async ({ email, password }) => {
846
- const response = await fetch('https://api.example.com/auth/signin', {
847
- method: 'POST',
848
- headers: { 'Content-Type': 'application/json' },
849
- body: JSON.stringify({ email, password }),
850
- })
851
-
852
- if (!response.ok) {
853
- return { success: false, error: 'Authentication failed' }
854
- }
855
-
856
- const data = await response.json()
857
- return {
858
- success: true,
859
- user: data.user,
860
- session: data.session,
861
- }
862
- },
863
- },
864
- },
865
- })
866
- ```
495
+ The library is designed to be:
496
+ - **Framework Agnostic** - Core logic works with any framework
497
+ - **Backend-First** - You implement your own database logic
498
+ - **Type-Safe** - Full TypeScript support throughout
499
+ - **Secure by Default** - Security features enabled by default
867
500
 
868
501
  ---
869
502
 
870
- ## 🚀 Advanced Features
871
-
872
- ### Token Refresh
873
-
874
- Automatic token refresh is built-in when you provide a `refreshSession` action:
875
-
876
- ```typescript
877
- actions: {
878
- refreshSession: async () => {
879
- // Your token refresh logic
880
- const newSession = await yourApi.refreshToken()
881
- return newSession
882
- },
883
- }
884
- ```
885
-
886
- ### Custom Callbacks
887
-
888
- ```typescript
889
- callbacks: {
890
- onSignIn: async (user, session) => {
891
- // Track sign-in analytics
892
- await analytics.track('user_signed_in', { userId: user.id })
893
- },
894
- onSignOut: async (user) => {
895
- // Cleanup logic
896
- await cleanupUserSession(user.id)
897
- },
898
- onError: async (error, context) => {
899
- // Error logging
900
- console.error(`Auth error in ${context}:`, error)
901
- },
902
- }
903
- ```
904
-
905
- ### OAuth State Store
906
-
907
- For production, use a persistent OAuth state store:
908
-
909
- ```typescript
910
- import { createRedisOAuthStateStore } from 'mulguard'
911
-
912
- const auth = mulguard({
913
- oauthStateStore: createRedisOAuthStateStore(redisClient),
914
- // ... rest of config
915
- })
916
- ```
917
-
918
- ---
919
-
920
- ## 📚 API Reference
921
-
922
- ### Core Functions
923
-
924
- #### `mulguard(config: MulguardConfig): MulguardInstance`
925
-
926
- Creates a new Mulguard authentication instance.
927
-
928
- #### `getServerSession(auth: MulguardInstance): Promise<Session | null>`
929
-
930
- Gets the current session on the server.
931
-
932
- ### Client Hooks
933
-
934
- #### `useAuth(auth: MulguardInstance)`
935
-
936
- Returns authentication methods and state.
937
-
938
- ```typescript
939
- const { signIn, signOut, isLoading } = useAuth(auth)
940
- ```
941
-
942
- #### `useSession(auth: MulguardInstance)`
943
-
944
- Returns the current session.
945
-
946
- ```typescript
947
- const { session, isLoading } = useSession(auth)
948
- ```
949
-
950
- ### Instance Methods
951
-
952
- #### `auth.getSession(): Promise<Session | null>`
953
-
954
- Gets the current session.
955
-
956
- #### `auth.signIn.email(credentials): Promise<AuthResult>`
957
-
958
- Signs in with email and password.
959
-
960
- #### `auth.signIn.oauth(provider): Promise<{ url: string; state: string }>`
961
-
962
- Initiates OAuth flow.
963
-
964
- #### `auth.signOut(): Promise<{ success: boolean }>`
503
+ ## 🔒 Security
965
504
 
966
- Signs out the current user.
505
+ Mulguard implements **comprehensive security features**:
967
506
 
968
- For complete API documentation, see the [API Reference](./docs/API_REFERENCE.md).
507
+ - **HttpOnly Cookies** - Prevents XSS attacks
508
+ - ✅ **Secure Flag** - HTTPS-only cookies in production
509
+ - ✅ **SameSite=Strict** - CSRF protection
510
+ - ✅ **PKCE for OAuth** - Prevents code interception attacks
511
+ - ✅ **Rate Limiting** - Prevents brute force attacks
512
+ - ✅ **Input Validation** - Prevents injection attacks
513
+ - ✅ **XSS Prevention** - Automatic XSS protection
514
+ - ✅ **Generic Error Messages** - Prevents information disclosure
969
515
 
970
516
  ---
971
517
 
972
- ## 📖 Examples & Guides
973
-
974
- ### Complete Guide
975
-
976
- 📚 **[Complete Usage Guide](./GUIDE.md)** - Comprehensive guide with:
977
- - Best practices for writing `auth.ts`
978
- - Production-ready examples
979
- - Security recommendations
980
- - Backend integration patterns
981
- - Advanced usage examples
518
+ ## 📚 Documentation
982
519
 
983
- ### Code Examples
984
-
985
- - **[Basic Email Authentication](./src/examples/email-auth.ts)** - Simple email/password setup
986
- - **[OAuth Authentication](./src/examples/oauth-auth.ts)** - Google, GitHub, etc.
987
- - **[PassKey Authentication](./src/examples/passkey-auth.ts)** - WebAuthn/PassKey setup
988
- - **[Two-Factor Authentication](./src/examples/two-factor-auth.ts)** - 2FA/TOTP implementation
989
- - **[Middleware Integration](./src/examples/middleware-example.ts)** - Next.js middleware
990
- - **[Server Components](./src/examples/server-component-example.tsx)** - Server-side usage
520
+ - **[GUIDE.md](./GUIDE.md)** - Complete usage guide with examples
521
+ - **[API Reference](./docs/API_DESIGN.md)** - Full API documentation
991
522
 
992
523
  ---
993
524
 
@@ -1019,29 +550,13 @@ Contributions are welcome! Please read our contributing guidelines before submit
1019
550
  4. Push to the branch (`git push origin feature/amazing-feature`)
1020
551
  5. Open a Pull Request
1021
552
 
1022
- ### Development Setup
1023
-
1024
- ```bash
1025
- # Clone the repository
1026
- git clone https://github.com/mulverse/mulguard.git
1027
-
1028
- # Install dependencies
1029
- npm install
1030
-
1031
- # Run development build
1032
- npm run dev
1033
-
1034
- # Run tests
1035
- npm test
1036
- ```
1037
-
1038
553
  ---
1039
554
 
1040
555
  ## 📝 License
1041
556
 
1042
557
  This project is licensed under the **MUV (Mulverse M.U.V General Public License)**.
1043
558
 
1044
- Copyright (C) 2022 Mulverse Inc.
559
+ Copyright (C) 2024 Mulverse Inc.
1045
560
 
1046
561
  See the [LICENSE](./LICENSE) file for details.
1047
562
 
@@ -1049,22 +564,10 @@ See the [LICENSE](./LICENSE) file for details.
1049
564
 
1050
565
  ## 💬 Support
1051
566
 
1052
- - **📖 Complete Guide**: [GUIDE.md](./GUIDE.md) - Comprehensive usage guide with best practices
1053
- - **📚 Documentation**: Check the [docs](./docs) directory for detailed guides
567
+ - **📖 Documentation**: Check the [GUIDE.md](./GUIDE.md) for detailed usage examples
1054
568
  - **🐛 Issues**: [GitHub Issues](https://github.com/mulverse/mulguard/issues)
1055
569
  - **💬 Discussions**: [GitHub Discussions](https://github.com/mulverse/mulguard/discussions)
1056
570
 
1057
- ## 🎯 Key Features & Improvements
1058
-
1059
- ### ✨ Latest Updates
1060
-
1061
- - **✅ Unified Sign-In Interface** - Use `auth.signIn('credentials', {...})` or `auth.signIn.email({...})`
1062
- - **✅ Automatic Input Validation** - Built-in email, password, and provider validation
1063
- - **✅ Enhanced Security** - Generic error messages, security logging, XSS/Injection prevention
1064
- - **✅ Single Unified Logic** - All sign-in methods use the same core logic
1065
- - **✅ Type-Safe** - Full TypeScript support with proper typing
1066
- - **✅ Production Ready** - Best practices built-in by default
1067
-
1068
571
  ---
1069
572
 
1070
573
  ## 🌟 About Mulverse
@@ -1076,3 +579,4 @@ Visit [mulverse.com](https://mulverse.com) to learn more about our other project
1076
579
  ---
1077
580
 
1078
581
  **Made with ❤️ by the Mulverse Team**
582
+