@temboplus/afloat 0.1.12 → 0.1.30
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 +120 -2
- package/esm/src/features/auth/access/contract.d.ts +14 -0
- package/esm/src/features/auth/access/contract.d.ts.map +1 -0
- package/esm/src/features/auth/access/contract.js +14 -0
- package/esm/src/features/auth/contract.d.ts +20 -20
- package/esm/src/features/auth/contract.js +2 -2
- package/esm/src/features/auth/identity/contract.d.ts +0 -7
- package/esm/src/features/auth/identity/contract.d.ts.map +1 -1
- package/esm/src/features/auth/identity/contract.js +0 -1
- package/esm/src/features/auth/identity/repository.d.ts +2 -2
- package/esm/src/features/auth/identity/repository.d.ts.map +1 -1
- package/esm/src/features/auth/identity/repository.js +5 -5
- package/esm/src/features/auth/manager.js +1 -1
- package/esm/src/features/auth/profile/contract.d.ts +17 -25
- package/esm/src/features/auth/profile/contract.d.ts.map +1 -1
- package/esm/src/features/auth/profile/contract.js +2 -4
- package/esm/src/features/auth/repository.d.ts +0 -1
- package/esm/src/features/auth/repository.d.ts.map +1 -1
- package/esm/src/features/auth/repository.js +3 -11
- package/esm/src/features/auth/storage/server_token_handler.d.ts +7 -6
- package/esm/src/features/auth/storage/server_token_handler.d.ts.map +1 -1
- package/esm/src/features/auth/storage/server_token_handler.js +73 -26
- package/esm/src/features/contact/contract.d.ts +10 -10
- package/esm/src/features/payout/contract.d.ts +12 -12
- package/esm/src/features/wallet/repository.d.ts +1 -28
- package/esm/src/features/wallet/repository.d.ts.map +1 -1
- package/esm/src/features/wallet/repository.js +0 -51
- package/esm/src/models/contact/derivatives/contact.js +2 -2
- package/esm/src/models/contact/derivatives/contact_info.d.ts +8 -8
- package/esm/src/models/contact/derivatives/contact_info.d.ts.map +1 -1
- package/esm/src/models/contact/derivatives/contact_info.js +12 -12
- package/esm/src/models/payout/channel.d.ts +4 -4
- package/esm/src/models/payout/channel.d.ts.map +1 -1
- package/esm/src/models/payout/channel.js +2 -2
- package/esm/src/models/payout/derivatives/payout.d.ts.map +1 -1
- package/esm/src/models/payout/derivatives/payout.js +2 -2
- package/esm/src/models/user/profile.d.ts +135 -12
- package/esm/src/models/user/profile.d.ts.map +1 -1
- package/esm/src/models/user/profile.js +318 -12
- package/esm/src/models/user/user.d.ts +14 -17
- package/esm/src/models/user/user.d.ts.map +1 -1
- package/esm/src/models/user/user.js +109 -26
- package/esm/src/models/wallet/index.d.ts +0 -1
- package/esm/src/models/wallet/index.d.ts.map +1 -1
- package/esm/src/models/wallet/index.js +0 -1
- package/esm/src/shared/token_required_repository.d.ts +78 -0
- package/esm/src/shared/token_required_repository.d.ts.map +1 -0
- package/esm/src/shared/token_required_repository.js +128 -0
- package/package.json +7 -7
- package/script/src/features/auth/access/contract.d.ts +14 -0
- package/script/src/features/auth/access/contract.d.ts.map +1 -0
- package/script/src/features/auth/access/contract.js +17 -0
- package/script/src/features/auth/contract.d.ts +20 -20
- package/script/src/features/auth/contract.js +1 -1
- package/script/src/features/auth/identity/contract.d.ts +0 -7
- package/script/src/features/auth/identity/contract.d.ts.map +1 -1
- package/script/src/features/auth/identity/contract.js +0 -1
- package/script/src/features/auth/identity/repository.d.ts +2 -2
- package/script/src/features/auth/identity/repository.d.ts.map +1 -1
- package/script/src/features/auth/identity/repository.js +5 -5
- package/script/src/features/auth/manager.js +1 -1
- package/script/src/features/auth/profile/contract.d.ts +17 -25
- package/script/src/features/auth/profile/contract.d.ts.map +1 -1
- package/script/src/features/auth/profile/contract.js +1 -3
- package/script/src/features/auth/repository.d.ts +0 -1
- package/script/src/features/auth/repository.d.ts.map +1 -1
- package/script/src/features/auth/repository.js +3 -11
- package/script/src/features/auth/storage/server_token_handler.d.ts +7 -6
- package/script/src/features/auth/storage/server_token_handler.d.ts.map +1 -1
- package/script/src/features/auth/storage/server_token_handler.js +72 -25
- package/script/src/features/contact/contract.d.ts +10 -10
- package/script/src/features/payout/contract.d.ts +12 -12
- package/script/src/features/wallet/repository.d.ts +1 -28
- package/script/src/features/wallet/repository.d.ts.map +1 -1
- package/script/src/features/wallet/repository.js +0 -51
- package/script/src/models/contact/derivatives/contact.js +1 -1
- package/script/src/models/contact/derivatives/contact_info.d.ts +8 -8
- package/script/src/models/contact/derivatives/contact_info.d.ts.map +1 -1
- package/script/src/models/contact/derivatives/contact_info.js +11 -11
- package/script/src/models/payout/channel.d.ts +4 -4
- package/script/src/models/payout/channel.d.ts.map +1 -1
- package/script/src/models/payout/channel.js +2 -2
- package/script/src/models/payout/derivatives/payout.d.ts.map +1 -1
- package/script/src/models/payout/derivatives/payout.js +1 -1
- package/script/src/models/user/profile.d.ts +135 -12
- package/script/src/models/user/profile.d.ts.map +1 -1
- package/script/src/models/user/profile.js +320 -13
- package/script/src/models/user/user.d.ts +14 -17
- package/script/src/models/user/user.d.ts.map +1 -1
- package/script/src/models/user/user.js +109 -26
- package/script/src/models/wallet/index.d.ts +0 -1
- package/script/src/models/wallet/index.d.ts.map +1 -1
- package/script/src/models/wallet/index.js +0 -1
- package/script/src/shared/token_required_repository.d.ts +78 -0
- package/script/src/shared/token_required_repository.d.ts.map +1 -0
- package/script/src/shared/token_required_repository.js +132 -0
- package/esm/src/features/auth/profile/repository.d.ts +0 -11
- package/esm/src/features/auth/profile/repository.d.ts.map +0 -1
- package/esm/src/features/auth/profile/repository.js +0 -21
- package/esm/src/features/files-gen/contract.d.ts +0 -67
- package/esm/src/features/files-gen/contract.d.ts.map +0 -1
- package/esm/src/features/files-gen/contract.js +0 -40
- package/esm/src/features/files-gen/repository.d.ts +0 -50
- package/esm/src/features/files-gen/repository.d.ts.map +0 -1
- package/esm/src/features/files-gen/repository.js +0 -56
- package/esm/src/models/wallet/statement.d.ts +0 -27
- package/esm/src/models/wallet/statement.d.ts.map +0 -1
- package/esm/src/models/wallet/statement.js +0 -13
- package/script/src/features/auth/profile/repository.d.ts +0 -11
- package/script/src/features/auth/profile/repository.d.ts.map +0 -1
- package/script/src/features/auth/profile/repository.js +0 -25
- package/script/src/features/files-gen/contract.d.ts +0 -67
- package/script/src/features/files-gen/contract.d.ts.map +0 -1
- package/script/src/features/files-gen/contract.js +0 -43
- package/script/src/features/files-gen/repository.d.ts +0 -50
- package/script/src/features/files-gen/repository.d.ts.map +0 -1
- package/script/src/features/files-gen/repository.js +0 -60
- package/script/src/models/wallet/statement.d.ts +0 -27
- package/script/src/models/wallet/statement.d.ts.map +0 -1
- package/script/src/models/wallet/statement.js +0 -16
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ This JavaScript/TypeScript package provides a central hub for shared utilities,
|
|
|
8
8
|
|
|
9
9
|
* **Abstracted Server Communication**
|
|
10
10
|
* Simplifies front-end development by abstracting all interactions with the server behind model-specific repositories
|
|
11
|
-
*
|
|
11
|
+
* Consuming projects only need to interact with these repositories, decoupling them from the underlying API implementation
|
|
12
12
|
|
|
13
13
|
* **Shared Utilities**
|
|
14
14
|
* Provides a collection of reusable helper functions for common tasks across Afloat projects, such as error handling
|
|
@@ -18,4 +18,122 @@ This JavaScript/TypeScript package provides a central hub for shared utilities,
|
|
|
18
18
|
|
|
19
19
|
* **Enhanced Maintainability**
|
|
20
20
|
* Centralizes common logic, making it easier to maintain and update across all consuming projects
|
|
21
|
-
* Reduces code duplication and improves consistency
|
|
21
|
+
* Reduces code duplication and improves consistency
|
|
22
|
+
|
|
23
|
+
* **Cross-Environment Compatibility**
|
|
24
|
+
* Works seamlessly in both client-side and server-side environments
|
|
25
|
+
* Supports both synchronous and asynchronous initialization patterns
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Authentication Setup
|
|
30
|
+
|
|
31
|
+
#### Client-Side Usage
|
|
32
|
+
|
|
33
|
+
In client-side applications, authentication is initialized synchronously:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { AfloatAuth } from "@temboplus/afloat";
|
|
37
|
+
|
|
38
|
+
// Initialize client auth (typically in your app entry point)
|
|
39
|
+
const auth = AfloatAuth.instance;
|
|
40
|
+
|
|
41
|
+
// Check if user is authenticated
|
|
42
|
+
console.log("User authenticated:", !!auth.currentUser);
|
|
43
|
+
|
|
44
|
+
// Access current user
|
|
45
|
+
const user = auth.currentUser;
|
|
46
|
+
if (user) {
|
|
47
|
+
console.log(`Logged in as: ${user.email}`);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### Server-Side Usage
|
|
52
|
+
|
|
53
|
+
In server-side environments, authentication requires asynchronous initialization:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { AfloatAuth } from "@temboplus/afloat";
|
|
57
|
+
|
|
58
|
+
// In a server route handler or similar context
|
|
59
|
+
async function handleRequest(req, res) {
|
|
60
|
+
try {
|
|
61
|
+
// Extract token from request
|
|
62
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
63
|
+
|
|
64
|
+
if (!token) {
|
|
65
|
+
return res.status(401).json({ error: 'Unauthorized' });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Initialize server-side auth
|
|
69
|
+
const auth = await AfloatAuth.initializeServer(token);
|
|
70
|
+
|
|
71
|
+
// Now you can use auth for permission checks
|
|
72
|
+
const isAdmin = auth.checkPermission(Permissions.Payout.View);
|
|
73
|
+
|
|
74
|
+
// Continue with your handler logic...
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error('Authentication error:', error);
|
|
77
|
+
return res.status(500).json({ error: 'Authentication failed' });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Using Repositories
|
|
83
|
+
|
|
84
|
+
Repositories provide a consistent interface for data operations across environments.
|
|
85
|
+
|
|
86
|
+
#### Client-Side Repository Usage
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { WalletRepo } from "@temboplus/afloat";
|
|
90
|
+
|
|
91
|
+
// Create repository - auth is automatically handled
|
|
92
|
+
const walletRepo = new WalletRepo();
|
|
93
|
+
|
|
94
|
+
// Use repository methods
|
|
95
|
+
async function displayBalance() {
|
|
96
|
+
try {
|
|
97
|
+
const balance = await walletRepo.getBalance();
|
|
98
|
+
console.log(`Current balance: ${balance}`);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('Error fetching balance:', error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### Server-Side Repository Usage
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { AfloatAuth, WalletRepo } from "@temboplus/afloat";
|
|
109
|
+
|
|
110
|
+
async function processServerRequest(token) {
|
|
111
|
+
// Initialize auth for this request
|
|
112
|
+
const auth = await AfloatAuth.initializeServer(token);
|
|
113
|
+
|
|
114
|
+
// Create repository with explicit auth instance
|
|
115
|
+
const walletRepo = new WalletRepo({ auth });
|
|
116
|
+
|
|
117
|
+
// Use repository methods
|
|
118
|
+
const balance = await walletRepo.getBalance();
|
|
119
|
+
const wallets = await walletRepo.getWallets();
|
|
120
|
+
|
|
121
|
+
return { balance, wallets };
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Best Practices
|
|
126
|
+
|
|
127
|
+
1. **Client-Side Applications**
|
|
128
|
+
- Initialize `AfloatAuth.instance` early in your application lifecycle
|
|
129
|
+
- Create repositories without explicit auth parameters
|
|
130
|
+
- Handle permission errors appropriately in your UI
|
|
131
|
+
|
|
132
|
+
2. **Server-Side Applications**
|
|
133
|
+
- Always use `await AfloatAuth.initializeServer(token)` for each request
|
|
134
|
+
- Pass the auth instance explicitly to repositories
|
|
135
|
+
- Implement proper error handling for authentication failures
|
|
136
|
+
|
|
137
|
+
3. **Testing**
|
|
138
|
+
- Use the `AuthContext` to inject mock auth instances during testing
|
|
139
|
+
- Reset `AuthContext.current` after each test to prevent test pollution
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Auth API contract
|
|
4
|
+
*/
|
|
5
|
+
export declare const accessContract: {
|
|
6
|
+
getAccessList: {
|
|
7
|
+
method: "GET";
|
|
8
|
+
path: "/access";
|
|
9
|
+
responses: {
|
|
10
|
+
200: z.ZodArray<z.ZodString, "many">;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/access/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;CAQzB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { initContract } from "@ts-rest/core";
|
|
3
|
+
/**
|
|
4
|
+
* Auth API contract
|
|
5
|
+
*/
|
|
6
|
+
export const accessContract = initContract().router({
|
|
7
|
+
getAccessList: {
|
|
8
|
+
method: "GET",
|
|
9
|
+
path: "/access",
|
|
10
|
+
responses: {
|
|
11
|
+
200: z.string().array(),
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -23,28 +23,28 @@ export declare const authContract: {
|
|
|
23
23
|
201: z.ZodObject<{
|
|
24
24
|
profile: z.ZodObject<{
|
|
25
25
|
id: z.ZodString;
|
|
26
|
-
firstName: z.ZodString
|
|
27
|
-
lastName: z.ZodString
|
|
26
|
+
firstName: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
27
|
+
lastName: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
28
28
|
displayName: z.ZodString;
|
|
29
|
-
phone: z.ZodString
|
|
29
|
+
phone: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
30
30
|
accountNo: z.ZodString;
|
|
31
|
-
email: z.ZodString
|
|
31
|
+
email: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
32
32
|
}, z.UnknownKeysParam, z.ZodTypeAny, {
|
|
33
33
|
id: string;
|
|
34
|
-
firstName: string;
|
|
35
|
-
lastName: string;
|
|
36
34
|
displayName: string;
|
|
37
|
-
phone: string;
|
|
38
35
|
accountNo: string;
|
|
39
|
-
|
|
36
|
+
firstName?: string | null | undefined;
|
|
37
|
+
lastName?: string | null | undefined;
|
|
38
|
+
phone?: string | null | undefined;
|
|
39
|
+
email?: string | null | undefined;
|
|
40
40
|
}, {
|
|
41
41
|
id: string;
|
|
42
|
-
firstName: string;
|
|
43
|
-
lastName: string;
|
|
44
42
|
displayName: string;
|
|
45
|
-
phone: string;
|
|
46
43
|
accountNo: string;
|
|
47
|
-
|
|
44
|
+
firstName?: string | null | undefined;
|
|
45
|
+
lastName?: string | null | undefined;
|
|
46
|
+
phone?: string | null | undefined;
|
|
47
|
+
email?: string | null | undefined;
|
|
48
48
|
}>;
|
|
49
49
|
token: z.ZodString;
|
|
50
50
|
access: z.ZodArray<z.ZodString, "many">;
|
|
@@ -53,12 +53,12 @@ export declare const authContract: {
|
|
|
53
53
|
resetPassword: boolean;
|
|
54
54
|
profile: {
|
|
55
55
|
id: string;
|
|
56
|
-
firstName: string;
|
|
57
|
-
lastName: string;
|
|
58
56
|
displayName: string;
|
|
59
|
-
phone: string;
|
|
60
57
|
accountNo: string;
|
|
61
|
-
|
|
58
|
+
firstName?: string | null | undefined;
|
|
59
|
+
lastName?: string | null | undefined;
|
|
60
|
+
phone?: string | null | undefined;
|
|
61
|
+
email?: string | null | undefined;
|
|
62
62
|
};
|
|
63
63
|
token: string;
|
|
64
64
|
access: string[];
|
|
@@ -66,12 +66,12 @@ export declare const authContract: {
|
|
|
66
66
|
resetPassword: boolean;
|
|
67
67
|
profile: {
|
|
68
68
|
id: string;
|
|
69
|
-
firstName: string;
|
|
70
|
-
lastName: string;
|
|
71
69
|
displayName: string;
|
|
72
|
-
phone: string;
|
|
73
70
|
accountNo: string;
|
|
74
|
-
|
|
71
|
+
firstName?: string | null | undefined;
|
|
72
|
+
lastName?: string | null | undefined;
|
|
73
|
+
phone?: string | null | undefined;
|
|
74
|
+
email?: string | null | undefined;
|
|
75
75
|
};
|
|
76
76
|
token: string;
|
|
77
77
|
access: string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { initContract } from "@ts-rest/core";
|
|
3
|
-
import {
|
|
3
|
+
import { Profile } from "../../models/index.js";
|
|
4
4
|
/**
|
|
5
5
|
* Auth API contract
|
|
6
6
|
*/
|
|
@@ -15,7 +15,7 @@ export const authContract = initContract().router({
|
|
|
15
15
|
}),
|
|
16
16
|
responses: {
|
|
17
17
|
201: z.object({
|
|
18
|
-
profile:
|
|
18
|
+
profile: Profile.schema,
|
|
19
19
|
token: z.string(),
|
|
20
20
|
access: z.array(z.string()),
|
|
21
21
|
resetPassword: z.boolean(),
|
|
@@ -6,13 +6,6 @@ export declare const identityContract: {
|
|
|
6
6
|
getUserCredentials: {
|
|
7
7
|
method: "GET";
|
|
8
8
|
path: "/me";
|
|
9
|
-
headers: z.ZodObject<{
|
|
10
|
-
token: z.ZodString;
|
|
11
|
-
}, "strip", z.ZodTypeAny, {
|
|
12
|
-
token: string;
|
|
13
|
-
}, {
|
|
14
|
-
token: string;
|
|
15
|
-
}>;
|
|
16
9
|
responses: {
|
|
17
10
|
200: z.ZodObject<{
|
|
18
11
|
name: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/identity/contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/identity/contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;CAW3B,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { BaseRepository } from "../../../shared/index.js";
|
|
2
1
|
import { identityContract } from "./contract.js";
|
|
3
2
|
import type { ClientInferResponseBody } from "@ts-rest/core";
|
|
3
|
+
import { TokenRequiredRepository } from "../../../shared/token_required_repository.js";
|
|
4
4
|
type GetUserIdentityResponse = ClientInferResponseBody<typeof identityContract.getUserCredentials>;
|
|
5
5
|
/**
|
|
6
6
|
* Class representing the LoginRepository.
|
|
7
7
|
* Provides methods to retrieve user identity-related information.
|
|
8
8
|
*/
|
|
9
|
-
export declare class LoginRepository extends
|
|
9
|
+
export declare class LoginRepository extends TokenRequiredRepository<typeof identityContract> {
|
|
10
10
|
/**
|
|
11
11
|
* Initializes an instance of LoginRepository.
|
|
12
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/identity/repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/identity/repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAEvF,KAAK,uBAAuB,GAAG,uBAAuB,CACpD,OAAO,gBAAgB,CAAC,kBAAkB,CAC3C,CAAC;AAEF;;;GAGG;AACH,qBAAa,eACX,SAAQ,uBAAuB,CAAC,OAAO,gBAAgB,CAAC;IACxD;;OAEG;;IAKH;;;;OAIG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;CAUnE"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { APIError } from "../../../errors/api_error.js";
|
|
2
|
-
import { BaseRepository } from "../../../shared/index.js";
|
|
3
2
|
import { identityContract } from "./contract.js";
|
|
3
|
+
import { TokenRequiredRepository } from "../../../shared/token_required_repository.js";
|
|
4
4
|
/**
|
|
5
5
|
* Class representing the LoginRepository.
|
|
6
6
|
* Provides methods to retrieve user identity-related information.
|
|
7
7
|
*/
|
|
8
|
-
export class LoginRepository extends
|
|
8
|
+
export class LoginRepository extends TokenRequiredRepository {
|
|
9
9
|
/**
|
|
10
10
|
* Initializes an instance of LoginRepository.
|
|
11
11
|
*/
|
|
12
12
|
constructor() {
|
|
13
|
-
super("login", identityContract);
|
|
13
|
+
super("login", identityContract, "");
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Retrieves the user's login credentials.
|
|
@@ -18,8 +18,8 @@ export class LoginRepository extends BaseRepository {
|
|
|
18
18
|
* @throws {APIError} If an error occurs while retrieving the credentials.
|
|
19
19
|
*/
|
|
20
20
|
async getIdentity(token) {
|
|
21
|
-
|
|
22
|
-
const result = await this.client.getUserCredentials(
|
|
21
|
+
this.setToken(token);
|
|
22
|
+
const result = await this.client.getUserCredentials();
|
|
23
23
|
if (result.status === 200)
|
|
24
24
|
return result.body;
|
|
25
25
|
throw new APIError({
|
|
@@ -77,7 +77,7 @@ export class AfloatAuth {
|
|
|
77
77
|
const store = new ServerStore();
|
|
78
78
|
try {
|
|
79
79
|
// Fetch and construct user data
|
|
80
|
-
const user = await tokenHandler.constructUser();
|
|
80
|
+
const user = await tokenHandler.constructUser(token);
|
|
81
81
|
store.setUser(user);
|
|
82
82
|
// Create and initialize auth instance
|
|
83
83
|
const auth = new AfloatAuth(store, tokenHandler);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
1
|
/**
|
|
3
2
|
* Profile API contract
|
|
4
3
|
*/
|
|
@@ -6,38 +5,31 @@ export declare const profileContract: {
|
|
|
6
5
|
getCurrentProfile: {
|
|
7
6
|
method: "GET";
|
|
8
7
|
path: "/me";
|
|
9
|
-
headers: z.ZodObject<{
|
|
10
|
-
token: z.ZodString;
|
|
11
|
-
}, "strip", z.ZodTypeAny, {
|
|
12
|
-
token: string;
|
|
13
|
-
}, {
|
|
14
|
-
token: string;
|
|
15
|
-
}>;
|
|
16
8
|
responses: {
|
|
17
|
-
200:
|
|
18
|
-
id:
|
|
19
|
-
firstName:
|
|
20
|
-
lastName:
|
|
21
|
-
displayName:
|
|
22
|
-
phone:
|
|
23
|
-
accountNo:
|
|
24
|
-
email:
|
|
25
|
-
},
|
|
9
|
+
200: import("zod").ZodObject<{
|
|
10
|
+
id: import("zod").ZodString;
|
|
11
|
+
firstName: import("zod").ZodNullable<import("zod").ZodOptional<import("zod").ZodString>>;
|
|
12
|
+
lastName: import("zod").ZodNullable<import("zod").ZodOptional<import("zod").ZodString>>;
|
|
13
|
+
displayName: import("zod").ZodString;
|
|
14
|
+
phone: import("zod").ZodNullable<import("zod").ZodOptional<import("zod").ZodString>>;
|
|
15
|
+
accountNo: import("zod").ZodString;
|
|
16
|
+
email: import("zod").ZodNullable<import("zod").ZodOptional<import("zod").ZodString>>;
|
|
17
|
+
}, import("zod").UnknownKeysParam, import("zod").ZodTypeAny, {
|
|
26
18
|
id: string;
|
|
27
|
-
firstName: string;
|
|
28
|
-
lastName: string;
|
|
29
19
|
displayName: string;
|
|
30
|
-
phone: string;
|
|
31
20
|
accountNo: string;
|
|
32
|
-
|
|
21
|
+
firstName?: string | null | undefined;
|
|
22
|
+
lastName?: string | null | undefined;
|
|
23
|
+
phone?: string | null | undefined;
|
|
24
|
+
email?: string | null | undefined;
|
|
33
25
|
}, {
|
|
34
26
|
id: string;
|
|
35
|
-
firstName: string;
|
|
36
|
-
lastName: string;
|
|
37
27
|
displayName: string;
|
|
38
|
-
phone: string;
|
|
39
28
|
accountNo: string;
|
|
40
|
-
|
|
29
|
+
firstName?: string | null | undefined;
|
|
30
|
+
lastName?: string | null | undefined;
|
|
31
|
+
phone?: string | null | undefined;
|
|
32
|
+
email?: string | null | undefined;
|
|
41
33
|
}>;
|
|
42
34
|
};
|
|
43
35
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/profile/contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/profile/contract.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQ1B,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { initContract } from "@ts-rest/core";
|
|
2
|
-
import {
|
|
3
|
-
import { z } from "zod";
|
|
2
|
+
import { Profile } from "../../../models/index.js";
|
|
4
3
|
/**
|
|
5
4
|
* Profile API contract
|
|
6
5
|
*/
|
|
@@ -8,9 +7,8 @@ export const profileContract = initContract().router({
|
|
|
8
7
|
getCurrentProfile: {
|
|
9
8
|
method: "GET",
|
|
10
9
|
path: "/me",
|
|
11
|
-
headers: z.object({ token: z.string() }),
|
|
12
10
|
responses: {
|
|
13
|
-
200:
|
|
11
|
+
200: Profile.schema,
|
|
14
12
|
},
|
|
15
13
|
},
|
|
16
14
|
});
|
|
@@ -26,6 +26,5 @@ export declare class AuthRepository extends BaseRepository<typeof authContract>
|
|
|
26
26
|
* @throws {APIError} If the current password is invalid or another error occurs during the update process.
|
|
27
27
|
*/
|
|
28
28
|
updatePassword(currentPassword: string, newPassword: string): Promise<boolean>;
|
|
29
|
-
getAccessList(token: string): Promise<string[]>;
|
|
30
29
|
}
|
|
31
30
|
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../src/src/features/auth/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAI7C;;;GAGG;AACH,qBAAa,cAAe,SAAQ,cAAc,CAAC,OAAO,YAAY,CAAC;IACrE;;OAEG;;IAKH;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../src/src/features/auth/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAI7C;;;GAGG;AACH,qBAAa,cAAe,SAAQ,cAAc,CAAC,OAAO,YAAY,CAAC;IACrE;;OAEG;;IAKH;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB3D;;;;;;OAMG;IACG,cAAc,CAClB,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC;CAiBpB"}
|
|
@@ -33,8 +33,9 @@ export class AuthRepository extends BaseRepository {
|
|
|
33
33
|
if (result.status === 201) {
|
|
34
34
|
const repo = new LoginRepository();
|
|
35
35
|
const loginCredentials = await repo.getIdentity(result.body.token);
|
|
36
|
-
const user =
|
|
37
|
-
|
|
36
|
+
const user = User.from({ ...result.body, ...loginCredentials });
|
|
37
|
+
if (user)
|
|
38
|
+
return user;
|
|
38
39
|
}
|
|
39
40
|
throw new APIError({
|
|
40
41
|
message: "An error occurred while trying to log in",
|
|
@@ -65,13 +66,4 @@ export class AuthRepository extends BaseRepository {
|
|
|
65
66
|
statusCode: 502,
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
|
-
async getAccessList(token) {
|
|
69
|
-
const result = await this.client.access({ headers: { token: token } });
|
|
70
|
-
if (result.status === 200)
|
|
71
|
-
return result.body;
|
|
72
|
-
throw new APIError({
|
|
73
|
-
message: "An error occurred while trying to get access list",
|
|
74
|
-
statusCode: 502,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
69
|
}
|
|
@@ -3,15 +3,19 @@ import { User } from "../../../models/index.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Server-side implementation of TokenHandler.
|
|
5
5
|
* Manages tokens in memory for the duration of a request.
|
|
6
|
+
* Uses TokenRequiredRepository instead of repositories that rely on AfloatAuth.
|
|
6
7
|
* @implements {TokenHandler}
|
|
7
8
|
*/
|
|
8
9
|
export declare class ServerTokenHandler implements TokenHandler {
|
|
9
|
-
private token
|
|
10
|
+
private token;
|
|
11
|
+
private accessRepo;
|
|
12
|
+
private profileRepo;
|
|
13
|
+
private identityRepo;
|
|
10
14
|
/**
|
|
11
15
|
* Creates a new instance of ServerTokenHandler.
|
|
12
16
|
* @param {string} [token] - Optional initial token value
|
|
13
17
|
*/
|
|
14
|
-
constructor(token
|
|
18
|
+
constructor(token: string);
|
|
15
19
|
/**
|
|
16
20
|
* Returns the stored token.
|
|
17
21
|
* @returns {string | undefined} The current token or undefined if not set
|
|
@@ -22,14 +26,11 @@ export declare class ServerTokenHandler implements TokenHandler {
|
|
|
22
26
|
* @param {string} token - The token to store
|
|
23
27
|
*/
|
|
24
28
|
setUserToken(token: string): void;
|
|
25
|
-
/**
|
|
26
|
-
* Clears the stored token from memory.
|
|
27
|
-
*/
|
|
28
29
|
clearToken(): void;
|
|
29
30
|
/**
|
|
30
31
|
* Fetches and constructs the full user data
|
|
31
32
|
* @returns {Promise<User>}
|
|
32
33
|
*/
|
|
33
|
-
constructUser(): Promise<User>;
|
|
34
|
+
constructUser(token: string): Promise<User>;
|
|
34
35
|
}
|
|
35
36
|
//# sourceMappingURL=server_token_handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server_token_handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/storage/server_token_handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,
|
|
1
|
+
{"version":3,"file":"server_token_handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/features/auth/storage/server_token_handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAW,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAMzD;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAiD;IACnE,OAAO,CAAC,WAAW,CAAkD;IACrE,OAAO,CAAC,YAAY,CAAmD;IAEvE;;;OAGG;gBACS,KAAK,EAAE,MAAM;IAqBzB;;;OAGG;IACH,YAAY,IAAI,MAAM,GAAG,SAAS;IAIlC;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAOjC,UAAU,IAAI,IAAI;IAOlB;;;OAGG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAoDlD"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { User } from "../../../models/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { Profile, User } from "../../../models/index.js";
|
|
2
|
+
import { profileContract } from "../profile/contract.js";
|
|
3
|
+
import { identityContract } from "../identity/contract.js";
|
|
4
|
+
import { TokenRequiredRepository } from "../../../shared/token_required_repository.js";
|
|
5
|
+
import { accessContract } from "../access/contract.js";
|
|
5
6
|
/**
|
|
6
7
|
* Server-side implementation of TokenHandler.
|
|
7
8
|
* Manages tokens in memory for the duration of a request.
|
|
9
|
+
* Uses TokenRequiredRepository instead of repositories that rely on AfloatAuth.
|
|
8
10
|
* @implements {TokenHandler}
|
|
9
11
|
*/
|
|
10
12
|
export class ServerTokenHandler {
|
|
@@ -17,8 +19,30 @@ export class ServerTokenHandler {
|
|
|
17
19
|
enumerable: true,
|
|
18
20
|
configurable: true,
|
|
19
21
|
writable: true,
|
|
20
|
-
value:
|
|
22
|
+
value: void 0
|
|
21
23
|
});
|
|
24
|
+
Object.defineProperty(this, "accessRepo", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
writable: true,
|
|
28
|
+
value: void 0
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(this, "profileRepo", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: void 0
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(this, "identityRepo", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: void 0
|
|
41
|
+
});
|
|
42
|
+
this.token = token;
|
|
43
|
+
this.accessRepo = new TokenRequiredRepository("auth", accessContract, this.token);
|
|
44
|
+
this.profileRepo = new TokenRequiredRepository("profile", profileContract, this.token);
|
|
45
|
+
this.identityRepo = new TokenRequiredRepository("login", identityContract, this.token);
|
|
22
46
|
}
|
|
23
47
|
/**
|
|
24
48
|
* Returns the stored token.
|
|
@@ -33,36 +57,59 @@ export class ServerTokenHandler {
|
|
|
33
57
|
*/
|
|
34
58
|
setUserToken(token) {
|
|
35
59
|
this.token = token;
|
|
60
|
+
this.accessRepo.setToken(token);
|
|
61
|
+
this.profileRepo.setToken(token);
|
|
62
|
+
this.identityRepo.setToken(token);
|
|
36
63
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Clears the stored token from memory.
|
|
39
|
-
*/
|
|
40
64
|
clearToken() {
|
|
41
|
-
this.token =
|
|
65
|
+
this.token = "";
|
|
66
|
+
this.accessRepo.setToken("");
|
|
67
|
+
this.profileRepo.setToken("");
|
|
68
|
+
this.identityRepo.setToken("");
|
|
42
69
|
}
|
|
43
70
|
/**
|
|
44
71
|
* Fetches and constructs the full user data
|
|
45
72
|
* @returns {Promise<User>}
|
|
46
73
|
*/
|
|
47
|
-
async constructUser() {
|
|
74
|
+
async constructUser(token) {
|
|
48
75
|
if (!this.token) {
|
|
49
76
|
throw new Error("Token is required to construct user");
|
|
50
77
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
this.setUserToken(token);
|
|
79
|
+
try {
|
|
80
|
+
// Fetch all data concurrently with Promise.all
|
|
81
|
+
const [access, profileResult, identityResult] = await Promise.all([
|
|
82
|
+
this.accessRepo.client.getAccessList(),
|
|
83
|
+
this.profileRepo.client.getCurrentProfile(),
|
|
84
|
+
this.identityRepo.client.getUserCredentials(),
|
|
85
|
+
]);
|
|
86
|
+
// Extract and validate response data
|
|
87
|
+
const accessList = this.accessRepo.handleResponse(access, 200);
|
|
88
|
+
const profileData = this.profileRepo.handleResponse(profileResult, 200);
|
|
89
|
+
const identityData = this.identityRepo.handleResponse(identityResult, 200);
|
|
90
|
+
// Create profile object
|
|
91
|
+
const profile = Profile.from(profileData);
|
|
92
|
+
if (!profile) {
|
|
93
|
+
throw new Error("Failed to create profile from response data");
|
|
94
|
+
}
|
|
95
|
+
// Construct and return user object
|
|
96
|
+
const user = User.from({
|
|
97
|
+
token: this.token,
|
|
98
|
+
profile,
|
|
99
|
+
access: accessList,
|
|
100
|
+
resetPassword: false,
|
|
101
|
+
...identityData,
|
|
102
|
+
});
|
|
103
|
+
if (!user) {
|
|
104
|
+
throw new Error("Failed to construct user");
|
|
105
|
+
}
|
|
106
|
+
return user;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
const message = error instanceof Error
|
|
110
|
+
? error.message
|
|
111
|
+
: "Unknown error occurred";
|
|
112
|
+
throw new Error(`Error constructing user: ${message}`);
|
|
113
|
+
}
|
|
67
114
|
}
|
|
68
115
|
}
|