@intelicity/gates-sdk 0.1.4 → 0.1.6
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 +218 -19
- package/dist/errors/error.d.ts +46 -2
- package/dist/errors/error.d.ts.map +1 -1
- package/dist/errors/error.js +82 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -1
- package/dist/services/auth-service.d.ts.map +1 -1
- package/dist/services/auth-service.js +61 -32
- package/dist/services/user-service.d.ts +2 -2
- package/dist/services/user-service.d.ts.map +1 -1
- package/dist/services/user-service.js +45 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,8 +14,9 @@ npm install @intelicity/gates-sdk
|
|
|
14
14
|
- 👥 User management service with backend integration
|
|
15
15
|
- 🎯 TypeScript support with full type definitions
|
|
16
16
|
- 💾 Built-in JWKS caching for better performance
|
|
17
|
-
- 🎨
|
|
17
|
+
- 🎨 Comprehensive error hierarchy with specific error types
|
|
18
18
|
- 🔐 Group-based access control
|
|
19
|
+
- ⚡ Detailed error messages with status codes and error codes
|
|
19
20
|
|
|
20
21
|
## Usage
|
|
21
22
|
|
|
@@ -79,7 +80,15 @@ try {
|
|
|
79
80
|
### Complete Integration Example
|
|
80
81
|
|
|
81
82
|
```typescript
|
|
82
|
-
import {
|
|
83
|
+
import {
|
|
84
|
+
AuthService,
|
|
85
|
+
UserService,
|
|
86
|
+
TokenExpiredError,
|
|
87
|
+
UnauthorizedGroupError,
|
|
88
|
+
ApiRequestError,
|
|
89
|
+
MissingParameterError,
|
|
90
|
+
GatesError,
|
|
91
|
+
} from "@intelicity/gates-sdk";
|
|
83
92
|
|
|
84
93
|
class MyApplication {
|
|
85
94
|
private authService: AuthService;
|
|
@@ -114,7 +123,41 @@ class MyApplication {
|
|
|
114
123
|
total: users.total,
|
|
115
124
|
};
|
|
116
125
|
} catch (error) {
|
|
117
|
-
|
|
126
|
+
// Handle specific error types
|
|
127
|
+
if (error instanceof TokenExpiredError) {
|
|
128
|
+
return { error: "Session expired", code: 401 };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (error instanceof UnauthorizedGroupError) {
|
|
132
|
+
return {
|
|
133
|
+
error: "Access denied",
|
|
134
|
+
code: 403,
|
|
135
|
+
requiredGroups: error.requiredGroups,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (error instanceof ApiRequestError) {
|
|
140
|
+
return {
|
|
141
|
+
error: "Service unavailable",
|
|
142
|
+
code: error.statusCode || 500,
|
|
143
|
+
details: error.message,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (error instanceof MissingParameterError) {
|
|
148
|
+
return { error: "Invalid request", code: 400 };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (error instanceof GatesError) {
|
|
152
|
+
return {
|
|
153
|
+
error: "Operation failed",
|
|
154
|
+
code: 500,
|
|
155
|
+
errorCode: error.code,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Unknown error
|
|
160
|
+
throw error;
|
|
118
161
|
}
|
|
119
162
|
}
|
|
120
163
|
}
|
|
@@ -122,44 +165,98 @@ class MyApplication {
|
|
|
122
165
|
|
|
123
166
|
### Error Handling
|
|
124
167
|
|
|
125
|
-
The SDK provides
|
|
168
|
+
The SDK provides a comprehensive error hierarchy for better error handling:
|
|
126
169
|
|
|
127
170
|
```typescript
|
|
128
171
|
import {
|
|
129
172
|
AuthService,
|
|
130
173
|
UserService,
|
|
174
|
+
// Base errors
|
|
175
|
+
GatesError,
|
|
176
|
+
// Authentication errors
|
|
131
177
|
AuthenticationError,
|
|
132
178
|
TokenExpiredError,
|
|
133
179
|
InvalidTokenError,
|
|
134
180
|
MissingAuthorizationError,
|
|
181
|
+
UnauthorizedGroupError,
|
|
182
|
+
// API errors
|
|
183
|
+
ApiError,
|
|
184
|
+
ApiRequestError,
|
|
185
|
+
InvalidResponseError,
|
|
186
|
+
// Parameter errors
|
|
187
|
+
MissingParameterError,
|
|
188
|
+
InvalidParameterError,
|
|
135
189
|
} from "@intelicity/gates-sdk";
|
|
136
190
|
|
|
137
|
-
const authService = new AuthService(region, userPoolId, audience);
|
|
191
|
+
const authService = new AuthService(region, userPoolId, audience, ["admin"]);
|
|
138
192
|
|
|
193
|
+
// Authentication Error Handling
|
|
139
194
|
try {
|
|
140
195
|
const user = await authService.verifyToken(token);
|
|
196
|
+
console.log("User authenticated:", user);
|
|
141
197
|
} catch (error) {
|
|
142
198
|
if (error instanceof TokenExpiredError) {
|
|
143
199
|
console.error("Token expired, please login again");
|
|
200
|
+
// error.code === "TOKEN_EXPIRED"
|
|
144
201
|
} else if (error instanceof InvalidTokenError) {
|
|
145
|
-
console.error("Invalid token
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
202
|
+
console.error("Invalid token:", error.message);
|
|
203
|
+
// error.code === "INVALID_TOKEN"
|
|
204
|
+
} else if (error instanceof UnauthorizedGroupError) {
|
|
205
|
+
console.error("Access denied:", error.message);
|
|
206
|
+
console.error("Required groups:", error.requiredGroups);
|
|
207
|
+
// error.code === "UNAUTHORIZED_GROUP"
|
|
208
|
+
} else if (error instanceof MissingParameterError) {
|
|
209
|
+
console.error("Missing parameter:", error.message);
|
|
210
|
+
// error.code === "MISSING_PARAMETER"
|
|
211
|
+
} else if (error instanceof AuthenticationError) {
|
|
149
212
|
console.error("Authentication failed:", error.message);
|
|
150
213
|
}
|
|
151
214
|
}
|
|
152
215
|
|
|
153
|
-
//
|
|
216
|
+
// User Service Error Handling
|
|
217
|
+
const userService = new UserService(backendUrl, systemName);
|
|
218
|
+
|
|
154
219
|
try {
|
|
155
220
|
const users = await userService.getAllUsers(token);
|
|
221
|
+
console.log("Users fetched:", users.profiles.length);
|
|
156
222
|
} catch (error) {
|
|
157
|
-
if (error
|
|
158
|
-
console.error(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
223
|
+
if (error instanceof ApiRequestError) {
|
|
224
|
+
console.error(`API request failed [${error.statusCode}]:`, error.message);
|
|
225
|
+
// error.code === "API_REQUEST_ERROR"
|
|
226
|
+
// error.statusCode contains HTTP status code
|
|
227
|
+
|
|
228
|
+
if (error.statusCode === 401) {
|
|
229
|
+
console.error("Unauthorized - check your token");
|
|
230
|
+
} else if (error.statusCode === 403) {
|
|
231
|
+
console.error("Forbidden - insufficient permissions");
|
|
232
|
+
} else if (error.statusCode === 404) {
|
|
233
|
+
console.error("Resource not found");
|
|
234
|
+
}
|
|
235
|
+
} else if (error instanceof InvalidResponseError) {
|
|
236
|
+
console.error("Invalid API response:", error.message);
|
|
237
|
+
// error.code === "INVALID_RESPONSE"
|
|
238
|
+
} else if (error instanceof MissingParameterError) {
|
|
239
|
+
console.error("Missing required parameter:", error.message);
|
|
240
|
+
} else if (error instanceof GatesError) {
|
|
241
|
+
console.error("Gates SDK error:", error.message, error.code);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Catch all Gates errors
|
|
246
|
+
try {
|
|
247
|
+
const profile = await userService.getProfile(token);
|
|
248
|
+
} catch (error) {
|
|
249
|
+
if (error instanceof GatesError) {
|
|
250
|
+
// All SDK errors inherit from GatesError
|
|
251
|
+
console.error(`Error [${error.code}]:`, error.message);
|
|
252
|
+
|
|
253
|
+
// You can check specific properties based on error type
|
|
254
|
+
if (error instanceof ApiRequestError && error.statusCode) {
|
|
255
|
+
console.error(`HTTP Status: ${error.statusCode}`);
|
|
256
|
+
}
|
|
257
|
+
if (error instanceof UnauthorizedGroupError) {
|
|
258
|
+
console.error(`Required groups: ${error.requiredGroups.join(", ")}`);
|
|
259
|
+
}
|
|
163
260
|
}
|
|
164
261
|
}
|
|
165
262
|
```
|
|
@@ -275,10 +372,82 @@ type VerifyOptions = {
|
|
|
275
372
|
|
|
276
373
|
#### Custom Errors
|
|
277
374
|
|
|
278
|
-
|
|
375
|
+
All errors inherit from `GatesError` and include a `code` property for easy error identification.
|
|
376
|
+
|
|
377
|
+
**Base Errors:**
|
|
378
|
+
|
|
379
|
+
- `GatesError`: Base error class for all SDK errors
|
|
380
|
+
- Properties: `message`, `code`
|
|
381
|
+
|
|
382
|
+
**Authentication Errors:**
|
|
383
|
+
|
|
384
|
+
- `AuthenticationError`: Base authentication error (extends `GatesError`)
|
|
279
385
|
- `TokenExpiredError`: Token has expired
|
|
386
|
+
- Code: `TOKEN_EXPIRED`
|
|
280
387
|
- `InvalidTokenError`: Token is invalid or malformed
|
|
388
|
+
- Code: `INVALID_TOKEN`
|
|
281
389
|
- `MissingAuthorizationError`: Authorization header is missing
|
|
390
|
+
- Code: `MISSING_AUTHORIZATION`
|
|
391
|
+
- `UnauthorizedGroupError`: User is not a member of required group
|
|
392
|
+
- Code: `UNAUTHORIZED_GROUP`
|
|
393
|
+
- Properties: `message`, `code`, `requiredGroups: string[]`
|
|
394
|
+
|
|
395
|
+
**API Errors:**
|
|
396
|
+
|
|
397
|
+
- `ApiError`: Base API error (extends `GatesError`)
|
|
398
|
+
- Properties: `message`, `code`, `statusCode?: number`
|
|
399
|
+
- `ApiRequestError`: API request failed
|
|
400
|
+
- Code: `API_REQUEST_ERROR`
|
|
401
|
+
- Properties: `message`, `code`, `statusCode?: number`
|
|
402
|
+
- `InvalidResponseError`: API response format is invalid
|
|
403
|
+
- Code: `INVALID_RESPONSE`
|
|
404
|
+
|
|
405
|
+
**Parameter Errors:**
|
|
406
|
+
|
|
407
|
+
- `MissingParameterError`: Required parameter is missing
|
|
408
|
+
- Code: `MISSING_PARAMETER`
|
|
409
|
+
- `InvalidParameterError`: Parameter has an invalid value
|
|
410
|
+
- Code: `INVALID_PARAMETER`
|
|
411
|
+
|
|
412
|
+
### Error Codes Reference
|
|
413
|
+
|
|
414
|
+
All SDK errors include a `code` property for programmatic error handling:
|
|
415
|
+
|
|
416
|
+
| Error Code | Error Class | Description |
|
|
417
|
+
| ----------------------- | --------------------------- | ------------------------------------ |
|
|
418
|
+
| `TOKEN_EXPIRED` | `TokenExpiredError` | JWT token has expired |
|
|
419
|
+
| `INVALID_TOKEN` | `InvalidTokenError` | Token is invalid or malformed |
|
|
420
|
+
| `MISSING_AUTHORIZATION` | `MissingAuthorizationError` | Authorization header is missing |
|
|
421
|
+
| `UNAUTHORIZED_GROUP` | `UnauthorizedGroupError` | User lacks required group membership |
|
|
422
|
+
| `API_REQUEST_ERROR` | `ApiRequestError` | API request failed |
|
|
423
|
+
| `INVALID_RESPONSE` | `InvalidResponseError` | API response format is invalid |
|
|
424
|
+
| `MISSING_PARAMETER` | `MissingParameterError` | Required parameter is missing |
|
|
425
|
+
| `INVALID_PARAMETER` | `InvalidParameterError` | Parameter has invalid value |
|
|
426
|
+
|
|
427
|
+
**Usage Example:**
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
try {
|
|
431
|
+
const user = await authService.verifyToken(token);
|
|
432
|
+
} catch (error) {
|
|
433
|
+
if (error instanceof GatesError) {
|
|
434
|
+
switch (error.code) {
|
|
435
|
+
case "TOKEN_EXPIRED":
|
|
436
|
+
// Redirect to login
|
|
437
|
+
break;
|
|
438
|
+
case "UNAUTHORIZED_GROUP":
|
|
439
|
+
// Show access denied page
|
|
440
|
+
break;
|
|
441
|
+
case "API_REQUEST_ERROR":
|
|
442
|
+
// Show error message with retry option
|
|
443
|
+
break;
|
|
444
|
+
default:
|
|
445
|
+
// Generic error handling
|
|
446
|
+
console.error(error.message);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
```
|
|
282
451
|
|
|
283
452
|
## Environment Variables
|
|
284
453
|
|
|
@@ -334,14 +503,30 @@ const userService = new UserService(
|
|
|
334
503
|
- Use strong, unique audience values (client IDs)
|
|
335
504
|
|
|
336
505
|
```typescript
|
|
506
|
+
import {
|
|
507
|
+
GatesError,
|
|
508
|
+
TokenExpiredError,
|
|
509
|
+
UnauthorizedGroupError,
|
|
510
|
+
} from "@intelicity/gates-sdk";
|
|
511
|
+
|
|
337
512
|
// Good: Secure error handling
|
|
338
513
|
try {
|
|
339
514
|
const user = await authService.verifyToken(token);
|
|
340
515
|
} catch (error) {
|
|
341
516
|
// Log for monitoring (server-side only)
|
|
342
|
-
|
|
517
|
+
if (error instanceof GatesError) {
|
|
518
|
+
console.error('Auth failed:', error.code, error.constructor.name);
|
|
519
|
+
}
|
|
343
520
|
|
|
344
|
-
// Return
|
|
521
|
+
// Return appropriate error to client based on type
|
|
522
|
+
if (error instanceof TokenExpiredError) {
|
|
523
|
+
throw new Error('Session expired');
|
|
524
|
+
}
|
|
525
|
+
if (error instanceof UnauthorizedGroupError) {
|
|
526
|
+
throw new Error('Access denied');
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Generic error for other cases
|
|
345
530
|
throw new Error('Authentication failed');
|
|
346
531
|
}
|
|
347
532
|
|
|
@@ -349,6 +534,20 @@ try {
|
|
|
349
534
|
catch (error) {
|
|
350
535
|
throw new Error(`Auth failed: ${error.message}`); // May expose internal details
|
|
351
536
|
}
|
|
537
|
+
|
|
538
|
+
// Good: Check error codes for routing logic
|
|
539
|
+
try {
|
|
540
|
+
const users = await userService.getAllUsers(token);
|
|
541
|
+
} catch (error) {
|
|
542
|
+
if (error instanceof GatesError) {
|
|
543
|
+
// Safe to use error codes for client-side logic
|
|
544
|
+
if (error.code === 'TOKEN_EXPIRED') {
|
|
545
|
+
redirectToLogin();
|
|
546
|
+
} else if (error.code === 'UNAUTHORIZED_GROUP') {
|
|
547
|
+
showAccessDenied();
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
352
551
|
```
|
|
353
552
|
|
|
354
553
|
## Development
|
package/dist/errors/error.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Base error class for
|
|
2
|
+
* Base error class for all Gates SDK errors
|
|
3
3
|
*/
|
|
4
|
-
export declare class
|
|
4
|
+
export declare class GatesError extends Error {
|
|
5
5
|
readonly code?: string | undefined;
|
|
6
6
|
constructor(message: string, code?: string | undefined);
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Base error class for authentication-related errors
|
|
10
|
+
*/
|
|
11
|
+
export declare class AuthenticationError extends GatesError {
|
|
12
|
+
constructor(message: string, code?: string);
|
|
13
|
+
}
|
|
8
14
|
/**
|
|
9
15
|
* Error thrown when a token has expired
|
|
10
16
|
*/
|
|
@@ -23,4 +29,42 @@ export declare class InvalidTokenError extends AuthenticationError {
|
|
|
23
29
|
export declare class MissingAuthorizationError extends AuthenticationError {
|
|
24
30
|
constructor(message?: string);
|
|
25
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Error thrown when user is not a member of required group
|
|
34
|
+
*/
|
|
35
|
+
export declare class UnauthorizedGroupError extends AuthenticationError {
|
|
36
|
+
readonly requiredGroups: string[];
|
|
37
|
+
constructor(message: string, requiredGroups: string[]);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Base error class for API-related errors
|
|
41
|
+
*/
|
|
42
|
+
export declare class ApiError extends GatesError {
|
|
43
|
+
readonly statusCode?: number | undefined;
|
|
44
|
+
constructor(message: string, statusCode?: number | undefined, code?: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error thrown when API request fails
|
|
48
|
+
*/
|
|
49
|
+
export declare class ApiRequestError extends ApiError {
|
|
50
|
+
constructor(message: string, statusCode?: number);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when API response is invalid
|
|
54
|
+
*/
|
|
55
|
+
export declare class InvalidResponseError extends ApiError {
|
|
56
|
+
constructor(message?: string);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Error thrown when a required parameter is missing
|
|
60
|
+
*/
|
|
61
|
+
export declare class MissingParameterError extends GatesError {
|
|
62
|
+
constructor(parameterName: string);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Error thrown when a parameter has an invalid value
|
|
66
|
+
*/
|
|
67
|
+
export declare class InvalidParameterError extends GatesError {
|
|
68
|
+
constructor(parameterName: string, reason?: string);
|
|
69
|
+
}
|
|
26
70
|
//# sourceMappingURL=error.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/errors/error.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/errors/error.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;aACU,IAAI,CAAC,EAAE,MAAM;gBAA9C,OAAO,EAAE,MAAM,EAAkB,IAAI,CAAC,EAAE,MAAM,YAAA;CAK3D;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,UAAU;gBACrC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAK3C;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,mBAAmB;gBAC5C,OAAO,SAAmB;CAKvC;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,mBAAmB;gBAC5C,OAAO,SAAmB;CAKvC;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,mBAAmB;gBACpD,OAAO,SAAwC;CAK5D;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,mBAAmB;aAChB,cAAc,EAAE,MAAM,EAAE;gBAAzD,OAAO,EAAE,MAAM,EAAkB,cAAc,EAAE,MAAM,EAAE;CAKtE;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,UAAU;aAGpB,UAAU,CAAC,EAAE,MAAM;gBADnC,OAAO,EAAE,MAAM,EACC,UAAU,CAAC,EAAE,MAAM,YAAA,EACnC,IAAI,CAAC,EAAE,MAAM;CAMhB;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAKjD;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,OAAO,SAAwC;CAK5D;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,UAAU;gBACvC,aAAa,EAAE,MAAM;CAQlC;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,UAAU;gBACvC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAQnD"}
|
package/dist/errors/error.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
// src/errors/error.ts
|
|
2
2
|
/**
|
|
3
|
-
* Base error class for
|
|
3
|
+
* Base error class for all Gates SDK errors
|
|
4
4
|
*/
|
|
5
|
-
export class
|
|
5
|
+
export class GatesError extends Error {
|
|
6
6
|
code;
|
|
7
7
|
constructor(message, code) {
|
|
8
8
|
super(message);
|
|
9
9
|
this.code = code;
|
|
10
|
+
this.name = "GatesError";
|
|
11
|
+
Object.setPrototypeOf(this, GatesError.prototype);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Base error class for authentication-related errors
|
|
16
|
+
*/
|
|
17
|
+
export class AuthenticationError extends GatesError {
|
|
18
|
+
constructor(message, code) {
|
|
19
|
+
super(message, code);
|
|
10
20
|
this.name = "AuthenticationError";
|
|
11
21
|
Object.setPrototypeOf(this, AuthenticationError.prototype);
|
|
12
22
|
}
|
|
@@ -15,7 +25,7 @@ export class AuthenticationError extends Error {
|
|
|
15
25
|
* Error thrown when a token has expired
|
|
16
26
|
*/
|
|
17
27
|
export class TokenExpiredError extends AuthenticationError {
|
|
18
|
-
constructor(message = "Token
|
|
28
|
+
constructor(message = "Token expirado") {
|
|
19
29
|
super(message, "TOKEN_EXPIRED");
|
|
20
30
|
this.name = "TokenExpiredError";
|
|
21
31
|
Object.setPrototypeOf(this, TokenExpiredError.prototype);
|
|
@@ -25,7 +35,7 @@ export class TokenExpiredError extends AuthenticationError {
|
|
|
25
35
|
* Error thrown when a token is invalid
|
|
26
36
|
*/
|
|
27
37
|
export class InvalidTokenError extends AuthenticationError {
|
|
28
|
-
constructor(message = "
|
|
38
|
+
constructor(message = "Token inválido") {
|
|
29
39
|
super(message, "INVALID_TOKEN");
|
|
30
40
|
this.name = "InvalidTokenError";
|
|
31
41
|
Object.setPrototypeOf(this, InvalidTokenError.prototype);
|
|
@@ -35,9 +45,76 @@ export class InvalidTokenError extends AuthenticationError {
|
|
|
35
45
|
* Error thrown when authorization header is missing
|
|
36
46
|
*/
|
|
37
47
|
export class MissingAuthorizationError extends AuthenticationError {
|
|
38
|
-
constructor(message = "
|
|
48
|
+
constructor(message = "Header de autorização não fornecido") {
|
|
39
49
|
super(message, "MISSING_AUTHORIZATION");
|
|
40
50
|
this.name = "MissingAuthorizationError";
|
|
41
51
|
Object.setPrototypeOf(this, MissingAuthorizationError.prototype);
|
|
42
52
|
}
|
|
43
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Error thrown when user is not a member of required group
|
|
56
|
+
*/
|
|
57
|
+
export class UnauthorizedGroupError extends AuthenticationError {
|
|
58
|
+
requiredGroups;
|
|
59
|
+
constructor(message, requiredGroups) {
|
|
60
|
+
super(message, "UNAUTHORIZED_GROUP");
|
|
61
|
+
this.requiredGroups = requiredGroups;
|
|
62
|
+
this.name = "UnauthorizedGroupError";
|
|
63
|
+
Object.setPrototypeOf(this, UnauthorizedGroupError.prototype);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Base error class for API-related errors
|
|
68
|
+
*/
|
|
69
|
+
export class ApiError extends GatesError {
|
|
70
|
+
statusCode;
|
|
71
|
+
constructor(message, statusCode, code) {
|
|
72
|
+
super(message, code);
|
|
73
|
+
this.statusCode = statusCode;
|
|
74
|
+
this.name = "ApiError";
|
|
75
|
+
Object.setPrototypeOf(this, ApiError.prototype);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Error thrown when API request fails
|
|
80
|
+
*/
|
|
81
|
+
export class ApiRequestError extends ApiError {
|
|
82
|
+
constructor(message, statusCode) {
|
|
83
|
+
super(message, statusCode, "API_REQUEST_ERROR");
|
|
84
|
+
this.name = "ApiRequestError";
|
|
85
|
+
Object.setPrototypeOf(this, ApiRequestError.prototype);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Error thrown when API response is invalid
|
|
90
|
+
*/
|
|
91
|
+
export class InvalidResponseError extends ApiError {
|
|
92
|
+
constructor(message = "Formato de resposta da API inválido") {
|
|
93
|
+
super(message, undefined, "INVALID_RESPONSE");
|
|
94
|
+
this.name = "InvalidResponseError";
|
|
95
|
+
Object.setPrototypeOf(this, InvalidResponseError.prototype);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Error thrown when a required parameter is missing
|
|
100
|
+
*/
|
|
101
|
+
export class MissingParameterError extends GatesError {
|
|
102
|
+
constructor(parameterName) {
|
|
103
|
+
super(`Parâmetro obrigatório ausente: ${parameterName}`, "MISSING_PARAMETER");
|
|
104
|
+
this.name = "MissingParameterError";
|
|
105
|
+
Object.setPrototypeOf(this, MissingParameterError.prototype);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Error thrown when a parameter has an invalid value
|
|
110
|
+
*/
|
|
111
|
+
export class InvalidParameterError extends GatesError {
|
|
112
|
+
constructor(parameterName, reason) {
|
|
113
|
+
const message = reason
|
|
114
|
+
? `Parâmetro '${parameterName}' inválido: ${reason}`
|
|
115
|
+
: `Parâmetro inválido: ${parameterName}`;
|
|
116
|
+
super(message, "INVALID_PARAMETER");
|
|
117
|
+
this.name = "InvalidParameterError";
|
|
118
|
+
Object.setPrototypeOf(this, InvalidParameterError.prototype);
|
|
119
|
+
}
|
|
120
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export type { GatesUser as GatesUser } from "./models/user.js";
|
|
|
2
2
|
export type { UserProfile as Profile, ProfileAttribute, } from "./models/profile.js";
|
|
3
3
|
export { GatesUserService as UserService, type UserListResponse, type GetAllUsersOptions, } from "./services/user-service.js";
|
|
4
4
|
export { GatesAuthService as AuthService, type VerifyOptions, } from "./services/auth-service.js";
|
|
5
|
-
export { AuthenticationError, TokenExpiredError, InvalidTokenError, MissingAuthorizationError, } from "./errors/error.js";
|
|
5
|
+
export { GatesError, AuthenticationError, TokenExpiredError, InvalidTokenError, MissingAuthorizationError, UnauthorizedGroupError, ApiError, ApiRequestError, InvalidResponseError, MissingParameterError, InvalidParameterError, } from "./errors/error.js";
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EAAE,SAAS,IAAI,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/D,YAAY,EACV,WAAW,IAAI,OAAO,EACtB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,gBAAgB,IAAI,WAAW,EAC/B,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gBAAgB,IAAI,WAAW,EAC/B,KAAK,aAAa,GACnB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAEL,UAAU,EAGV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EAGtB,QAAQ,EACR,eAAe,EACf,oBAAoB,EAGpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
// Main exports for Gates SDK
|
|
2
|
+
// Services
|
|
1
3
|
export { GatesUserService as UserService, } from "./services/user-service.js";
|
|
2
4
|
export { GatesAuthService as AuthService, } from "./services/auth-service.js";
|
|
3
|
-
|
|
5
|
+
// Errors
|
|
6
|
+
export {
|
|
7
|
+
// Base errors
|
|
8
|
+
GatesError,
|
|
9
|
+
// Authentication errors
|
|
10
|
+
AuthenticationError, TokenExpiredError, InvalidTokenError, MissingAuthorizationError, UnauthorizedGroupError,
|
|
11
|
+
// API errors
|
|
12
|
+
ApiError, ApiRequestError, InvalidResponseError,
|
|
13
|
+
// Parameter errors
|
|
14
|
+
MissingParameterError, InvalidParameterError, } from "./errors/error.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../../src/services/auth-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../../src/services/auth-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAS9C,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAoB;gBAGjD,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAoCnC,OAAO,KAAK,MAAM,GAEjB;IAED,UAAU,CAAC,MAAM,GAAE,MAAM,EAAO,GAAG,OAAO;IAgBpC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;CA0FrD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { jwtVerify } from "jose";
|
|
1
|
+
import { jwtVerify, errors as joseErrors } from "jose";
|
|
2
2
|
import { getJwks } from "../cache/jwks-cache.js";
|
|
3
|
+
import { InvalidParameterError, MissingParameterError, TokenExpiredError, InvalidTokenError, UnauthorizedGroupError, } from "../errors/error.js";
|
|
3
4
|
export class GatesAuthService {
|
|
4
5
|
region;
|
|
5
6
|
userPoolId;
|
|
@@ -7,21 +8,21 @@ export class GatesAuthService {
|
|
|
7
8
|
requiredGroup;
|
|
8
9
|
constructor(region, userPoolId, audience, requiredGroup) {
|
|
9
10
|
if (!region || typeof region !== "string" || region.trim().length === 0) {
|
|
10
|
-
throw new
|
|
11
|
+
throw new MissingParameterError("region");
|
|
11
12
|
}
|
|
12
13
|
if (!userPoolId ||
|
|
13
14
|
typeof userPoolId !== "string" ||
|
|
14
15
|
userPoolId.trim().length === 0) {
|
|
15
|
-
throw new
|
|
16
|
+
throw new MissingParameterError("userPoolId");
|
|
16
17
|
}
|
|
17
18
|
if (!audience ||
|
|
18
19
|
typeof audience !== "string" ||
|
|
19
20
|
audience.trim().length === 0) {
|
|
20
|
-
throw new
|
|
21
|
+
throw new MissingParameterError("audience");
|
|
21
22
|
}
|
|
22
23
|
// Validar formato do userPoolId (deve seguir padrão AWS)
|
|
23
24
|
if (!/^[a-zA-Z0-9_-]+$/.test(userPoolId)) {
|
|
24
|
-
throw new
|
|
25
|
+
throw new InvalidParameterError("userPoolId", "deve seguir o formato AWS (apenas alfanuméricos, hífens e underscores)");
|
|
25
26
|
}
|
|
26
27
|
this.region = region;
|
|
27
28
|
this.userPoolId = userPoolId;
|
|
@@ -45,36 +46,64 @@ export class GatesAuthService {
|
|
|
45
46
|
}
|
|
46
47
|
async verifyToken(token) {
|
|
47
48
|
if (!token) {
|
|
48
|
-
throw new
|
|
49
|
+
throw new MissingParameterError("token");
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
try {
|
|
52
|
+
const jwks = getJwks(this.region, this.userPoolId);
|
|
53
|
+
const { payload } = await jwtVerify(token, jwks, {
|
|
54
|
+
issuer: this.issuer,
|
|
55
|
+
audience: this.audience,
|
|
56
|
+
});
|
|
57
|
+
if (this.requiredGroup) {
|
|
58
|
+
const userGroups = payload["cognito:groups"];
|
|
59
|
+
const requiredGroups = Array.isArray(this.requiredGroup)
|
|
60
|
+
? this.requiredGroup
|
|
61
|
+
: [this.requiredGroup];
|
|
62
|
+
if (!userGroups || !Array.isArray(userGroups)) {
|
|
63
|
+
throw new UnauthorizedGroupError("Usuário não pertence a nenhum grupo obrigatório", requiredGroups);
|
|
64
|
+
}
|
|
65
|
+
// Verifica se o usuário tem pelo menos um dos grupos obrigatórios
|
|
66
|
+
const hasRequiredGroup = requiredGroups.some((group) => userGroups.includes(group));
|
|
67
|
+
if (!hasRequiredGroup) {
|
|
68
|
+
throw new UnauthorizedGroupError(`Usuário deve ser membro de um dos seguintes grupos: ${requiredGroups.join(", ")}`, requiredGroups);
|
|
69
|
+
}
|
|
59
70
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
// Mapear o payload do Cognito para o formato do GatesUser
|
|
72
|
+
const user = {
|
|
73
|
+
user_id: payload.sub,
|
|
74
|
+
email: payload.email,
|
|
75
|
+
name: payload.name,
|
|
76
|
+
role: payload["custom:general_role"],
|
|
77
|
+
exp: payload.exp,
|
|
78
|
+
iat: payload.iat,
|
|
79
|
+
};
|
|
80
|
+
return user;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
// Re-throw known errors
|
|
84
|
+
if (error instanceof UnauthorizedGroupError ||
|
|
85
|
+
error instanceof MissingParameterError) {
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
// Handle jose-specific errors
|
|
89
|
+
if (error instanceof joseErrors.JWTExpired) {
|
|
90
|
+
throw new TokenExpiredError("Token expirado");
|
|
91
|
+
}
|
|
92
|
+
if (error instanceof joseErrors.JWTInvalid) {
|
|
93
|
+
throw new InvalidTokenError("Token inválido ou malformado");
|
|
94
|
+
}
|
|
95
|
+
// Handle other jose errors
|
|
96
|
+
if (error instanceof Error) {
|
|
97
|
+
if (error.message.includes("expired")) {
|
|
98
|
+
throw new TokenExpiredError(error.message);
|
|
99
|
+
}
|
|
100
|
+
if (error.message.includes("signature") ||
|
|
101
|
+
error.message.includes("invalid")) {
|
|
102
|
+
throw new InvalidTokenError(error.message);
|
|
103
|
+
}
|
|
104
|
+
throw new InvalidTokenError(`Falha na verificação do token: ${error.message}`);
|
|
67
105
|
}
|
|
106
|
+
throw new InvalidTokenError("Falha na verificação do token");
|
|
68
107
|
}
|
|
69
|
-
// Mapear o payload do Cognito para o formato do GatesUser
|
|
70
|
-
const user = {
|
|
71
|
-
user_id: payload.sub,
|
|
72
|
-
email: payload.email,
|
|
73
|
-
name: payload.name,
|
|
74
|
-
role: payload["custom:general_role"],
|
|
75
|
-
exp: payload.exp,
|
|
76
|
-
iat: payload.iat,
|
|
77
|
-
};
|
|
78
|
-
return user;
|
|
79
108
|
}
|
|
80
109
|
}
|
|
@@ -27,9 +27,9 @@ export declare class GatesUserService {
|
|
|
27
27
|
getAllUsers(idToken: string): Promise<UserListResponse>;
|
|
28
28
|
/**
|
|
29
29
|
* Busca um usuário específico por ID
|
|
30
|
-
* @param
|
|
30
|
+
* @param idToken Token de autenticação
|
|
31
31
|
* @returns Dados do usuário
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
getProfile(idToken: string): Promise<UserProfile>;
|
|
34
34
|
}
|
|
35
35
|
//# sourceMappingURL=user-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-service.d.ts","sourceRoot":"","sources":["../../src/services/user-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"user-service.d.ts","sourceRoot":"","sources":["../../src/services/user-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,sBAAsB,CAAC;AAOrE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAeD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;gBAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAQ3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAExB;IAEF;;;;;OAKG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,GAEd,OAAO,CAAC,gBAAgB,CAAC;IAqE5B;;;;OAIG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAuExD"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MissingParameterError, ApiRequestError, InvalidResponseError, } from "../errors/error.js";
|
|
1
2
|
export class GatesUserService {
|
|
2
3
|
baseUrl;
|
|
3
4
|
system;
|
|
@@ -10,7 +11,7 @@ export class GatesUserService {
|
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
13
|
endpoints = {
|
|
13
|
-
all: "
|
|
14
|
+
all: "get-all-profiles-from-system",
|
|
14
15
|
};
|
|
15
16
|
/**
|
|
16
17
|
* Busca todos os usuários do Cognito através do backend
|
|
@@ -22,7 +23,7 @@ export class GatesUserService {
|
|
|
22
23
|
// options: GetAllUsersOptions = {}
|
|
23
24
|
) {
|
|
24
25
|
if (!idToken) {
|
|
25
|
-
throw new
|
|
26
|
+
throw new MissingParameterError("idToken");
|
|
26
27
|
}
|
|
27
28
|
try {
|
|
28
29
|
const queryParams = new URLSearchParams();
|
|
@@ -35,7 +36,7 @@ export class GatesUserService {
|
|
|
35
36
|
method: "POST",
|
|
36
37
|
headers: {
|
|
37
38
|
...this.defaultHeaders,
|
|
38
|
-
Authorization:
|
|
39
|
+
Authorization: `${idToken}`,
|
|
39
40
|
},
|
|
40
41
|
body: JSON.stringify({
|
|
41
42
|
system_name: this.system,
|
|
@@ -43,9 +44,12 @@ export class GatesUserService {
|
|
|
43
44
|
});
|
|
44
45
|
if (!response.ok) {
|
|
45
46
|
const errorText = await response.text();
|
|
46
|
-
throw new
|
|
47
|
+
throw new ApiRequestError(`Falha ao buscar usuários: ${errorText}`, response.status);
|
|
47
48
|
}
|
|
48
49
|
const data = (await response.json());
|
|
50
|
+
if (!data.profiles || !Array.isArray(data.profiles)) {
|
|
51
|
+
throw new InvalidResponseError("Resposta da API não contém o array 'profiles'");
|
|
52
|
+
}
|
|
49
53
|
// Adicionar total baseado no length se não vier da API
|
|
50
54
|
if (!data.total && data.profiles) {
|
|
51
55
|
data.total = data.profiles.length;
|
|
@@ -53,53 +57,69 @@ export class GatesUserService {
|
|
|
53
57
|
return data;
|
|
54
58
|
}
|
|
55
59
|
catch (error) {
|
|
60
|
+
// Re-throw known errors
|
|
61
|
+
if (error instanceof MissingParameterError ||
|
|
62
|
+
error instanceof ApiRequestError ||
|
|
63
|
+
error instanceof InvalidResponseError) {
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
// Handle fetch errors
|
|
56
67
|
if (error instanceof Error) {
|
|
57
|
-
throw new
|
|
68
|
+
throw new ApiRequestError(`Falha ao buscar usuários: ${error.message}`);
|
|
58
69
|
}
|
|
59
|
-
throw new
|
|
70
|
+
throw new ApiRequestError("Falha ao buscar usuários: Erro desconhecido");
|
|
60
71
|
}
|
|
61
72
|
}
|
|
62
73
|
/**
|
|
63
74
|
* Busca um usuário específico por ID
|
|
64
|
-
* @param
|
|
75
|
+
* @param idToken Token de autenticação
|
|
65
76
|
* @returns Dados do usuário
|
|
66
77
|
*/
|
|
67
|
-
async
|
|
68
|
-
if (!
|
|
69
|
-
throw new
|
|
78
|
+
async getProfile(idToken) {
|
|
79
|
+
if (!idToken) {
|
|
80
|
+
throw new MissingParameterError("idToken");
|
|
70
81
|
}
|
|
71
82
|
try {
|
|
72
|
-
const response = await fetch(`${this.baseUrl}/
|
|
73
|
-
method: "
|
|
83
|
+
const response = await fetch(`${this.baseUrl}/get-profile?system_name=${this.system}`, {
|
|
84
|
+
method: "GET",
|
|
74
85
|
headers: {
|
|
75
86
|
...this.defaultHeaders,
|
|
76
|
-
Authorization: `${
|
|
87
|
+
Authorization: `${idToken}`,
|
|
77
88
|
},
|
|
78
|
-
body: JSON.stringify({ system_name: this.system }),
|
|
79
89
|
});
|
|
80
90
|
if (!response.ok) {
|
|
81
91
|
const errorText = await response.text();
|
|
82
|
-
throw new
|
|
92
|
+
throw new ApiRequestError(`Falha ao buscar perfil do usuário: ${errorText}`, response.status);
|
|
83
93
|
}
|
|
84
94
|
const data = (await response.json());
|
|
85
|
-
// A API retorna {
|
|
86
|
-
if (!data.
|
|
87
|
-
throw new
|
|
95
|
+
// A API retorna { profile: {...}, email: ..., name: ..., message: "..." }
|
|
96
|
+
if (!data.profile) {
|
|
97
|
+
throw new InvalidResponseError("Resposta da API não contém os dados do 'profile'");
|
|
98
|
+
}
|
|
99
|
+
if (!data.email || !data.name) {
|
|
100
|
+
throw new InvalidResponseError("Resposta da API não contém os campos obrigatórios do usuário (email ou name)");
|
|
88
101
|
}
|
|
89
102
|
const userProfile = {
|
|
90
|
-
user_id: data.
|
|
91
|
-
email: data.
|
|
92
|
-
name: data.
|
|
93
|
-
enabled: data.
|
|
94
|
-
profile_attributes: data.
|
|
103
|
+
user_id: data.profile.user_id,
|
|
104
|
+
email: data.email,
|
|
105
|
+
name: data.name,
|
|
106
|
+
enabled: data.profile.enabled,
|
|
107
|
+
profile_attributes: data.profile.profile_attributes || [],
|
|
95
108
|
};
|
|
96
109
|
return userProfile;
|
|
97
110
|
}
|
|
98
111
|
catch (error) {
|
|
112
|
+
// Re-throw known errors
|
|
113
|
+
if (error instanceof MissingParameterError ||
|
|
114
|
+
error instanceof ApiRequestError ||
|
|
115
|
+
error instanceof InvalidResponseError) {
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
// Handle fetch errors
|
|
99
119
|
if (error instanceof Error) {
|
|
100
|
-
throw new
|
|
120
|
+
throw new ApiRequestError(`Falha ao buscar perfil do usuário: ${error.message}`);
|
|
101
121
|
}
|
|
102
|
-
throw new
|
|
122
|
+
throw new ApiRequestError("Falha ao buscar perfil do usuário: Erro desconhecido");
|
|
103
123
|
}
|
|
104
124
|
}
|
|
105
125
|
}
|