@go-avro/avro-js 0.0.2-beta.76 → 0.0.2-beta.78
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.
|
@@ -3,6 +3,7 @@ export declare class AuthManager {
|
|
|
3
3
|
private storages;
|
|
4
4
|
private baseUrl;
|
|
5
5
|
private tokenRefreshedCallbacks;
|
|
6
|
+
private tokenRefreshFailedCallbacks;
|
|
6
7
|
constructor({ baseUrl, storage, }: {
|
|
7
8
|
baseUrl: string;
|
|
8
9
|
storage: TokenStorage | TokenStorage[];
|
|
@@ -11,6 +12,7 @@ export declare class AuthManager {
|
|
|
11
12
|
fetchNewTokens(): Promise<Tokens>;
|
|
12
13
|
accessToken(): Promise<string | undefined>;
|
|
13
14
|
onTokenRefreshed(callback: (accessToken: string) => void): void;
|
|
15
|
+
onTokenRefreshFailed(callback: () => void): void;
|
|
14
16
|
refreshTokens(): Promise<Tokens | null>;
|
|
15
17
|
setTokens(tokens: Tokens): Promise<void>;
|
|
16
18
|
clearTokens(): Promise<void>;
|
package/dist/auth/AuthManager.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export class AuthManager {
|
|
2
2
|
constructor({ baseUrl, storage, }) {
|
|
3
3
|
this.tokenRefreshedCallbacks = [];
|
|
4
|
+
this.tokenRefreshFailedCallbacks = [];
|
|
4
5
|
this.storages = Array.isArray(storage) ? storage : [storage];
|
|
5
6
|
if (this.storages.length === 0) {
|
|
6
7
|
throw new Error('At least one token storage must be provided');
|
|
@@ -92,6 +93,9 @@ export class AuthManager {
|
|
|
92
93
|
onTokenRefreshed(callback) {
|
|
93
94
|
this.tokenRefreshedCallbacks.push(callback);
|
|
94
95
|
}
|
|
96
|
+
onTokenRefreshFailed(callback) {
|
|
97
|
+
this.tokenRefreshFailedCallbacks.push(callback);
|
|
98
|
+
}
|
|
95
99
|
async refreshTokens() {
|
|
96
100
|
try {
|
|
97
101
|
const newToken = await this.fetchNewTokens();
|
|
@@ -103,6 +107,7 @@ export class AuthManager {
|
|
|
103
107
|
return newToken;
|
|
104
108
|
}
|
|
105
109
|
catch (error) {
|
|
110
|
+
this.tokenRefreshFailedCallbacks.forEach(cb => cb());
|
|
106
111
|
console.error('Failed to refresh tokens:', error);
|
|
107
112
|
return null;
|
|
108
113
|
}
|
|
@@ -246,6 +246,7 @@ declare module '../client/QueryClient' {
|
|
|
246
246
|
export declare class AvroQueryClient {
|
|
247
247
|
protected config: Required<AvroQueryClientConfig>;
|
|
248
248
|
readonly socket: Socket;
|
|
249
|
+
_isAuthenticated: boolean;
|
|
249
250
|
constructor(config: AvroQueryClientConfig);
|
|
250
251
|
emit(eventName: string, data: unknown): void;
|
|
251
252
|
on<T>(eventName: string, callback: (data: T) => void): void;
|
|
@@ -254,13 +255,16 @@ export declare class AvroQueryClient {
|
|
|
254
255
|
post<T>(path: string, data: any, cancelToken?: CancelToken, headers?: Record<string, string>, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<T>;
|
|
255
256
|
put<T>(path: string, data: any, cancelToken?: CancelToken, headers?: Record<string, string>, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<T>;
|
|
256
257
|
delete<T>(path: string, cancelToken?: CancelToken, headers?: Record<string, string>, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<T>;
|
|
257
|
-
|
|
258
|
+
useLogin(): ReturnType<typeof useMutation<LoginResponse, StandardError, {
|
|
258
259
|
username: string;
|
|
259
260
|
password: string;
|
|
260
261
|
code?: string;
|
|
261
|
-
|
|
262
|
+
cancelToken?: CancelToken;
|
|
263
|
+
}>>;
|
|
262
264
|
setTokens(tokens: Tokens): Promise<void>;
|
|
263
265
|
clearTokens(): Promise<void>;
|
|
266
|
+
isAuthenticated(): boolean;
|
|
267
|
+
isAuthenticatedAsync(): Promise<boolean>;
|
|
264
268
|
useLogout(): ReturnType<typeof useMutation<void, StandardError, CancelToken | undefined>>;
|
|
265
269
|
fetchJobs(companyGuid: string, body?: {
|
|
266
270
|
amt?: number;
|
|
@@ -4,6 +4,7 @@ import { LoginResponse } from '../types/api';
|
|
|
4
4
|
import { StandardError } from '../types/error';
|
|
5
5
|
export class AvroQueryClient {
|
|
6
6
|
constructor(config) {
|
|
7
|
+
this._isAuthenticated = false;
|
|
7
8
|
this.config = {
|
|
8
9
|
baseUrl: config.baseUrl,
|
|
9
10
|
authManager: config.authManager,
|
|
@@ -11,6 +12,9 @@ export class AvroQueryClient {
|
|
|
11
12
|
retryStrategy: config.retryStrategy ?? 'fixed',
|
|
12
13
|
timeout: config.timeout ?? 0,
|
|
13
14
|
};
|
|
15
|
+
config.authManager.isAuthenticated().then(isAuth => {
|
|
16
|
+
this._isAuthenticated = isAuth;
|
|
17
|
+
});
|
|
14
18
|
this.socket = io(config.baseUrl, { autoConnect: false, transports: ["websocket"], });
|
|
15
19
|
if (!this.socket.connected) {
|
|
16
20
|
this.config.authManager.accessToken().then(token => {
|
|
@@ -20,6 +24,7 @@ export class AvroQueryClient {
|
|
|
20
24
|
});
|
|
21
25
|
}
|
|
22
26
|
this.socket.on('connect', () => {
|
|
27
|
+
this._isAuthenticated = true;
|
|
23
28
|
console.log(`Socket connected with ID: ${this.socket?.id}`);
|
|
24
29
|
});
|
|
25
30
|
this.socket.on('disconnect', (reason) => {
|
|
@@ -30,11 +35,18 @@ export class AvroQueryClient {
|
|
|
30
35
|
});
|
|
31
36
|
this.config.authManager.onTokenRefreshed((newAccessToken) => {
|
|
32
37
|
if (this.socket && newAccessToken) {
|
|
38
|
+
this._isAuthenticated = true;
|
|
33
39
|
console.log('Access token refreshed, updating socket auth...');
|
|
34
40
|
this.socket.auth = { token: newAccessToken };
|
|
35
41
|
this.socket.disconnect().connect();
|
|
36
42
|
}
|
|
37
43
|
});
|
|
44
|
+
config.authManager.onTokenRefreshFailed(() => {
|
|
45
|
+
this._isAuthenticated = false;
|
|
46
|
+
if (this.socket && this.socket.connected) {
|
|
47
|
+
this.socket.disconnect();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
38
50
|
}
|
|
39
51
|
emit(eventName, data) {
|
|
40
52
|
if (!this.socket?.connected) {
|
|
@@ -61,26 +73,32 @@ export class AvroQueryClient {
|
|
|
61
73
|
delete(path, cancelToken, headers = {}, progressUpdateCallback) {
|
|
62
74
|
return this._xhr('DELETE', path, null, cancelToken, headers, false, this.config.maxRetries, progressUpdateCallback);
|
|
63
75
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
useLogin() {
|
|
77
|
+
const queryClient = useQueryClient();
|
|
78
|
+
return useMutation({
|
|
79
|
+
mutationFn: async ({ username, password, code, cancelToken }) => {
|
|
80
|
+
const resp = await this._fetch('POST', '/login', { username, password, code }, cancelToken);
|
|
81
|
+
if (!resp || !('access_token' in resp)) {
|
|
82
|
+
if (resp.msg === "TOTP email sent") {
|
|
83
|
+
return LoginResponse.NEEDS_TOTP;
|
|
84
|
+
}
|
|
85
|
+
throw new StandardError(401, 'Invalid login response');
|
|
70
86
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this.
|
|
76
|
-
}
|
|
77
|
-
return this.config.authManager.setTokens({ access_token: resp.access_token, refresh_token: resp.refresh_token }).then(() => {
|
|
87
|
+
this.socket.auth = { token: resp.access_token };
|
|
88
|
+
if (!this.socket.connected) {
|
|
89
|
+
this.socket.connect();
|
|
90
|
+
}
|
|
91
|
+
await this.config.authManager.setTokens({ access_token: resp.access_token, refresh_token: resp.refresh_token });
|
|
78
92
|
return LoginResponse.SUCCESS;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
93
|
+
},
|
|
94
|
+
onSettled: () => {
|
|
95
|
+
queryClient.invalidateQueries();
|
|
96
|
+
},
|
|
97
|
+
onError: (err) => {
|
|
98
|
+
this.config.authManager.clearTokens();
|
|
99
|
+
console.error('Login failed:', err);
|
|
100
|
+
throw new StandardError(401, 'Login failed');
|
|
101
|
+
}
|
|
84
102
|
});
|
|
85
103
|
}
|
|
86
104
|
setTokens(tokens) {
|
|
@@ -89,6 +107,12 @@ export class AvroQueryClient {
|
|
|
89
107
|
clearTokens() {
|
|
90
108
|
return this.config.authManager.clearTokens();
|
|
91
109
|
}
|
|
110
|
+
isAuthenticated() {
|
|
111
|
+
return this._isAuthenticated;
|
|
112
|
+
}
|
|
113
|
+
isAuthenticatedAsync() {
|
|
114
|
+
return this.config.authManager.isAuthenticated();
|
|
115
|
+
}
|
|
92
116
|
useLogout() {
|
|
93
117
|
const queryClient = useQueryClient();
|
|
94
118
|
return useMutation({
|
|
@@ -100,6 +124,7 @@ export class AvroQueryClient {
|
|
|
100
124
|
}
|
|
101
125
|
},
|
|
102
126
|
onSettled: () => {
|
|
127
|
+
this._isAuthenticated = false;
|
|
103
128
|
queryClient.invalidateQueries();
|
|
104
129
|
},
|
|
105
130
|
onError: (err) => {
|