zet-api 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish-to-npm.yml +80 -0
- package/LICENSE +674 -0
- package/README.md +257 -0
- package/dist/auth/manager.d.ts +19 -0
- package/dist/auth/manager.js +228 -0
- package/dist/auth/types.d.ts +277 -0
- package/dist/auth/types.js +64 -0
- package/dist/core/auth-manager.d.ts +54 -0
- package/dist/core/auth-manager.js +159 -0
- package/dist/core/auth-types.d.ts +238 -0
- package/dist/core/auth-types.js +54 -0
- package/dist/core/config.d.ts +16 -0
- package/dist/core/config.js +18 -0
- package/dist/core/constants.d.ts +25 -0
- package/dist/core/constants.js +51 -0
- package/dist/core/gtfs-types.d.ts +198 -0
- package/dist/core/gtfs-types.js +70 -0
- package/dist/core/manager.d.ts +39 -0
- package/dist/core/manager.js +359 -0
- package/dist/core/parsers.d.ts +893 -0
- package/dist/core/parsers.js +110 -0
- package/dist/core/utils.d.ts +4 -0
- package/dist/core/utils.js +59 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +22 -0
- package/dist/live-polling.d.ts +1 -0
- package/dist/live-polling.js +105 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +35 -0
- package/dist/text.d.ts +1 -0
- package/dist/text.js +35 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export type LoginCredentials = z.infer<typeof LoginCredentialsSchema>;
|
|
3
|
+
export declare const LoginCredentialsSchema: z.ZodEffects<z.ZodObject<{
|
|
4
|
+
username: z.ZodOptional<z.ZodString>;
|
|
5
|
+
password: z.ZodOptional<z.ZodString>;
|
|
6
|
+
revokeOtherTokens: z.ZodOptional<z.ZodBoolean>;
|
|
7
|
+
fcmToken: z.ZodOptional<z.ZodString>;
|
|
8
|
+
refreshToken: z.ZodOptional<z.ZodString>;
|
|
9
|
+
accessToken: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
username?: string | undefined;
|
|
12
|
+
password?: string | undefined;
|
|
13
|
+
revokeOtherTokens?: boolean | undefined;
|
|
14
|
+
fcmToken?: string | undefined;
|
|
15
|
+
refreshToken?: string | undefined;
|
|
16
|
+
accessToken?: string | undefined;
|
|
17
|
+
}, {
|
|
18
|
+
username?: string | undefined;
|
|
19
|
+
password?: string | undefined;
|
|
20
|
+
revokeOtherTokens?: boolean | undefined;
|
|
21
|
+
fcmToken?: string | undefined;
|
|
22
|
+
refreshToken?: string | undefined;
|
|
23
|
+
accessToken?: string | undefined;
|
|
24
|
+
}>, {
|
|
25
|
+
username?: string | undefined;
|
|
26
|
+
password?: string | undefined;
|
|
27
|
+
revokeOtherTokens?: boolean | undefined;
|
|
28
|
+
fcmToken?: string | undefined;
|
|
29
|
+
refreshToken?: string | undefined;
|
|
30
|
+
accessToken?: string | undefined;
|
|
31
|
+
}, {
|
|
32
|
+
username?: string | undefined;
|
|
33
|
+
password?: string | undefined;
|
|
34
|
+
revokeOtherTokens?: boolean | undefined;
|
|
35
|
+
fcmToken?: string | undefined;
|
|
36
|
+
refreshToken?: string | undefined;
|
|
37
|
+
accessToken?: string | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
export type RegisterCredentials = z.infer<typeof RegisterCredentialsSchema>;
|
|
40
|
+
export declare const RegisterCredentialsSchema: z.ZodObject<{
|
|
41
|
+
email: z.ZodString;
|
|
42
|
+
password: z.ZodString;
|
|
43
|
+
confirmPassword: z.ZodString;
|
|
44
|
+
}, "strip", z.ZodTypeAny, {
|
|
45
|
+
password: string;
|
|
46
|
+
email: string;
|
|
47
|
+
confirmPassword: string;
|
|
48
|
+
}, {
|
|
49
|
+
password: string;
|
|
50
|
+
email: string;
|
|
51
|
+
confirmPassword: string;
|
|
52
|
+
}>;
|
|
53
|
+
export type AuthTokens = z.infer<typeof AuthTokensSchema>;
|
|
54
|
+
export type AuthTokensLogin = AuthTokens & {
|
|
55
|
+
expiresIn: number;
|
|
56
|
+
viaTokenRefresh: boolean;
|
|
57
|
+
viaAccessToken: boolean;
|
|
58
|
+
};
|
|
59
|
+
export declare const AuthTokensSchema: z.ZodObject<{
|
|
60
|
+
accessToken: z.ZodString;
|
|
61
|
+
refreshToken: z.ZodString;
|
|
62
|
+
}, "strip", z.ZodTypeAny, {
|
|
63
|
+
refreshToken: string;
|
|
64
|
+
accessToken: string;
|
|
65
|
+
}, {
|
|
66
|
+
refreshToken: string;
|
|
67
|
+
accessToken: string;
|
|
68
|
+
}>;
|
|
69
|
+
export type RefreshTokenRequest = z.infer<typeof RefreshTokenRequestSchema>;
|
|
70
|
+
export declare const RefreshTokenRequestSchema: z.ZodObject<{
|
|
71
|
+
refreshToken: z.ZodString;
|
|
72
|
+
}, "strip", z.ZodTypeAny, {
|
|
73
|
+
refreshToken: string;
|
|
74
|
+
}, {
|
|
75
|
+
refreshToken: string;
|
|
76
|
+
}>;
|
|
77
|
+
export type Account = z.infer<typeof AccountSchema>;
|
|
78
|
+
export declare const AccountSchema: z.ZodObject<{
|
|
79
|
+
id: z.ZodNumber;
|
|
80
|
+
uid: z.ZodString;
|
|
81
|
+
email: z.ZodString;
|
|
82
|
+
firstName: z.ZodString;
|
|
83
|
+
lastName: z.ZodString;
|
|
84
|
+
ePurseAmount: z.ZodNumber;
|
|
85
|
+
clientId: z.ZodNullable<z.ZodNumber>;
|
|
86
|
+
language: z.ZodNumber;
|
|
87
|
+
isFullProfileActivationInProgress: z.ZodBoolean;
|
|
88
|
+
messages: z.ZodArray<z.ZodUnknown, "many">;
|
|
89
|
+
processes: z.ZodNullable<z.ZodUnknown>;
|
|
90
|
+
}, "strip", z.ZodTypeAny, {
|
|
91
|
+
email: string;
|
|
92
|
+
id: number;
|
|
93
|
+
uid: string;
|
|
94
|
+
firstName: string;
|
|
95
|
+
lastName: string;
|
|
96
|
+
ePurseAmount: number;
|
|
97
|
+
clientId: number | null;
|
|
98
|
+
language: number;
|
|
99
|
+
isFullProfileActivationInProgress: boolean;
|
|
100
|
+
messages: unknown[];
|
|
101
|
+
processes?: unknown;
|
|
102
|
+
}, {
|
|
103
|
+
email: string;
|
|
104
|
+
id: number;
|
|
105
|
+
uid: string;
|
|
106
|
+
firstName: string;
|
|
107
|
+
lastName: string;
|
|
108
|
+
ePurseAmount: number;
|
|
109
|
+
clientId: number | null;
|
|
110
|
+
language: number;
|
|
111
|
+
isFullProfileActivationInProgress: boolean;
|
|
112
|
+
messages: unknown[];
|
|
113
|
+
processes?: unknown;
|
|
114
|
+
}>;
|
|
115
|
+
export type StopIncomingTrip = z.infer<typeof StopIncomingTripSchema>;
|
|
116
|
+
export declare const StopIncomingTripSchema: z.ZodObject<{
|
|
117
|
+
tripId: z.ZodString;
|
|
118
|
+
routeShortName: z.ZodString;
|
|
119
|
+
headsign: z.ZodString;
|
|
120
|
+
expectedArrivalDateTime: z.ZodString;
|
|
121
|
+
hasLiveTracking: z.ZodBoolean;
|
|
122
|
+
daysFromToday: z.ZodNumber;
|
|
123
|
+
shapeId: z.ZodString;
|
|
124
|
+
vehicles: z.ZodArray<z.ZodObject<{
|
|
125
|
+
id: z.ZodString;
|
|
126
|
+
isForDisabledPeople: z.ZodNullable<z.ZodBoolean>;
|
|
127
|
+
vehicleTypeId: z.ZodNullable<z.ZodNumber>;
|
|
128
|
+
position: z.ZodOptional<z.ZodObject<{
|
|
129
|
+
latitude: z.ZodNumber;
|
|
130
|
+
longitude: z.ZodNumber;
|
|
131
|
+
}, "strip", z.ZodTypeAny, {
|
|
132
|
+
latitude: number;
|
|
133
|
+
longitude: number;
|
|
134
|
+
}, {
|
|
135
|
+
latitude: number;
|
|
136
|
+
longitude: number;
|
|
137
|
+
}>>;
|
|
138
|
+
}, "strip", z.ZodTypeAny, {
|
|
139
|
+
id: string;
|
|
140
|
+
isForDisabledPeople: boolean | null;
|
|
141
|
+
vehicleTypeId: number | null;
|
|
142
|
+
position?: {
|
|
143
|
+
latitude: number;
|
|
144
|
+
longitude: number;
|
|
145
|
+
} | undefined;
|
|
146
|
+
}, {
|
|
147
|
+
id: string;
|
|
148
|
+
isForDisabledPeople: boolean | null;
|
|
149
|
+
vehicleTypeId: number | null;
|
|
150
|
+
position?: {
|
|
151
|
+
latitude: number;
|
|
152
|
+
longitude: number;
|
|
153
|
+
} | undefined;
|
|
154
|
+
}>, "many">;
|
|
155
|
+
}, "strip", z.ZodTypeAny, {
|
|
156
|
+
tripId: string;
|
|
157
|
+
routeShortName: string;
|
|
158
|
+
headsign: string;
|
|
159
|
+
expectedArrivalDateTime: string;
|
|
160
|
+
hasLiveTracking: boolean;
|
|
161
|
+
daysFromToday: number;
|
|
162
|
+
shapeId: string;
|
|
163
|
+
vehicles: {
|
|
164
|
+
id: string;
|
|
165
|
+
isForDisabledPeople: boolean | null;
|
|
166
|
+
vehicleTypeId: number | null;
|
|
167
|
+
position?: {
|
|
168
|
+
latitude: number;
|
|
169
|
+
longitude: number;
|
|
170
|
+
} | undefined;
|
|
171
|
+
}[];
|
|
172
|
+
}, {
|
|
173
|
+
tripId: string;
|
|
174
|
+
routeShortName: string;
|
|
175
|
+
headsign: string;
|
|
176
|
+
expectedArrivalDateTime: string;
|
|
177
|
+
hasLiveTracking: boolean;
|
|
178
|
+
daysFromToday: number;
|
|
179
|
+
shapeId: string;
|
|
180
|
+
vehicles: {
|
|
181
|
+
id: string;
|
|
182
|
+
isForDisabledPeople: boolean | null;
|
|
183
|
+
vehicleTypeId: number | null;
|
|
184
|
+
position?: {
|
|
185
|
+
latitude: number;
|
|
186
|
+
longitude: number;
|
|
187
|
+
} | undefined;
|
|
188
|
+
}[];
|
|
189
|
+
}>;
|
|
190
|
+
export type StopIncomingTripWithDates = Omit<StopIncomingTrip, 'expectedArrivalDateTime'> & {
|
|
191
|
+
expectedArrivalDateTime: Date;
|
|
192
|
+
};
|
|
193
|
+
export type GetStopIncomingTripsInput = z.infer<typeof GetStopIncomingTripsInputSchema>;
|
|
194
|
+
export declare const GetStopIncomingTripsInputSchema: z.ZodObject<{
|
|
195
|
+
stopId: z.ZodString;
|
|
196
|
+
isMapView: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
197
|
+
}, "strip", z.ZodTypeAny, {
|
|
198
|
+
stopId: string;
|
|
199
|
+
isMapView: boolean;
|
|
200
|
+
}, {
|
|
201
|
+
stopId: string;
|
|
202
|
+
isMapView?: boolean | undefined;
|
|
203
|
+
}>;
|
|
204
|
+
export declare const StopIncomingTripsResponseSchema: z.ZodArray<z.ZodObject<{
|
|
205
|
+
tripId: z.ZodString;
|
|
206
|
+
routeShortName: z.ZodString;
|
|
207
|
+
headsign: z.ZodString;
|
|
208
|
+
expectedArrivalDateTime: z.ZodString;
|
|
209
|
+
hasLiveTracking: z.ZodBoolean;
|
|
210
|
+
daysFromToday: z.ZodNumber;
|
|
211
|
+
shapeId: z.ZodString;
|
|
212
|
+
vehicles: z.ZodArray<z.ZodObject<{
|
|
213
|
+
id: z.ZodString;
|
|
214
|
+
isForDisabledPeople: z.ZodNullable<z.ZodBoolean>;
|
|
215
|
+
vehicleTypeId: z.ZodNullable<z.ZodNumber>;
|
|
216
|
+
position: z.ZodOptional<z.ZodObject<{
|
|
217
|
+
latitude: z.ZodNumber;
|
|
218
|
+
longitude: z.ZodNumber;
|
|
219
|
+
}, "strip", z.ZodTypeAny, {
|
|
220
|
+
latitude: number;
|
|
221
|
+
longitude: number;
|
|
222
|
+
}, {
|
|
223
|
+
latitude: number;
|
|
224
|
+
longitude: number;
|
|
225
|
+
}>>;
|
|
226
|
+
}, "strip", z.ZodTypeAny, {
|
|
227
|
+
id: string;
|
|
228
|
+
isForDisabledPeople: boolean | null;
|
|
229
|
+
vehicleTypeId: number | null;
|
|
230
|
+
position?: {
|
|
231
|
+
latitude: number;
|
|
232
|
+
longitude: number;
|
|
233
|
+
} | undefined;
|
|
234
|
+
}, {
|
|
235
|
+
id: string;
|
|
236
|
+
isForDisabledPeople: boolean | null;
|
|
237
|
+
vehicleTypeId: number | null;
|
|
238
|
+
position?: {
|
|
239
|
+
latitude: number;
|
|
240
|
+
longitude: number;
|
|
241
|
+
} | undefined;
|
|
242
|
+
}>, "many">;
|
|
243
|
+
}, "strip", z.ZodTypeAny, {
|
|
244
|
+
tripId: string;
|
|
245
|
+
routeShortName: string;
|
|
246
|
+
headsign: string;
|
|
247
|
+
expectedArrivalDateTime: string;
|
|
248
|
+
hasLiveTracking: boolean;
|
|
249
|
+
daysFromToday: number;
|
|
250
|
+
shapeId: string;
|
|
251
|
+
vehicles: {
|
|
252
|
+
id: string;
|
|
253
|
+
isForDisabledPeople: boolean | null;
|
|
254
|
+
vehicleTypeId: number | null;
|
|
255
|
+
position?: {
|
|
256
|
+
latitude: number;
|
|
257
|
+
longitude: number;
|
|
258
|
+
} | undefined;
|
|
259
|
+
}[];
|
|
260
|
+
}, {
|
|
261
|
+
tripId: string;
|
|
262
|
+
routeShortName: string;
|
|
263
|
+
headsign: string;
|
|
264
|
+
expectedArrivalDateTime: string;
|
|
265
|
+
hasLiveTracking: boolean;
|
|
266
|
+
daysFromToday: number;
|
|
267
|
+
shapeId: string;
|
|
268
|
+
vehicles: {
|
|
269
|
+
id: string;
|
|
270
|
+
isForDisabledPeople: boolean | null;
|
|
271
|
+
vehicleTypeId: number | null;
|
|
272
|
+
position?: {
|
|
273
|
+
latitude: number;
|
|
274
|
+
longitude: number;
|
|
275
|
+
} | undefined;
|
|
276
|
+
}[];
|
|
277
|
+
}>, "many">;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StopIncomingTripsResponseSchema = exports.GetStopIncomingTripsInputSchema = exports.StopIncomingTripSchema = exports.AccountSchema = exports.RefreshTokenRequestSchema = exports.AuthTokensSchema = exports.RegisterCredentialsSchema = exports.LoginCredentialsSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.LoginCredentialsSchema = zod_1.z.object({
|
|
6
|
+
username: zod_1.z.string().email().optional(),
|
|
7
|
+
password: zod_1.z.string().optional(),
|
|
8
|
+
revokeOtherTokens: zod_1.z.boolean().optional(),
|
|
9
|
+
fcmToken: zod_1.z.string().optional(),
|
|
10
|
+
refreshToken: zod_1.z.string().optional(),
|
|
11
|
+
accessToken: zod_1.z.string().optional(),
|
|
12
|
+
}).refine((data) => {
|
|
13
|
+
return (data.accessToken && data.refreshToken) || data.refreshToken || (data.username && data.password);
|
|
14
|
+
}, {
|
|
15
|
+
message: 'Either (accessToken + refreshToken), refreshToken alone, or both username and password must be provided',
|
|
16
|
+
});
|
|
17
|
+
exports.RegisterCredentialsSchema = zod_1.z.object({
|
|
18
|
+
email: zod_1.z.string().email(),
|
|
19
|
+
password: zod_1.z.string(),
|
|
20
|
+
confirmPassword: zod_1.z.string(),
|
|
21
|
+
});
|
|
22
|
+
exports.AuthTokensSchema = zod_1.z.object({
|
|
23
|
+
accessToken: zod_1.z.string(),
|
|
24
|
+
refreshToken: zod_1.z.string(),
|
|
25
|
+
});
|
|
26
|
+
exports.RefreshTokenRequestSchema = zod_1.z.object({
|
|
27
|
+
refreshToken: zod_1.z.string(),
|
|
28
|
+
});
|
|
29
|
+
exports.AccountSchema = zod_1.z.object({
|
|
30
|
+
id: zod_1.z.number(),
|
|
31
|
+
uid: zod_1.z.string(),
|
|
32
|
+
email: zod_1.z.string().email(),
|
|
33
|
+
firstName: zod_1.z.string(),
|
|
34
|
+
lastName: zod_1.z.string(),
|
|
35
|
+
ePurseAmount: zod_1.z.number(),
|
|
36
|
+
clientId: zod_1.z.number().nullable(),
|
|
37
|
+
language: zod_1.z.number(),
|
|
38
|
+
isFullProfileActivationInProgress: zod_1.z.boolean(),
|
|
39
|
+
messages: zod_1.z.array(zod_1.z.unknown()),
|
|
40
|
+
processes: zod_1.z.unknown().nullable(),
|
|
41
|
+
});
|
|
42
|
+
exports.StopIncomingTripSchema = zod_1.z.object({
|
|
43
|
+
tripId: zod_1.z.string(),
|
|
44
|
+
routeShortName: zod_1.z.string(),
|
|
45
|
+
headsign: zod_1.z.string(),
|
|
46
|
+
expectedArrivalDateTime: zod_1.z.string(),
|
|
47
|
+
hasLiveTracking: zod_1.z.boolean(),
|
|
48
|
+
daysFromToday: zod_1.z.number(),
|
|
49
|
+
shapeId: zod_1.z.string(),
|
|
50
|
+
vehicles: zod_1.z.array(zod_1.z.object({
|
|
51
|
+
id: zod_1.z.string(),
|
|
52
|
+
isForDisabledPeople: zod_1.z.boolean().nullable(),
|
|
53
|
+
vehicleTypeId: zod_1.z.number().nullable(),
|
|
54
|
+
position: zod_1.z.object({
|
|
55
|
+
latitude: zod_1.z.number(),
|
|
56
|
+
longitude: zod_1.z.number(),
|
|
57
|
+
}).optional(),
|
|
58
|
+
})),
|
|
59
|
+
});
|
|
60
|
+
exports.GetStopIncomingTripsInputSchema = zod_1.z.object({
|
|
61
|
+
stopId: zod_1.z.string(),
|
|
62
|
+
isMapView: zod_1.z.boolean().optional().default(false),
|
|
63
|
+
});
|
|
64
|
+
exports.StopIncomingTripsResponseSchema = zod_1.z.array(exports.StopIncomingTripSchema);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { LoginCredentials, AuthTokens, Account } from './auth-types';
|
|
2
|
+
/**
|
|
3
|
+
* ZetAuthManager handles authentication with the ZET API
|
|
4
|
+
* Manages login, token refresh, and account information
|
|
5
|
+
*/
|
|
6
|
+
export declare class ZetAuthManager {
|
|
7
|
+
private accessToken;
|
|
8
|
+
private refreshToken;
|
|
9
|
+
private tokenExpiresAt;
|
|
10
|
+
/**
|
|
11
|
+
* Check if currently authenticated
|
|
12
|
+
*/
|
|
13
|
+
isAuthenticated(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Check if access token is expired or about to expire (within 1 minute)
|
|
16
|
+
*/
|
|
17
|
+
isAccessTokenExpired(): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Get current access token, refreshing if needed
|
|
20
|
+
*/
|
|
21
|
+
getAccessToken(): Promise<string | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Login with username and password
|
|
24
|
+
*/
|
|
25
|
+
login(credentials: LoginCredentials): Promise<AuthTokens>;
|
|
26
|
+
/**
|
|
27
|
+
* Refresh access token using refresh token
|
|
28
|
+
*/
|
|
29
|
+
refreshAccessToken(): Promise<AuthTokens>;
|
|
30
|
+
/**
|
|
31
|
+
* Get account information (requires authentication)
|
|
32
|
+
*/
|
|
33
|
+
getAccount(): Promise<Account>;
|
|
34
|
+
/**
|
|
35
|
+
* Logout and clear stored tokens
|
|
36
|
+
*/
|
|
37
|
+
logout(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Set tokens and calculate expiration
|
|
40
|
+
*/
|
|
41
|
+
private setTokens;
|
|
42
|
+
/**
|
|
43
|
+
* Clear all stored tokens
|
|
44
|
+
*/
|
|
45
|
+
private clearTokens;
|
|
46
|
+
/**
|
|
47
|
+
* Manually set tokens (for restoring session)
|
|
48
|
+
*/
|
|
49
|
+
setTokensManually(tokens: AuthTokens): void;
|
|
50
|
+
/**
|
|
51
|
+
* Get current tokens (for saving session)
|
|
52
|
+
*/
|
|
53
|
+
getTokens(): AuthTokens | null;
|
|
54
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ZetAuthManager = void 0;
|
|
7
|
+
const auth_types_1 = require("./auth-types");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
const axios_1 = __importDefault(require("axios"));
|
|
10
|
+
const config_1 = __importDefault(require("./config"));
|
|
11
|
+
/**
|
|
12
|
+
* ZetAuthManager handles authentication with the ZET API
|
|
13
|
+
* Manages login, token refresh, and account information
|
|
14
|
+
*/
|
|
15
|
+
class ZetAuthManager {
|
|
16
|
+
accessToken = null;
|
|
17
|
+
refreshToken = null;
|
|
18
|
+
tokenExpiresAt = null;
|
|
19
|
+
/**
|
|
20
|
+
* Check if currently authenticated
|
|
21
|
+
*/
|
|
22
|
+
isAuthenticated() {
|
|
23
|
+
return !!this.accessToken && !!this.refreshToken;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check if access token is expired or about to expire (within 1 minute)
|
|
27
|
+
*/
|
|
28
|
+
isAccessTokenExpired() {
|
|
29
|
+
if (!this.tokenExpiresAt)
|
|
30
|
+
return true;
|
|
31
|
+
return Date.now() >= this.tokenExpiresAt - 60000; // 1 minute buffer
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get current access token, refreshing if needed
|
|
35
|
+
*/
|
|
36
|
+
async getAccessToken() {
|
|
37
|
+
if (!this.isAuthenticated()) {
|
|
38
|
+
throw new Error('Not authenticated. Please login first.');
|
|
39
|
+
}
|
|
40
|
+
if (this.isAccessTokenExpired() && this.refreshToken) {
|
|
41
|
+
await this.refreshAccessToken();
|
|
42
|
+
}
|
|
43
|
+
return this.accessToken;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Login with username and password
|
|
47
|
+
*/
|
|
48
|
+
async login(credentials) {
|
|
49
|
+
const validated = auth_types_1.LoginCredentialsSchema.parse(credentials);
|
|
50
|
+
const response = await axios_1.default.post(`${config_1.default.authServiceUrl}/login`, validated).catch((err) => err.response);
|
|
51
|
+
if (!response || response.status !== 200) {
|
|
52
|
+
throw new Error(`Login failed: ${response?.statusText || 'Unknown error'}`);
|
|
53
|
+
}
|
|
54
|
+
const parsed = auth_types_1.AuthTokensSchema.safeParse(response.data);
|
|
55
|
+
if (!parsed.success) {
|
|
56
|
+
throw new Error(`Failed to parse login response: ${(0, utils_1.parseZodError)(parsed.error).join(', ')}.`);
|
|
57
|
+
}
|
|
58
|
+
this.setTokens(parsed.data);
|
|
59
|
+
return parsed.data;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Refresh access token using refresh token
|
|
63
|
+
*/
|
|
64
|
+
async refreshAccessToken() {
|
|
65
|
+
if (!this.refreshToken) {
|
|
66
|
+
throw new Error('No refresh token available. Please login first.');
|
|
67
|
+
}
|
|
68
|
+
const validated = auth_types_1.RefreshTokenRequestSchema.parse({ refreshToken: this.refreshToken });
|
|
69
|
+
const response = await axios_1.default.post(`${config_1.default.authServiceUrl}/refreshTokens`, validated).catch((err) => err.response);
|
|
70
|
+
if (!response || response.status !== 200) {
|
|
71
|
+
// If refresh fails, clear tokens and require re-login
|
|
72
|
+
this.clearTokens();
|
|
73
|
+
throw new Error(`Token refresh failed: ${response?.statusText || 'Unknown error'}. Please login again.`);
|
|
74
|
+
}
|
|
75
|
+
const parsed = auth_types_1.AuthTokensSchema.safeParse(response.data);
|
|
76
|
+
if (!parsed.success) {
|
|
77
|
+
throw new Error(`Failed to parse refresh response: ${(0, utils_1.parseZodError)(parsed.error).join(', ')}.`);
|
|
78
|
+
}
|
|
79
|
+
this.setTokens(parsed.data);
|
|
80
|
+
return parsed.data;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get account information (requires authentication)
|
|
84
|
+
*/
|
|
85
|
+
async getAccount() {
|
|
86
|
+
const token = await this.getAccessToken();
|
|
87
|
+
if (!token) {
|
|
88
|
+
throw new Error('Not authenticated. Please login first.');
|
|
89
|
+
}
|
|
90
|
+
const response = await axios_1.default.get(config_1.default.accountServiceUrl, {
|
|
91
|
+
headers: {
|
|
92
|
+
Authorization: `Bearer ${token}`,
|
|
93
|
+
},
|
|
94
|
+
}).catch((err) => err.response);
|
|
95
|
+
if (!response || response.status !== 200) {
|
|
96
|
+
throw new Error(`Failed to get account: ${response?.statusText || 'Unknown error'}`);
|
|
97
|
+
}
|
|
98
|
+
const parsed = auth_types_1.AccountSchema.safeParse(response.data);
|
|
99
|
+
if (!parsed.success) {
|
|
100
|
+
throw new Error(`Failed to parse account data: ${(0, utils_1.parseZodError)(parsed.error).join(', ')}.`);
|
|
101
|
+
}
|
|
102
|
+
return parsed.data;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Logout and clear stored tokens
|
|
106
|
+
*/
|
|
107
|
+
logout() {
|
|
108
|
+
this.clearTokens();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Set tokens and calculate expiration
|
|
112
|
+
*/
|
|
113
|
+
setTokens(tokens) {
|
|
114
|
+
this.accessToken = tokens.accessToken;
|
|
115
|
+
this.refreshToken = tokens.refreshToken;
|
|
116
|
+
// Decode JWT to get expiration (simple base64 decode, no verification)
|
|
117
|
+
try {
|
|
118
|
+
const parts = tokens.accessToken.split('.');
|
|
119
|
+
if (parts.length === 3 && parts[1]) {
|
|
120
|
+
const payload = JSON.parse(atob(parts[1]));
|
|
121
|
+
this.tokenExpiresAt = payload.exp * 1000; // Convert to milliseconds
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// If decode fails, assume 15 minutes
|
|
125
|
+
this.tokenExpiresAt = Date.now() + 900000;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
// If decode fails, assume 15 minutes
|
|
130
|
+
this.tokenExpiresAt = Date.now() + 900000;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Clear all stored tokens
|
|
135
|
+
*/
|
|
136
|
+
clearTokens() {
|
|
137
|
+
this.accessToken = null;
|
|
138
|
+
this.refreshToken = null;
|
|
139
|
+
this.tokenExpiresAt = null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Manually set tokens (for restoring session)
|
|
143
|
+
*/
|
|
144
|
+
setTokensManually(tokens) {
|
|
145
|
+
this.setTokens(tokens);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get current tokens (for saving session)
|
|
149
|
+
*/
|
|
150
|
+
getTokens() {
|
|
151
|
+
if (!this.accessToken || !this.refreshToken)
|
|
152
|
+
return null;
|
|
153
|
+
return {
|
|
154
|
+
accessToken: this.accessToken,
|
|
155
|
+
refreshToken: this.refreshToken,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.ZetAuthManager = ZetAuthManager;
|