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 +79 -739
- package/dist/custom-fetch-Ce6_l1Qb.js +118 -0
- package/dist/custom-fetch-Ce6_l1Qb.js.map +1 -0
- package/dist/index-BdPCSdtc.d.ts +2015 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +30 -17
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.d.ts +2935 -738
- package/dist/plugins/index.js +4090 -523
- package/dist/plugins/index.js.map +1 -1
- package/dist/rolldown-runtime-w6R9maHv.js +18 -0
- package/package.json +19 -18
- package/dist/fetch-BnZpQ0Yq.js +0 -128
- package/dist/fetch-BnZpQ0Yq.js.map +0 -1
- package/dist/fetch-CEj1gBkL.cjs +0 -163
- package/dist/fetch-CEj1gBkL.cjs.map +0 -1
- package/dist/index.cjs +0 -60
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -2
- package/dist/plugins/index.cjs +0 -696
- package/dist/plugins/index.cjs.map +0 -1
- package/dist/plugins/index.d.cts +0 -825
- package/dist/sdk-7eSlhCrf.d.cts +0 -167
- package/dist/sdk-7eSlhCrf.d.ts +0 -167
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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
|
-
//
|
|
531
|
-
await
|
|
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
|
-
|
|
543
|
-
|
|
544
|
-
await
|
|
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
|
-
|
|
89
|
+
Use with SSR frameworks e.g. Next.js/Tanstack Start etc.
|
|
561
90
|
|
|
562
91
|
```typescript
|
|
563
|
-
import {
|
|
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
|
-
|
|
586
|
-
|
|
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
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
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
|
-
//
|
|
597
|
-
await authulaClient.emailPassword.changePassword({
|
|
598
|
-
token: "reset-token",
|
|
599
|
-
password: "newSecurePassword123",
|
|
600
|
-
});
|
|
105
|
+
// Now you can use the client...
|
|
601
106
|
|
|
602
|
-
|
|
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
|
-
|
|
112
|
+
For server-side rendering or applications that need to handle cookies properly:
|
|
614
113
|
|
|
615
114
|
```typescript
|
|
616
|
-
import {
|
|
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
|
-
|
|
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: "
|
|
648
|
-
headerName: "X-CSRF-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
|
|
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.
|