authula 0.5.4 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="./project-logo.png" width="200" />
2
+ <img src="./project-logo.png" width="200" />
3
3
  </p>
4
4
 
5
5
  <p align="center">
@@ -14,15 +14,39 @@ This Node.js SDK provides seamless integration with an Authula server for both c
14
14
 
15
15
  ---
16
16
 
17
+ ## 🚨 Breaking Changes
18
+
19
+ Starting with v0.6.x, the SDK transitions to an automated, schema-driven architecture powered by Orval. Code generation is now tied 1-to-1 with the Authula backend OpenAPI specification, ensuring absolute parity and enhanced reliability.
20
+
21
+ This architectural shift introduces several breaking changes to the SDK footprint:
22
+
23
+ 1. Relocation of Core Methods
24
+
25
+ What changed: Core utility methods have been consolidated.
26
+
27
+ Impact: Any foundational system methods have moved directly into the Core Plugin namespace, as the underlying Authula engine now explicitly groups these operations under the core OpenAPI tag.
28
+
29
+ 2. Standardized Method Signatures via Orval
30
+
31
+ What changed: Every Authula plugin now exposes its feature set via auto-generated endpoints.
32
+
33
+ Impact: While plugins remain organized under their original top-level objects, individual method names, parameters, and payloads may have changed to match the strict schema specification.
34
+
35
+ 3. Unified Server & Client Support
36
+
37
+ The Benefit: Each plugin now natively exports decoupled, standalone methods optimized for server-side execution, alongside fully typed TanStack Query hooks dedicated to client-side web applications.
38
+
39
+ Why this matters: Moving forward, this SDK will perfectly mirror upstream backend updates with zero drift, drastically reducing runtime bugs and offering complete type safety across your entire stack.
40
+
17
41
  ## Features
18
42
 
19
43
  - **Framework Agnostic**: Works with Next.js/React, Vue.js and more
20
44
  - **Full TypeScript Support**: Complete TypeScript definitions with strict typing
21
- - **SSR Safe**: Supports proper cookie handling for SSR apps
22
45
  - **CSRF Protection**: Automatic CSRF token handling for mutating requests
23
46
  - **Multiple Auth Methods**: Email/password, OAuth2, JWT-based authentication
24
47
  - **Plugin Architecture**: Extensible plugin system for custom authentication flows
25
48
  - **Automatic Token Refresh**: Built-in bearer token refresh mechanism
49
+ - **Built-in support for Zod and Tanstack Query**: provides types and zod schemas out of the box along with tanstack query code for all available methods.
26
50
 
27
51
  ## Installation
28
52
 
@@ -38,742 +62,91 @@ pnpm add authula
38
62
 
39
63
  ### Basic Setup
40
64
 
41
- ```typescript
42
- import { createClient } from "authula";
43
- import { EmailPasswordPlugin } from "authula/plugins";
44
-
45
- // Create a client instance
46
- const authulaClient = createClient({
47
- // Your Authula server URL
48
- url: "http://localhost:8080/auth",
49
- plugins: [new EmailPasswordPlugin()],
50
- });
51
-
52
- // Now you can use the client to perform authentication operations
53
- ```
65
+ `Client instance`:
54
66
 
55
- ### Using with Cookies (SSR Compatible)
56
-
57
- For server-side rendering or applications that need to handle cookies properly:
67
+ Use with SPA (Vite etc.)
58
68
 
59
69
  ```typescript
60
- import { cookies } from "next/headers";
61
-
62
70
  import { createClient } from "authula";
63
- import { EmailPasswordPlugin, CSRFPlugin } from "authula/plugins";
64
-
65
- const authulaClient = createClient({
66
- url: "http://localhost:8080/auth",
67
- cookies: cookies, // Provide cookie store for SSR
68
- plugins: [
69
- new EmailPasswordPlugin(),
70
- new CSRFPlugin({
71
- cookieName: "authula_csrf_token",
72
- headerName: "X-AUTHULA-CSRF-TOKEN",
73
- }),
74
- ],
75
- });
76
- ```
77
-
78
- ## Core Client Methods
79
-
80
- The client provides built-in methods for essential authentication operations:
81
-
82
- ### Get Current User
83
-
84
- Retrieve information about the currently authenticated user:
85
-
86
- ```typescript
87
- const { user, session } = await authulaClient.getMe();
88
-
89
- console.log(user.email);
90
- console.log(session.id);
91
- ```
92
-
93
- ### Sign Out
94
-
95
- Sign out the current user or all sessions:
96
-
97
- ```typescript
98
- // Sign out current session
99
- await authulaClient.signOut({});
100
-
101
- // Sign out all sessions
102
- await authulaClient.signOut({
103
- signOutAll: true,
104
- });
105
-
106
- // Sign out a specific session
107
- await authulaClient.signOut({
108
- sessionId: "session-id",
109
- });
110
- ```
111
-
112
- ### Get Plugin Instance
113
-
114
- Access a plugin instance programmatically:
115
-
116
- ```typescript
117
- const emailPasswordPlugin = authulaClient.getPlugin("emailPassword");
118
-
119
- // Use the plugin
120
- if (emailPasswordPlugin) {
121
- // Plugin methods are now available
122
- }
123
- ```
124
-
125
- ## Available Plugins
126
-
127
- ### Access Control Plugin
128
-
129
- Provides role-based access control (RBAC) management for users, including roles, permissions, and their assignments.
130
-
131
- ```typescript
132
- import { AccessControlPlugin } from "authula/plugins";
133
-
134
- const authulaClient = createClient({
135
- url: "http://localhost:8080/auth",
136
- plugins: [new AccessControlPlugin()],
137
- });
138
- ```
139
-
140
- #### Role Management
141
-
142
- ```typescript
143
- // Create a new role
144
- const createdRole = await authulaClient.accessControl.createRole({
145
- name: "Admin",
146
- description: "Administrator role",
147
- isSystem: false,
148
- });
149
-
150
- // Get all roles
151
- const allRoles = await authulaClient.accessControl.getAllRoles();
152
-
153
- // Look up a role by name
154
- const roleByName = await authulaClient.accessControl.getRoleByName("Admin");
155
-
156
- // Get a specific role
157
- const roleDetails = await authulaClient.accessControl.getRoleById("role-id");
158
-
159
- // Update a role
160
- const updatedRole = await authulaClient.accessControl.updateRole("role-id", {
161
- name: "Updated name",
162
- description: "Updated description",
163
- });
164
-
165
- // Delete a role
166
- const deleteRoleResult =
167
- await authulaClient.accessControl.deleteRole("role-id");
168
- ```
169
-
170
- #### Permission Management
171
-
172
- ```typescript
173
- // Create a new permission
174
- const createdPermission = await authulaClient.accessControl.createPermission({
175
- key: "users.create",
176
- description: "Create new users",
177
- isSystem: false,
178
- });
179
-
180
- // Get all permissions
181
- const allPermissions = await authulaClient.accessControl.getAllPermissions();
182
-
183
- // Get a specific permission
184
- const permission =
185
- await authulaClient.accessControl.getPermissionById("permission-id");
186
-
187
- // Update a permission
188
- const updatedPermission = await authulaClient.accessControl.updatePermission(
189
- "permission-id",
190
- {
191
- description: "Updated permission description",
192
- },
193
- );
194
-
195
- // Delete a permission
196
- const deletePermissionResult =
197
- await authulaClient.accessControl.deletePermission("permission-id");
198
- ```
199
-
200
- #### Role-Permission Management
201
-
202
- ```typescript
203
- // Add a permission to a role
204
- const addPermissionResult = await authulaClient.accessControl.addRolePermission(
205
- "role-id",
206
- {
207
- permissionId: "permission-id",
208
- },
209
- );
210
-
211
- // Get all permissions for a role
212
- const rolePermissions =
213
- await authulaClient.accessControl.getRolePermissions("role-id");
214
-
215
- // Replace all permissions for a role
216
- const replaceRolePermissionsResult =
217
- await authulaClient.accessControl.replaceRolePermissions("role-id", {
218
- permissionIds: ["permission-id-1", "permission-id-2", "permission-id-3"],
219
- });
220
-
221
- // Remove a permission from a role
222
- const removeRolePermissionResult =
223
- await authulaClient.accessControl.removeRolePermission(
224
- "role-id",
225
- "permission-id",
226
- );
227
- ```
228
-
229
- #### User Role Management
230
-
231
- ```typescript
232
- // Get all roles assigned to a user
233
- const userRoles = await authulaClient.accessControl.getUserRoles("user-id");
234
-
235
- // Assign a role to a user
236
- const assignUserRoleResult = await authulaClient.accessControl.assignUserRole(
237
- "user-id",
238
- {
239
- roleId: "role-id",
240
- expiresAt: new Date("2025-12-31"), // Optional: role expiration date
241
- },
242
- );
243
-
244
- // Replace all roles for a user
245
- const replaceUserRolesResult =
246
- await authulaClient.accessControl.replaceUserRoles("user-id", {
247
- roleIds: ["role-id-1", "role-id-2"],
248
- });
249
-
250
- // Remove a role from a user
251
- const removeUserRoleResult = await authulaClient.accessControl.removeUserRole(
252
- "user-id",
253
- "role-id",
254
- );
255
- ```
256
-
257
- #### User Permission Management
258
-
259
- ```typescript
260
- // Get all effective permissions for a user (from all assigned roles)
261
- const effectivePermissions =
262
- await authulaClient.accessControl.getUserPermissions("user-id");
263
-
264
- // Check whether the user has all requested permissions
265
- const permissionCheck = await authulaClient.accessControl.checkUserPermissions(
266
- "user-id",
267
- {
268
- permissionKeys: ["users.create", "users.update"],
269
- },
270
- );
271
- ```
272
-
273
- ---
274
-
275
- ### Organizations Plugin
276
-
277
- Provides the ability to manage organizations, members, teams and invitations.
278
-
279
- ```typescript
280
- import { OrganizationsPlugin } from "authula/plugins";
281
-
282
- const authulaClient = createClient({
283
- url: "http://localhost:8080/auth",
284
- plugins: [new OrganizationsPlugin()],
285
- });
286
-
287
- // Organizations
288
-
289
- await authulaClient.organizations.createOrganization({
290
- name: "Acme Inc.",
291
- slug: "acme-inc",
292
- logo: "https://example.com/logo.svg",
293
- metadata: { key: "value" },
294
- });
295
-
296
- await authulaClient.organizations.getAllOrganizations();
297
-
298
- await authulaClient.organizations.getOrganizationById("organization-id");
299
-
300
- await authulaClient.organizations.updateOrganization("organization-id", {
301
- name: "Updated name",
302
- });
303
-
304
- await authulaClient.organizations.deleteOrganization("organization-id");
305
-
306
- // Invitations
307
-
308
- await authulaClient.organizations.createOrganizationInvitation(
309
- "organization-id",
310
- {
311
- email: "user@example.com",
312
- role: "member",
313
- redirectUrl: "https://example.com/invite",
314
- },
315
- );
316
-
317
- await authulaClient.organizations.getAllOrganizationInvitations(
318
- "organization-id",
319
- );
320
-
321
- await authulaClient.organizations.getOrganizationInvitation(
322
- "organization-id",
323
- "invitation-id",
324
- );
325
-
326
- await authulaClient.organizations.revokeOrganizationInvitation(
327
- "organization-id",
328
- "invitation-id",
329
- );
330
-
331
- await authulaClient.organizations.acceptOrganizationInvitation(
332
- "organization-id",
333
- "invitation-id",
334
- {
335
- redirectUrl: "https://example.com/accepted",
336
- },
337
- );
338
-
339
- await authulaClient.organizations.rejectOrganizationInvitation(
340
- "organization-id",
341
- "invitation-id",
342
- );
343
-
344
- // Members
345
-
346
- await authulaClient.organizations.addOrganizationMember("organization-id", {
347
- userId: "user-id",
348
- role: "owner",
349
- });
350
-
351
- await authulaClient.organizations.getAllOrganizationMembers("organization-id");
352
-
353
- await authulaClient.organizations.getOrganizationMember(
354
- "organization-id",
355
- "member-id",
356
- );
357
-
358
- await authulaClient.organizations.updateOrganizationMember(
359
- "organization-id",
360
- "member-id",
361
- {
362
- role: "owner",
363
- },
364
- );
365
-
366
- await authulaClient.organizations.deleteOrganizationMember(
367
- "organization-id",
368
- "member-id",
369
- );
370
-
371
- // Teams
71
+ import { CorePlugin, EmailPasswordPlugin } from "authula/plugins";
372
72
 
373
- await authulaClient.organizations.createOrganizationTeam("organization-id", {
374
- name: "Platform",
375
- slug: "platform",
376
- description: "Platform team",
377
- metadata: { key: "value" },
378
- });
379
-
380
- await authulaClient.organizations.getAllOrganizationTeams("organization-id");
381
-
382
- await authulaClient.organizations.updateOrganizationTeam(
383
- "organization-id",
384
- "team-id",
385
- {
386
- name: "Platform",
387
- slug: "platform",
388
- description: "Updated team description",
389
- metadata: { key: "value" },
390
- },
391
- );
392
- await authulaClient.organizations.deleteOrganizationTeam(
393
- "organization-id",
394
- "team-id",
395
- );
396
-
397
- // Team Members
398
-
399
- await authulaClient.organizations.addOrganizationTeamMember(
400
- "organization-id",
401
- "team-id",
402
- {
403
- memberId: "member-id",
404
- },
405
- );
406
- await authulaClient.organizations.getAllOrganizationTeamMembers(
407
- "organization-id",
408
- "team-id",
409
- );
410
- await authulaClient.organizations.getOrganizationTeamMember(
411
- "organization-id",
412
- "team-id",
413
- "member-id",
414
- );
415
- await authulaClient.organizations.deleteOrganizationTeamMember(
416
- "organization-id",
417
- "team-id",
418
- "member-id",
419
- );
420
- ```
421
-
422
- ---
423
-
424
- ### Admin Plugin
425
-
426
- Provides the ability to manage users, accounts, sessions, and impersonations.
427
-
428
- ```typescript
429
- import { AdminPlugin } from "authula/plugins";
430
-
431
- const authulaClient = createClient({
432
- url: "http://localhost:8080/auth",
433
- plugins: [new AdminPlugin()],
434
- });
435
- ```
436
-
437
- #### User Management
438
-
439
- ```typescript
440
- await authulaClient.admin.createUser({
441
- name: "John Doe",
442
- email: "user@example.com",
443
- // other fields...
444
- });
445
-
446
- // Get all users with pagination
447
- const users = await authulaClient.admin.getAllUsers(100);
448
-
449
- // Get a specific user by ID
450
- const user = await authulaClient.admin.getUserById("user-id");
451
-
452
- // Update user information
453
- await authulaClient.admin.updateUser("user-id", { name: "Jane" });
454
-
455
- // Delete a user
456
- await authulaClient.admin.deleteUser("user-id");
457
- ```
458
-
459
- #### Account Management
460
-
461
- ```typescript
462
- // Create a new account for a user
463
- await authulaClient.admin.createAccount("user-id", {
464
- /* account data */
465
- });
466
-
467
- // Get all accounts for a user
468
- await authulaClient.admin.getUserAccounts("user-id");
469
-
470
- // Get a specific account by ID
471
- await authulaClient.admin.getAccountById("account-id");
472
-
473
- // Update account information
474
- await authulaClient.admin.updateAccount("account-id", {
475
- /* data */
476
- });
477
-
478
- // Delete an account
479
- await authulaClient.admin.deleteAccount("account-id");
480
- ```
481
-
482
- #### User State Management
483
-
484
- ```typescript
485
- // Get user state
486
- await authulaClient.admin.getUserState("user-id");
487
-
488
- // Create or update user state
489
- await authulaClient.admin.createUserState("user-id", {
490
- /* state data */
491
- });
492
-
493
- // Update user state
494
- await authulaClient.admin.updateUserState("user-id", {
495
- /* state data */
496
- });
497
-
498
- // Delete user state
499
- await authulaClient.admin.deleteUserState("user-id");
500
-
501
- // Get all banned user states
502
- await authulaClient.admin.getBannedUserStates();
503
-
504
- // Ban a user
505
- await authulaClient.admin.banUser("user-id", { reason: "reason..." });
506
-
507
- // Unban a user
508
- await authulaClient.admin.unbanUser("user-id");
509
-
510
- // Get all active sessions for a user
511
- await authulaClient.admin.getUserAdminSessions("user-id");
512
- ```
513
-
514
- #### Session State Management
515
-
516
- ```typescript
517
- // Get session state
518
- await authulaClient.admin.getSessionState("session-id");
519
-
520
- // Create or update session state
521
- await authulaClient.admin.createSessionState("session-id", {
522
- /* data */
523
- });
524
-
525
- // Update session state
526
- await authulaClient.admin.updateSessionState("session-id", {
527
- /* data */
73
+ const authulaBrowserClient = createClient({
74
+ // Your Authula server URL
75
+ url: "http://localhost:8080/api/auth",
76
+ plugins: [new CorePlugin(), new EmailPasswordPlugin()],
528
77
  });
529
78
 
530
- // Delete session state
531
- await authulaClient.admin.deleteSessionState("session-id");
532
-
533
- // Get all revoked session states
534
- await authulaClient.admin.getRevokedSessionStates();
535
-
536
- // Revoke a session
537
- await authulaClient.admin.revokeSession("session-id", { reason: "reason..." });
538
- ```
539
-
540
- #### Impersonations
79
+ // Direct method call
80
+ const response = await authulaBrowserClient.core.getMe();
541
81
 
542
- ```typescript
543
- // Get all active impersonations
544
- await authulaClient.admin.getAllImpersonations();
545
-
546
- // Get a specific impersonation by ID
547
- await authulaClient.admin.getImpersonationById("impersonation-id");
548
-
549
- // Start impersonating a user
550
- await authulaClient.admin.startImpersonation({ user_id: "user-id" /* data */ });
551
-
552
- // Stop impersonation
553
- await authulaClient.admin.stopImpersonation("impersonation-id");
82
+ // Tanstack Query
83
+ const { data, error, isLoading, isError } =
84
+ await authulaBrowserClient.core.useGetMe();
554
85
  ```
555
86
 
556
- ---
557
-
558
- ### Email Password Plugin
87
+ `Server instance`:
559
88
 
560
- Handles traditional email/password authentication flows.
89
+ Use with SSR frameworks e.g. Next.js/Tanstack Start etc.
561
90
 
562
91
  ```typescript
563
- import { EmailPasswordPlugin } from "authula/plugins";
564
-
565
- const authulaClient = createClient({
566
- url: "http://localhost:8080/auth",
567
- plugins: [new EmailPasswordPlugin()],
568
- });
569
-
570
- // Sign up
571
- await authulaClient.emailPassword.signUp({
572
- name: "John Doe",
573
- email: "john@example.com",
574
- password: "securePassword123",
575
- callbackUrl: "http://localhost:3000/callback", // Optional callback URL
576
- });
577
-
578
- // Sign in
579
- const response = await authulaClient.emailPassword.signIn({
580
- email: "john@example.com",
581
- password: "securePassword123",
582
- callbackUrl: "http://localhost:3000/callback", // Optional callback URL
583
- });
92
+ import { cookies } from "next/headers";
584
93
 
585
- // Send email verification
586
- await authulaClient.emailPassword.sendEmailVerification({
587
- callbackUrl: "http://localhost:3000/callback", // Optional callback URL
588
- });
94
+ import { createClient } from "authula";
95
+ import { CorePlugin, EmailPasswordPlugin } from "authula/plugins";
589
96
 
590
- // Request password reset
591
- await authulaClient.emailPassword.requestPasswordReset({
592
- email: "john@example.com",
593
- callbackUrl: "http://localhost:3000/callback", // Optional callback URL
97
+ const authulaServerClient = createClient({
98
+ // Your Authula server URL
99
+ url: "http://localhost:8080/api/auth",
100
+ plugins: [new CorePlugin(), new EmailPasswordPlugin()],
101
+ // For frameworks other than Next.js, you may need to implement this cookies object manually by implementing the interface.
102
+ cookies: cookies,
594
103
  });
595
104
 
596
- // Change password
597
- await authulaClient.emailPassword.changePassword({
598
- token: "reset-token",
599
- password: "newSecurePassword123",
600
- });
105
+ // Now you can use the client...
601
106
 
602
- // Request email change
603
- await authulaClient.emailPassword.requestEmailChange({
604
- email: "john.doe@example.com",
605
- callbackUrl: "http://localhost:3000/callback", // Optional callback URL
606
- });
107
+ const response = await authulaServerClient.core.getMe();
607
108
  ```
608
109
 
609
- ---
610
-
611
- ### OAuth2 Plugin
110
+ ### Using with Cookies (SSR Compatible)
612
111
 
613
- Handles OAuth2 authentication with popular providers.
112
+ For server-side rendering or applications that need to handle cookies properly:
614
113
 
615
114
  ```typescript
616
- import { OAuth2Plugin } from "authula/plugins";
617
-
618
- const authulaClient = createClient({
619
- url: "http://localhost:8080/auth",
620
- plugins: [new OAuth2Plugin()],
621
- });
622
-
623
- // Redirect user to OAuth2 provider
624
- const response = await authulaClient.oauth2.signIn({
625
- provider: "google", // or "github", "discord"
626
- redirect_to: "http://localhost:3000/callback",
627
- });
628
-
629
- // Redirect user to the authUrl
630
- window.location.href = response.auth_url;
631
- ```
632
-
633
- ---
634
-
635
- ### CSRF Plugin
636
-
637
- Provides automatic CSRF protection for mutating requests.
115
+ import { cookies } from "next/headers";
638
116
 
639
- ```typescript
640
- import { CSRFPlugin } from "authula/plugins";
117
+ import { createClient } from "authula";
118
+ import { CorePlugin, EmailPasswordPlugin, CSRFPlugin } from "authula/plugins";
641
119
 
642
120
  const authulaClient = createClient({
643
- url: "http://localhost:8080/auth",
644
- cookies: ..., // Provide cookie store for SSR if needed, else omit for SPA/Mobile apps
121
+ url: "http://localhost:8080/api/auth",
645
122
  plugins: [
123
+ new CorePlugin(),
124
+ new EmailPasswordPlugin(),
646
125
  new CSRFPlugin({
647
- cookieName: "csrf_token", // Name of the CSRF token cookie
648
- headerName: "X-CSRF-TOKEN" // Header name to send the token
649
- })
650
- ]
651
- });
652
-
653
- // CSRF tokens will be automatically added to mutating requests (POST, PUT, PATCH, DELETE)
654
- ```
655
-
656
- ---
657
-
658
- ### JWT Plugin
659
-
660
- Handles JWT token operations including refresh.
661
-
662
- ```typescript
663
- import { JWTPlugin } from "authula/plugins";
664
-
665
- const authulaClient = createClient({
666
- url: "http://localhost:8080/auth",
667
- plugins: [new JWTPlugin()],
668
- });
669
-
670
- // Refresh JWT tokens
671
- const tokens = await authulaClient.jwt.refreshToken({
672
- refresh_token: "your-refresh-token",
673
- });
674
-
675
- // Get JWKS keys
676
- const jwksKeys = await authulaClient.jwt.getJWKSKeys();
677
- ```
678
-
679
- ---
680
-
681
- ### Bearer Plugin
682
-
683
- Provides automatic bearer token handling and refresh.
684
-
685
- ```typescript
686
- import { BearerPlugin, JWTPlugin } from "authula/plugins";
687
-
688
- const authulaClient = createClient({
689
- url: "http://localhost:8080/auth",
690
- plugins: [
691
- new JWTPlugin(),
692
- new BearerPlugin({
693
- headerName: "Authorization", // Can be omitted as default is Authorization
126
+ cookieName: "authula_csrf_token",
127
+ headerName: "X-AUTHULA-CSRF-TOKEN",
694
128
  }),
695
129
  ],
130
+ cookies,
696
131
  });
697
-
698
- // The Bearer plugin will automatically:
699
- // 1. Add Authorization: Bearer <token> header to requests
700
- // 2. Handle token refresh when receiving 401 responses
701
- // 3. Store tokens in localStorage (access_token and refresh_token)
702
132
  ```
703
133
 
704
- ---
705
-
706
- ### Magic Link Plugin
707
-
708
- Provides flows for passwordless authentication.
709
-
710
- ```typescript
711
- import { MagicLinkPlugin } from "authula/plugins";
712
-
713
- const authulaClient = createClient({
714
- url: "http://localhost:8080/auth",
715
- plugins: [new MagicLinkPlugin()],
716
- });
717
-
718
- // Send magic link via email
719
- await authulaClient.magicLink.signIn({
720
- email: "john.doe@example.com",
721
- name: "John Doe", // Optional name
722
- callbackUrl: "http://localhost:3000/callback", // Optional callback URL
723
- });
724
-
725
- // Verify magic link token
726
- await authulaClient.magicLink.verify({
727
- token: "magic-link-token",
728
- callbackUrl: "http://localhost:3000/callback", // Optional callback URL
729
- });
730
-
731
- // Exchange token from verify endpoint for session
732
- await authulaClient.magicLink.exchange({
733
- token: "magic-link-token",
734
- });
735
- ```
736
-
737
- ---
738
-
739
- ### TOTP Plugin
740
-
741
- Provides time-based one-time password (TOTP) two-factor authentication flows.
742
-
743
- ```typescript
744
- import { TOTPPlugin } from "authula/plugins";
745
-
746
- const authulaClient = createClient({
747
- url: "http://localhost:8080/auth",
748
- plugins: [new TOTPPlugin()],
749
- });
750
-
751
- // Enable TOTP for the current user
752
- await authulaClient.totp.enable();
753
-
754
- // Disable TOTP for the current user
755
- await authulaClient.totp.disable();
756
-
757
- // Get the TOTP URI for QR code generation
758
- await authulaClient.totp.getUri();
759
-
760
- // Verify a TOTP code
761
- await authulaClient.totp.verify({
762
- code: "123456",
763
- trustDevice: true,
764
- });
765
-
766
- // Verify a backup code
767
- await authulaClient.totp.verifyBackupCode({
768
- code: "AbcXyz",
769
- trustDevice: true,
770
- });
771
-
772
- // Generate fresh backup codes
773
- await authulaClient.totp.generateBackupCodes();
774
- ```
134
+ ## Available Plugins
775
135
 
776
- ---
136
+ The following plugins are available in this SDK:
137
+
138
+ - Core
139
+ - Access Control
140
+ - Admin
141
+ - Organizations
142
+ - API Key
143
+ - Email Password
144
+ - OAuth2
145
+ - CSRF
146
+ - JWT
147
+ - Bearer
148
+ - Magic Link
149
+ - TOTP
777
150
 
778
151
  ## Advanced Configuration
779
152
 
@@ -786,6 +159,7 @@ const authulaClient = createClient({
786
159
  url: "http://localhost:8080/auth",
787
160
  fetchOptions: {
788
161
  abortTimeout: 30, // Timeout in seconds
162
+ headers: {}, // Custom headers
789
163
  },
790
164
  plugins: [
791
165
  // your plugins
@@ -800,7 +174,7 @@ Add custom before/after fetch hooks for advanced customization:
800
174
  ```typescript
801
175
  const authulaClient = createClient({
802
176
  url: "http://localhost:8080/auth",
803
- plugins: [new EmailPasswordPlugin()],
177
+ plugins: [new CorePlugin()],
804
178
  });
805
179
 
806
180
  // Register a before fetch hook
@@ -822,40 +196,6 @@ authulaClient.registerAfterFetch(async (ctx, response) => {
822
196
  });
823
197
  ```
824
198
 
825
- ## API Reference
826
-
827
- ### Client Configuration
828
-
829
- ```typescript
830
- {
831
- // Base URL of your Authula server
832
- url: string,
833
- // Optional fetch configuration
834
- fetchOptions?: {
835
- // Request timeout in seconds
836
- abortTimeout?: number
837
- },
838
- // Cookie provider for SSR compatibility
839
- cookies?: () => CookieStore
840
- }
841
- ```
842
-
843
- ## Error Handling
844
-
845
- All methods return promises that can be caught for error handling:
846
-
847
- ```typescript
848
- try {
849
- const response = await authulaClient.emailPassword.signIn({
850
- email: "user@example.com",
851
- password: "password",
852
- });
853
- console.log("Signed in successfully", response);
854
- } catch (error) {
855
- console.error("Sign in failed:", error);
856
- }
857
- ```
858
-
859
199
  ## Contributing
860
200
 
861
201
  Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.