@23blocks/block-authentication 4.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
ADDED
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
# @23blocks/block-authentication
|
|
2
|
+
|
|
3
|
+
Authentication block for the 23blocks SDK - users, roles, API keys, and identity management.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@23blocks/block-authentication)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @23blocks/block-authentication @23blocks/transport-http
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
This package provides comprehensive authentication and identity management including:
|
|
17
|
+
|
|
18
|
+
- **Authentication** - Sign in, sign up, sign out, password reset
|
|
19
|
+
- **Users** - User management, profiles, avatars
|
|
20
|
+
- **Roles & Permissions** - Role-based access control
|
|
21
|
+
- **API Keys** - Create and manage API keys
|
|
22
|
+
- **MFA** - Multi-factor authentication
|
|
23
|
+
- **OAuth** - Social login and token management
|
|
24
|
+
- **Tenants** - Multi-tenant user management
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { createHttpTransport } from '@23blocks/transport-http';
|
|
30
|
+
import { createAuthenticationBlock } from '@23blocks/block-authentication';
|
|
31
|
+
|
|
32
|
+
// Create transport with your authentication service URL
|
|
33
|
+
const transport = createHttpTransport({
|
|
34
|
+
baseUrl: 'https://auth.yourapp.com', // Your authentication service URL
|
|
35
|
+
headers: () => {
|
|
36
|
+
const token = localStorage.getItem('access_token');
|
|
37
|
+
return {
|
|
38
|
+
'api-key': 'your-api-key',
|
|
39
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Create block
|
|
45
|
+
const auth = createAuthenticationBlock(transport, {
|
|
46
|
+
apiKey: 'your-api-key',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Sign in
|
|
50
|
+
const { user, accessToken, refreshToken } = await auth.auth.signIn({
|
|
51
|
+
email: 'user@example.com',
|
|
52
|
+
password: 'password',
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
localStorage.setItem('access_token', accessToken);
|
|
56
|
+
console.log('Welcome', user.email);
|
|
57
|
+
|
|
58
|
+
// Get current user
|
|
59
|
+
const currentUser = await auth.auth.getCurrentUser();
|
|
60
|
+
|
|
61
|
+
// Sign out
|
|
62
|
+
await auth.auth.signOut();
|
|
63
|
+
localStorage.removeItem('access_token');
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Services
|
|
67
|
+
|
|
68
|
+
### auth - Authentication
|
|
69
|
+
|
|
70
|
+
#### Sign In
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// Required fields: email, password
|
|
74
|
+
const { user, accessToken, refreshToken, expiresIn } = await auth.auth.signIn({
|
|
75
|
+
email: 'user@example.com', // Required
|
|
76
|
+
password: 'password', // Required
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**SignInRequest:**
|
|
81
|
+
| Field | Type | Required | Description |
|
|
82
|
+
|-------|------|----------|-------------|
|
|
83
|
+
| `email` | string | **Yes** | User's email address |
|
|
84
|
+
| `password` | string | **Yes** | User's password |
|
|
85
|
+
|
|
86
|
+
**SignInResponse:**
|
|
87
|
+
| Field | Type | Description |
|
|
88
|
+
|-------|------|-------------|
|
|
89
|
+
| `user` | User | The authenticated user object |
|
|
90
|
+
| `accessToken` | string | JWT access token |
|
|
91
|
+
| `refreshToken` | string? | Refresh token (if enabled) |
|
|
92
|
+
| `tokenType` | string | Always "Bearer" |
|
|
93
|
+
| `expiresIn` | number? | Token expiration in seconds |
|
|
94
|
+
|
|
95
|
+
#### Sign Up (Registration)
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// Sign up with required fields only
|
|
99
|
+
const { user, accessToken, message } = await auth.auth.signUp({
|
|
100
|
+
email: 'newuser@example.com', // Required
|
|
101
|
+
password: 'securePassword123', // Required
|
|
102
|
+
passwordConfirmation: 'securePassword123', // Required - must match password
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Sign up with all optional fields
|
|
106
|
+
const { user, accessToken, message } = await auth.auth.signUp({
|
|
107
|
+
// Required fields
|
|
108
|
+
email: 'newuser@example.com',
|
|
109
|
+
password: 'securePassword123',
|
|
110
|
+
passwordConfirmation: 'securePassword123',
|
|
111
|
+
|
|
112
|
+
// Optional fields
|
|
113
|
+
name: 'John Doe', // Display name
|
|
114
|
+
username: 'johndoe', // Unique username
|
|
115
|
+
roleId: 'role-uuid', // Assign specific role
|
|
116
|
+
confirmSuccessUrl: 'https://yourapp.com/email-confirmed', // Redirect after email confirmation
|
|
117
|
+
timeZone: 'America/New_York', // User's timezone
|
|
118
|
+
preferredLanguage: 'en', // Language preference
|
|
119
|
+
payload: { customField: 'value' }, // Custom JSON data
|
|
120
|
+
uniqueId: 'custom-id-123', // Custom unique identifier
|
|
121
|
+
subscription: 'premium-plan', // Subscription model unique_id
|
|
122
|
+
|
|
123
|
+
// OAuth registration (when registering via social login)
|
|
124
|
+
provider: 'google', // OAuth provider
|
|
125
|
+
uid: 'google-user-id', // OAuth user ID
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**SignUpRequest:**
|
|
130
|
+
| Field | Type | Required | Description |
|
|
131
|
+
|-------|------|----------|-------------|
|
|
132
|
+
| `email` | string | **Yes** | User's email address |
|
|
133
|
+
| `password` | string | **Yes** | Password (min length depends on server config) |
|
|
134
|
+
| `passwordConfirmation` | string | **Yes** | Must match password exactly |
|
|
135
|
+
| `name` | string | No | User's display name |
|
|
136
|
+
| `username` | string | No | Unique username |
|
|
137
|
+
| `roleId` | string | No | Role ID to assign |
|
|
138
|
+
| `confirmSuccessUrl` | string | No | URL to redirect after email confirmation |
|
|
139
|
+
| `timeZone` | string | No | IANA timezone (e.g., 'America/New_York') |
|
|
140
|
+
| `preferredLanguage` | string | No | Language code (e.g., 'en', 'es') |
|
|
141
|
+
| `payload` | object | No | Custom JSON data stored with user |
|
|
142
|
+
| `uniqueId` | string | No | Custom unique identifier |
|
|
143
|
+
| `subscription` | string | No | Subscription model unique_id |
|
|
144
|
+
| `provider` | string | No | OAuth provider name |
|
|
145
|
+
| `uid` | string | No | OAuth user ID |
|
|
146
|
+
|
|
147
|
+
**SignUpResponse:**
|
|
148
|
+
| Field | Type | Description |
|
|
149
|
+
|-------|------|-------------|
|
|
150
|
+
| `user` | User | The created user object |
|
|
151
|
+
| `accessToken` | string? | JWT token (only if email confirmation is disabled) |
|
|
152
|
+
| `message` | string? | Server message (e.g., "Confirmation email sent") |
|
|
153
|
+
|
|
154
|
+
> **Note:** If email confirmation is enabled on the server, `accessToken` will be `undefined` and the user must confirm their email before signing in.
|
|
155
|
+
|
|
156
|
+
#### Sign Out
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
await auth.auth.signOut();
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### Get Current User
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Returns user with role, avatar, and profile included
|
|
166
|
+
const user = await auth.auth.getCurrentUser();
|
|
167
|
+
console.log(user.email, user.role?.name, user.avatar?.url);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### Validate Token
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
const { user, valid } = await auth.auth.validateToken();
|
|
174
|
+
if (valid) {
|
|
175
|
+
console.log('Token is valid for', user.email);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### Password Reset
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// Request password reset email
|
|
183
|
+
await auth.auth.requestPasswordReset({
|
|
184
|
+
email: 'user@example.com', // Required
|
|
185
|
+
redirectUrl: 'https://yourapp.com/reset-password', // Optional
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Update password with reset token (from email link)
|
|
189
|
+
await auth.auth.updatePassword({
|
|
190
|
+
password: 'newSecurePassword', // Required
|
|
191
|
+
passwordConfirmation: 'newSecurePassword', // Required
|
|
192
|
+
resetPasswordToken: 'token-from-email', // Required for reset
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Update password with current password (logged in user)
|
|
196
|
+
await auth.auth.updatePassword({
|
|
197
|
+
password: 'newSecurePassword', // Required
|
|
198
|
+
passwordConfirmation: 'newSecurePassword', // Required
|
|
199
|
+
currentPassword: 'oldPassword', // Required for change
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**PasswordResetRequest:**
|
|
204
|
+
| Field | Type | Required | Description |
|
|
205
|
+
|-------|------|----------|-------------|
|
|
206
|
+
| `email` | string | **Yes** | User's email address |
|
|
207
|
+
| `redirectUrl` | string | No | URL for password reset page |
|
|
208
|
+
|
|
209
|
+
**PasswordUpdateRequest:**
|
|
210
|
+
| Field | Type | Required | Description |
|
|
211
|
+
|-------|------|----------|-------------|
|
|
212
|
+
| `password` | string | **Yes** | New password |
|
|
213
|
+
| `passwordConfirmation` | string | **Yes** | Must match password |
|
|
214
|
+
| `resetPasswordToken` | string | Conditional | Required when using reset link |
|
|
215
|
+
| `currentPassword` | string | Conditional | Required when changing password |
|
|
216
|
+
|
|
217
|
+
#### Refresh Token
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
const { accessToken, refreshToken, expiresIn } = await auth.auth.refreshToken({
|
|
221
|
+
refreshToken: 'current-refresh-token', // Required
|
|
222
|
+
});
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### Magic Link (Passwordless Login)
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// Request magic link email
|
|
229
|
+
await auth.auth.requestMagicLink({
|
|
230
|
+
email: 'user@example.com', // Required
|
|
231
|
+
redirectUrl: 'https://yourapp.com/magic-link', // Optional
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Verify magic link token (from email)
|
|
235
|
+
const { user, accessToken, refreshToken } = await auth.auth.verifyMagicLink({
|
|
236
|
+
token: 'magic-link-token', // Required
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
#### Invitations
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
// Send invitation to new user
|
|
244
|
+
await auth.auth.sendInvitation({
|
|
245
|
+
email: 'newuser@example.com', // Required
|
|
246
|
+
roleId: 'role-id', // Optional
|
|
247
|
+
redirectUrl: 'https://yourapp.com/accept-invite', // Optional
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Accept invitation
|
|
251
|
+
const { user, accessToken } = await auth.auth.acceptInvitation({
|
|
252
|
+
invitationToken: 'invitation-token', // Required
|
|
253
|
+
password: 'password', // Required
|
|
254
|
+
passwordConfirmation: 'password', // Required - must match password
|
|
255
|
+
name: 'John Doe', // Optional
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Resend invitation
|
|
259
|
+
const user = await auth.auth.resendInvitation({
|
|
260
|
+
email: 'user@example.com', // Required
|
|
261
|
+
appid: 'app-id', // Optional
|
|
262
|
+
acceptInvitationUrl: 'https://yourapp.com/accept', // Optional
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**AcceptInvitationRequest:**
|
|
267
|
+
| Field | Type | Required | Description |
|
|
268
|
+
|-------|------|----------|-------------|
|
|
269
|
+
| `invitationToken` | string | **Yes** | Token from invitation email |
|
|
270
|
+
| `password` | string | **Yes** | New password |
|
|
271
|
+
| `passwordConfirmation` | string | **Yes** | Must match password |
|
|
272
|
+
| `name` | string | No | User's display name |
|
|
273
|
+
|
|
274
|
+
#### Email Confirmation
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
// Confirm email with token (from confirmation email link)
|
|
278
|
+
const user = await auth.auth.confirmEmail('confirmation-token');
|
|
279
|
+
|
|
280
|
+
// Resend confirmation email
|
|
281
|
+
await auth.auth.resendConfirmation({
|
|
282
|
+
email: 'user@example.com', // Required
|
|
283
|
+
confirmSuccessUrl: 'https://yourapp.com/confirmed', // Optional - redirect URL
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**ResendConfirmationRequest:**
|
|
288
|
+
| Field | Type | Required | Description |
|
|
289
|
+
|-------|------|----------|-------------|
|
|
290
|
+
| `email` | string | **Yes** | User's email address |
|
|
291
|
+
| `confirmSuccessUrl` | string | No | URL to redirect after confirmation |
|
|
292
|
+
|
|
293
|
+
#### Email & Document Validation
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// Validate email before registration
|
|
297
|
+
const { exists, wellFormed, canRecover, accountStatus, maskedEmail } =
|
|
298
|
+
await auth.auth.validateEmail({
|
|
299
|
+
email: 'user@example.com',
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
if (exists) {
|
|
303
|
+
console.log('Email already registered');
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Validate document before registration
|
|
307
|
+
const { exists, canRecover, maskedEmail, maskedDocument, accountStatus } =
|
|
308
|
+
await auth.auth.validateDocument({
|
|
309
|
+
documentType: 'national_id',
|
|
310
|
+
documentNumber: '12345678',
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
#### Account Recovery (Deleted Accounts)
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// Request account recovery for a deleted account
|
|
318
|
+
const { success, message } = await auth.auth.requestAccountRecovery({
|
|
319
|
+
email: 'user@example.com', // Required
|
|
320
|
+
recoveryUrl: 'https://yourapp.com/recover', // Optional
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Complete account recovery with new password
|
|
324
|
+
const user = await auth.auth.completeAccountRecovery({
|
|
325
|
+
recoveryToken: 'recovery-token', // Required
|
|
326
|
+
password: 'newPassword', // Required
|
|
327
|
+
passwordConfirmation: 'newPassword', // Required
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### users - User Management
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
// List users (admin)
|
|
335
|
+
const { data: users, meta } = await auth.users.list({
|
|
336
|
+
limit: 20,
|
|
337
|
+
offset: 0,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
// Get user by ID
|
|
341
|
+
const user = await auth.users.get('user-id');
|
|
342
|
+
|
|
343
|
+
// Update user
|
|
344
|
+
const updated = await auth.users.update('user-id', {
|
|
345
|
+
name: 'New Name',
|
|
346
|
+
roleId: 'new-role-id',
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Delete user (soft delete)
|
|
350
|
+
await auth.users.delete('user-id');
|
|
351
|
+
|
|
352
|
+
// Get/update current user's profile
|
|
353
|
+
const profile = await auth.users.getProfile();
|
|
354
|
+
const updatedProfile = await auth.users.updateProfile({
|
|
355
|
+
firstName: 'John',
|
|
356
|
+
lastName: 'Doe',
|
|
357
|
+
phoneNumber: '+1234567890',
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// User devices
|
|
361
|
+
const devices = await auth.users.getDevices();
|
|
362
|
+
const device = await auth.users.addDevice({
|
|
363
|
+
deviceType: 'mobile',
|
|
364
|
+
pushId: 'push-token',
|
|
365
|
+
osType: 'ios',
|
|
366
|
+
});
|
|
367
|
+
await auth.users.removeDevice('device-id');
|
|
368
|
+
|
|
369
|
+
// Search users
|
|
370
|
+
const results = await auth.users.search({
|
|
371
|
+
query: 'john',
|
|
372
|
+
limit: 10,
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// User subscriptions
|
|
376
|
+
const subscription = await auth.users.addSubscription({
|
|
377
|
+
subscriptionModelId: 'model-id',
|
|
378
|
+
code: 'PREMIUM',
|
|
379
|
+
});
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### roles - Role Management
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
// List roles
|
|
386
|
+
const { data: roles } = await auth.roles.list();
|
|
387
|
+
|
|
388
|
+
// Get role by ID
|
|
389
|
+
const role = await auth.roles.get('role-id');
|
|
390
|
+
|
|
391
|
+
// Create role (admin)
|
|
392
|
+
const newRole = await auth.roles.create({
|
|
393
|
+
name: 'Editor',
|
|
394
|
+
code: 'editor',
|
|
395
|
+
permissionIds: ['perm-1', 'perm-2'],
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
// Update role
|
|
399
|
+
const updated = await auth.roles.update('role-id', {
|
|
400
|
+
name: 'Senior Editor',
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
// Delete role
|
|
404
|
+
await auth.roles.delete('role-id');
|
|
405
|
+
|
|
406
|
+
// List permissions
|
|
407
|
+
const { data: permissions } = await auth.roles.listPermissions();
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### apiKeys - API Key Management
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// List API keys
|
|
414
|
+
const { data: keys } = await auth.apiKeys.list();
|
|
415
|
+
|
|
416
|
+
// Get API key by ID
|
|
417
|
+
const key = await auth.apiKeys.get('key-id');
|
|
418
|
+
|
|
419
|
+
// Create API key
|
|
420
|
+
const { apiKey, secret } = await auth.apiKeys.create({
|
|
421
|
+
name: 'My API Key',
|
|
422
|
+
scopes: ['read', 'write'],
|
|
423
|
+
expiresAt: '2025-12-31',
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// Update API key
|
|
427
|
+
const updated = await auth.apiKeys.update('key-id', {
|
|
428
|
+
name: 'Updated Name',
|
|
429
|
+
scopes: ['read'],
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// Revoke API key
|
|
433
|
+
await auth.apiKeys.revoke('key-id');
|
|
434
|
+
|
|
435
|
+
// Delete API key
|
|
436
|
+
await auth.apiKeys.delete('key-id');
|
|
437
|
+
|
|
438
|
+
// Get usage statistics
|
|
439
|
+
const stats = await auth.apiKeys.getUsageStats('key-id');
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### mfa - Multi-Factor Authentication
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Check MFA status
|
|
446
|
+
const { enabled, methods } = await auth.mfa.getStatus();
|
|
447
|
+
|
|
448
|
+
// Setup MFA (get QR code)
|
|
449
|
+
const { qrCodeUrl, secret, backupCodes } = await auth.mfa.setup();
|
|
450
|
+
|
|
451
|
+
// Enable MFA
|
|
452
|
+
await auth.mfa.enable({
|
|
453
|
+
code: '123456',
|
|
454
|
+
secret: 'secret-from-setup',
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// Verify MFA code
|
|
458
|
+
const { valid } = await auth.mfa.verify({
|
|
459
|
+
code: '123456',
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
// Disable MFA
|
|
463
|
+
await auth.mfa.disable({
|
|
464
|
+
code: '123456',
|
|
465
|
+
});
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### oauth - OAuth & Token Management
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
// Social login
|
|
472
|
+
const { user, accessToken } = await auth.oauth.socialLogin({
|
|
473
|
+
provider: 'google',
|
|
474
|
+
accessToken: 'google-access-token',
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// Introspect token
|
|
478
|
+
const { active, userId, scopes } = await auth.oauth.introspectToken('token');
|
|
479
|
+
|
|
480
|
+
// Revoke token
|
|
481
|
+
await auth.oauth.revokeToken({
|
|
482
|
+
token: 'token-to-revoke',
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
// Revoke all tokens
|
|
486
|
+
await auth.oauth.revokeAllTokens();
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### tenants - Multi-Tenant Users
|
|
490
|
+
|
|
491
|
+
```typescript
|
|
492
|
+
// List tenant users
|
|
493
|
+
const { data: tenantUsers } = await auth.tenants.listUsers({
|
|
494
|
+
limit: 20,
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// Get tenant user
|
|
498
|
+
const tenantUser = await auth.tenants.getUser('tenant-user-id');
|
|
499
|
+
|
|
500
|
+
// Create tenant user
|
|
501
|
+
const newUser = await auth.tenants.createUser({
|
|
502
|
+
email: 'user@tenant.com',
|
|
503
|
+
name: 'Tenant User',
|
|
504
|
+
roleId: 'role-id',
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
// Update tenant user
|
|
508
|
+
const updated = await auth.tenants.updateUser('tenant-user-id', {
|
|
509
|
+
name: 'Updated Name',
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
// Delete tenant user
|
|
513
|
+
await auth.tenants.deleteUser('tenant-user-id');
|
|
514
|
+
|
|
515
|
+
// Validate tenant code
|
|
516
|
+
const { valid, tenant } = await auth.tenants.validateCode({
|
|
517
|
+
code: 'TENANT123',
|
|
518
|
+
});
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### avatars - User Avatars
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
// Get user avatar
|
|
525
|
+
const avatar = await auth.avatars.get('user-id');
|
|
526
|
+
|
|
527
|
+
// Create/upload avatar
|
|
528
|
+
const avatar = await auth.avatars.create({
|
|
529
|
+
userId: 'user-id',
|
|
530
|
+
file: fileBlob,
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
// Get presigned URL for upload
|
|
534
|
+
const { url, fields } = await auth.avatars.getPresignedUrl({
|
|
535
|
+
filename: 'avatar.jpg',
|
|
536
|
+
contentType: 'image/jpeg',
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// Delete avatar
|
|
540
|
+
await auth.avatars.delete('avatar-id');
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
## Types
|
|
544
|
+
|
|
545
|
+
```typescript
|
|
546
|
+
import type {
|
|
547
|
+
// User types
|
|
548
|
+
User,
|
|
549
|
+
Role,
|
|
550
|
+
Permission,
|
|
551
|
+
UserAvatar,
|
|
552
|
+
UserProfile,
|
|
553
|
+
|
|
554
|
+
// Auth types
|
|
555
|
+
SignInRequest,
|
|
556
|
+
SignInResponse,
|
|
557
|
+
SignUpRequest,
|
|
558
|
+
SignUpResponse,
|
|
559
|
+
PasswordResetRequest,
|
|
560
|
+
PasswordUpdateRequest,
|
|
561
|
+
RefreshTokenRequest,
|
|
562
|
+
RefreshTokenResponse,
|
|
563
|
+
MagicLinkRequest,
|
|
564
|
+
MagicLinkVerifyRequest,
|
|
565
|
+
InvitationRequest,
|
|
566
|
+
AcceptInvitationRequest,
|
|
567
|
+
ResendConfirmationRequest,
|
|
568
|
+
ValidateEmailRequest,
|
|
569
|
+
ValidateEmailResponse,
|
|
570
|
+
ValidateDocumentRequest,
|
|
571
|
+
ValidateDocumentResponse,
|
|
572
|
+
AccountRecoveryRequest,
|
|
573
|
+
AccountRecoveryResponse,
|
|
574
|
+
CompleteRecoveryRequest,
|
|
575
|
+
|
|
576
|
+
// API Key types
|
|
577
|
+
ApiKey,
|
|
578
|
+
ApiKeyWithSecret,
|
|
579
|
+
CreateApiKeyRequest,
|
|
580
|
+
|
|
581
|
+
// MFA types
|
|
582
|
+
MfaSetupResponse,
|
|
583
|
+
MfaVerifyRequest,
|
|
584
|
+
MfaStatusResponse,
|
|
585
|
+
|
|
586
|
+
// Company types
|
|
587
|
+
Company,
|
|
588
|
+
Tenant,
|
|
589
|
+
} from '@23blocks/block-authentication';
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## Error Handling
|
|
593
|
+
|
|
594
|
+
```typescript
|
|
595
|
+
import { isBlockErrorException, ErrorCodes } from '@23blocks/contracts';
|
|
596
|
+
|
|
597
|
+
try {
|
|
598
|
+
await auth.auth.signIn({ email, password });
|
|
599
|
+
} catch (error) {
|
|
600
|
+
if (isBlockErrorException(error)) {
|
|
601
|
+
switch (error.code) {
|
|
602
|
+
case ErrorCodes.INVALID_CREDENTIALS:
|
|
603
|
+
console.log('Invalid email or password');
|
|
604
|
+
break;
|
|
605
|
+
case ErrorCodes.UNAUTHORIZED:
|
|
606
|
+
console.log('Session expired');
|
|
607
|
+
break;
|
|
608
|
+
case ErrorCodes.VALIDATION_ERROR:
|
|
609
|
+
console.log('Validation error:', error.message);
|
|
610
|
+
break;
|
|
611
|
+
default:
|
|
612
|
+
console.log('Error:', error.message);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
## Related Packages
|
|
619
|
+
|
|
620
|
+
- [`@23blocks/angular`](https://www.npmjs.com/package/@23blocks/angular) - Angular integration
|
|
621
|
+
- [`@23blocks/react`](https://www.npmjs.com/package/@23blocks/react) - React integration
|
|
622
|
+
- [`@23blocks/sdk`](https://www.npmjs.com/package/@23blocks/sdk) - Full SDK package
|
|
623
|
+
|
|
624
|
+
## License
|
|
625
|
+
|
|
626
|
+
MIT - Copyright (c) 2024 23blocks
|
package/dist/index.esm.js
CHANGED
|
@@ -2764,11 +2764,11 @@ const tenantUserMapper = {
|
|
|
2764
2764
|
* baseUrl: 'https://api.example.com',
|
|
2765
2765
|
* headers: () => ({
|
|
2766
2766
|
* 'Authorization': `Bearer ${getToken()}`,
|
|
2767
|
-
* '
|
|
2767
|
+
* 'api-key': 'your-api-key',
|
|
2768
2768
|
* }),
|
|
2769
2769
|
* });
|
|
2770
2770
|
*
|
|
2771
|
-
* const auth = createAuthenticationBlock(transport, {
|
|
2771
|
+
* const auth = createAuthenticationBlock(transport, { apiKey: 'your-api-key' });
|
|
2772
2772
|
*
|
|
2773
2773
|
* // Sign in
|
|
2774
2774
|
* const { user, accessToken } = await auth.auth.signIn({
|
|
@@ -15,8 +15,8 @@ import { type TenantsService } from './services/tenants.service.js';
|
|
|
15
15
|
* Configuration for the Authentication block
|
|
16
16
|
*/
|
|
17
17
|
export interface AuthenticationBlockConfig extends BlockConfig {
|
|
18
|
-
/**
|
|
19
|
-
|
|
18
|
+
/** API Key for authenticating with 23blocks services */
|
|
19
|
+
apiKey: string;
|
|
20
20
|
/** Tenant ID (optional, for multi-tenant setups) */
|
|
21
21
|
tenantId?: string;
|
|
22
22
|
}
|
|
@@ -137,11 +137,11 @@ export interface AuthenticationBlock {
|
|
|
137
137
|
* baseUrl: 'https://api.example.com',
|
|
138
138
|
* headers: () => ({
|
|
139
139
|
* 'Authorization': `Bearer ${getToken()}`,
|
|
140
|
-
* '
|
|
140
|
+
* 'api-key': 'your-api-key',
|
|
141
141
|
* }),
|
|
142
142
|
* });
|
|
143
143
|
*
|
|
144
|
-
* const auth = createAuthenticationBlock(transport, {
|
|
144
|
+
* const auth = createAuthenticationBlock(transport, { apiKey: 'your-api-key' });
|
|
145
145
|
*
|
|
146
146
|
* // Sign in
|
|
147
147
|
* const { user, accessToken } = await auth.auth.signIn({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authentication.block.d.ts","sourceRoot":"","sources":["../../../src/lib/authentication.block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC7B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIL,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EACjC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAML,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAOL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC1F,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE1F;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,WAAW;IAC5D,
|
|
1
|
+
{"version":3,"file":"authentication.block.d.ts","sourceRoot":"","sources":["../../../src/lib/authentication.block.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED