@thetechfossil/auth2 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,442 @@
1
+ 'use strict';
2
+
3
+ var axios = require('axios');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var axios__default = /*#__PURE__*/_interopDefault(axios);
8
+
9
+ // src/core/http-client.ts
10
+ var HttpClient = class {
11
+ constructor(baseUrl, defaultHeaders = {}) {
12
+ this.csrfToken = null;
13
+ this.axiosInstance = axios__default.default.create({
14
+ baseURL: baseUrl.replace(/\/$/, ""),
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ ...defaultHeaders
18
+ },
19
+ withCredentials: true,
20
+ // Include cookies for CSRF
21
+ timeout: 3e4
22
+ // 30 second timeout
23
+ });
24
+ this.axiosInstance.interceptors.request.use(
25
+ (config) => {
26
+ if (this.csrfToken && ["post", "put", "delete", "patch"].includes(config.method?.toLowerCase() || "")) {
27
+ config.headers["x-csrf-token"] = this.csrfToken;
28
+ }
29
+ return config;
30
+ },
31
+ (error) => Promise.reject(error)
32
+ );
33
+ this.axiosInstance.interceptors.response.use(
34
+ (response) => response,
35
+ async (error) => {
36
+ const originalRequest = error.config;
37
+ if (error.response?.status === 403 && !originalRequest._retry) {
38
+ originalRequest._retry = true;
39
+ try {
40
+ await this.refreshCsrfToken();
41
+ if (originalRequest.headers) {
42
+ originalRequest.headers["x-csrf-token"] = this.csrfToken;
43
+ }
44
+ return this.axiosInstance(originalRequest);
45
+ } catch (refreshError) {
46
+ return Promise.reject(refreshError);
47
+ }
48
+ }
49
+ return Promise.reject(error);
50
+ }
51
+ );
52
+ }
53
+ async get(endpoint, headers) {
54
+ const response = await this.axiosInstance.get(endpoint, { headers });
55
+ return response.data;
56
+ }
57
+ async post(endpoint, data, headers) {
58
+ const response = await this.axiosInstance.post(endpoint, data, { headers });
59
+ return response.data;
60
+ }
61
+ async put(endpoint, data, headers) {
62
+ const response = await this.axiosInstance.put(endpoint, data, { headers });
63
+ return response.data;
64
+ }
65
+ async delete(endpoint, headers) {
66
+ const response = await this.axiosInstance.delete(endpoint, { headers });
67
+ return response.data;
68
+ }
69
+ setAuthToken(token) {
70
+ this.axiosInstance.defaults.headers.common["Authorization"] = `Bearer ${token}`;
71
+ }
72
+ removeAuthToken() {
73
+ delete this.axiosInstance.defaults.headers.common["Authorization"];
74
+ }
75
+ setCsrfToken(token) {
76
+ this.csrfToken = token;
77
+ }
78
+ getCsrfToken() {
79
+ return this.csrfToken;
80
+ }
81
+ removeCsrfToken() {
82
+ this.csrfToken = null;
83
+ }
84
+ async refreshCsrfToken() {
85
+ try {
86
+ const response = await this.axiosInstance.get("/api/v1/auth/csrf-token");
87
+ this.csrfToken = response.data.csrfToken;
88
+ } catch (error) {
89
+ console.error("Failed to refresh CSRF token:", error);
90
+ throw error;
91
+ }
92
+ }
93
+ };
94
+
95
+ // src/core/auth-service.ts
96
+ var AuthService = class {
97
+ constructor(config) {
98
+ this.token = null;
99
+ this.config = {
100
+ localStorageKey: "auth_token",
101
+ csrfEnabled: true,
102
+ ...config
103
+ };
104
+ this.httpClient = new HttpClient(this.config.baseUrl);
105
+ this.loadTokenFromStorage();
106
+ if (this.config.csrfEnabled && typeof window !== "undefined") {
107
+ this.refreshCsrfToken();
108
+ }
109
+ }
110
+ loadTokenFromStorage() {
111
+ if (typeof window !== "undefined" && this.config.localStorageKey) {
112
+ try {
113
+ const token = localStorage.getItem(this.config.localStorageKey);
114
+ if (token) {
115
+ this.token = token;
116
+ this.httpClient.setAuthToken(token);
117
+ }
118
+ } catch (error) {
119
+ console.warn("Failed to load token from storage:", error);
120
+ }
121
+ }
122
+ }
123
+ saveTokenToStorage(token) {
124
+ if (typeof window !== "undefined" && this.config.localStorageKey) {
125
+ try {
126
+ localStorage.setItem(this.config.localStorageKey, token);
127
+ } catch (error) {
128
+ console.warn("Failed to save token to storage:", error);
129
+ }
130
+ }
131
+ }
132
+ removeTokenFromStorage() {
133
+ if (typeof window !== "undefined" && this.config.localStorageKey) {
134
+ try {
135
+ localStorage.removeItem(this.config.localStorageKey);
136
+ } catch (error) {
137
+ console.warn("Failed to remove token from storage:", error);
138
+ }
139
+ }
140
+ }
141
+ isAuthenticated() {
142
+ return !!this.token;
143
+ }
144
+ getToken() {
145
+ return this.token;
146
+ }
147
+ getCurrentUser() {
148
+ if (!this.token)
149
+ return null;
150
+ try {
151
+ const payload = JSON.parse(atob(this.token.split(".")[1]));
152
+ return payload.user || null;
153
+ } catch (error) {
154
+ console.error("Failed to parse user from token:", error);
155
+ return null;
156
+ }
157
+ }
158
+ // CSRF Token Management
159
+ async refreshCsrfToken() {
160
+ if (!this.config.csrfEnabled)
161
+ return;
162
+ try {
163
+ const response = await this.httpClient.get("/api/v1/auth/csrf-token");
164
+ if (response.csrfToken) {
165
+ this.httpClient.setCsrfToken(response.csrfToken);
166
+ }
167
+ } catch (error) {
168
+ console.error("Failed to get CSRF token:", error);
169
+ }
170
+ }
171
+ getCsrfToken() {
172
+ return this.httpClient.getCsrfToken();
173
+ }
174
+ // OAuth Methods
175
+ loginWithOAuth(provider) {
176
+ if (typeof window === "undefined") {
177
+ throw new Error("OAuth login is only available in browser environments");
178
+ }
179
+ const oauthUrl = `${this.config.baseUrl}/api/v1/auth/oauth/${provider}`;
180
+ window.location.href = oauthUrl;
181
+ }
182
+ linkOAuthProvider(provider) {
183
+ if (typeof window === "undefined") {
184
+ throw new Error("OAuth linking is only available in browser environments");
185
+ }
186
+ if (!this.token) {
187
+ throw new Error("Must be authenticated to link OAuth provider");
188
+ }
189
+ const linkUrl = `${this.config.baseUrl}/api/v1/auth/oauth/${provider}/link`;
190
+ window.location.href = linkUrl;
191
+ }
192
+ async unlinkOAuthProvider(provider) {
193
+ if (!this.token) {
194
+ throw new Error("Not authenticated");
195
+ }
196
+ const response = await this.httpClient.delete(
197
+ `/api/v1/auth/oauth/${provider}/unlink`
198
+ );
199
+ return response;
200
+ }
201
+ // Standard Auth Methods
202
+ async login(data) {
203
+ const response = await this.httpClient.post("/api/v1/auth/login", data);
204
+ if (response.success && response.token) {
205
+ this.token = response.token;
206
+ this.httpClient.setAuthToken(response.token);
207
+ this.saveTokenToStorage(response.token);
208
+ return response;
209
+ }
210
+ if (response.success && response.message === "OTP sent to your email.") {
211
+ return response;
212
+ }
213
+ if (response.success && response.message === "OTP verified successfully." && response.token) {
214
+ this.token = response.token;
215
+ this.httpClient.setAuthToken(response.token);
216
+ this.saveTokenToStorage(response.token);
217
+ return response;
218
+ }
219
+ throw new Error(response.message || "Login failed");
220
+ }
221
+ async register(data) {
222
+ const registerData = { ...data };
223
+ if (!registerData.frontendBaseUrl && typeof window !== "undefined") {
224
+ registerData.frontendBaseUrl = process.env.FRONTEND_BASE_URL || process.env.NEXT_PUBLIC_FRONTEND_BASE_URL || process.env.REACT_APP_FRONTEND_BASE_URL || process.env.NEXT_PUBLIC_APP_URL || window.location.origin;
225
+ }
226
+ const response = await this.httpClient.post("/api/v1/auth/register", registerData);
227
+ if (response.success && response.message === "Registration data saved. Verification email sent. Please check your inbox.") {
228
+ return response;
229
+ }
230
+ throw new Error(response.message || "Registration failed");
231
+ }
232
+ async verify(data) {
233
+ const response = await this.httpClient.post("/api/v1/auth/verify", data);
234
+ if (response.success && response.token) {
235
+ this.token = response.token;
236
+ this.httpClient.setAuthToken(response.token);
237
+ this.saveTokenToStorage(response.token);
238
+ }
239
+ return response;
240
+ }
241
+ async verifyEmailToken(token) {
242
+ const response = await this.httpClient.get(`/api/v1/auth/verify-email?token=${token}`);
243
+ if (response.success && response.token) {
244
+ this.token = response.token;
245
+ this.httpClient.setAuthToken(response.token);
246
+ this.saveTokenToStorage(response.token);
247
+ }
248
+ return response;
249
+ }
250
+ async logout() {
251
+ this.token = null;
252
+ this.httpClient.removeAuthToken();
253
+ this.httpClient.removeCsrfToken();
254
+ this.removeTokenFromStorage();
255
+ }
256
+ async getProfile() {
257
+ if (!this.token) {
258
+ throw new Error("Not authenticated");
259
+ }
260
+ const response = await this.httpClient.get("/api/v1/user/me");
261
+ return response.user;
262
+ }
263
+ async updateProfile(data) {
264
+ if (!this.token) {
265
+ throw new Error("Not authenticated");
266
+ }
267
+ const response = await this.httpClient.post("/api/v1/user/update/user", data);
268
+ if (response.success && response.token) {
269
+ this.token = response.token;
270
+ this.httpClient.setAuthToken(response.token);
271
+ this.saveTokenToStorage(response.token);
272
+ }
273
+ return response;
274
+ }
275
+ async getAllUsers() {
276
+ if (!this.token) {
277
+ throw new Error("Not authenticated");
278
+ }
279
+ const response = await this.httpClient.get("/api/v1/user/all");
280
+ return response.users;
281
+ }
282
+ async getUserById(id) {
283
+ const response = await this.httpClient.get(`/api/v1/user/${id}`);
284
+ return response.user;
285
+ }
286
+ async forgotPassword(email) {
287
+ if (typeof window !== "undefined") {
288
+ process.env.FRONTEND_BASE_URL || process.env.NEXT_PUBLIC_FRONTEND_BASE_URL || process.env.REACT_APP_FRONTEND_BASE_URL || process.env.NEXT_PUBLIC_APP_URL || window.location.origin;
289
+ }
290
+ const response = await this.httpClient.post("/api/v1/auth/forgot-password", { email });
291
+ return response;
292
+ }
293
+ async resetPassword(token, password) {
294
+ const response = await this.httpClient.post("/api/v1/auth/reset-password", { token, password });
295
+ return response;
296
+ }
297
+ };
298
+
299
+ // src/node/auth-client.ts
300
+ var AuthClient = class extends AuthService {
301
+ constructor(config) {
302
+ super(config);
303
+ }
304
+ // Override methods that require browser-specific features
305
+ // For Node.js, token persistence must be handled manually
306
+ async register(data) {
307
+ const registerData = { ...data };
308
+ if (!registerData.frontendBaseUrl) {
309
+ registerData.frontendBaseUrl = process.env.FRONTEND_BASE_URL || process.env.NEXT_PUBLIC_FRONTEND_BASE_URL || process.env.REACT_APP_FRONTEND_BASE_URL;
310
+ }
311
+ const response = await this["httpClient"].post("/api/v1/auth/register", registerData);
312
+ if (response.success && response.message === "Registration data saved. Verification email sent. Please check your inbox.") {
313
+ return response;
314
+ }
315
+ throw new Error(response.message || "Registration failed");
316
+ }
317
+ async login(data) {
318
+ const response = await this["httpClient"].post("/api/v1/auth/login", data);
319
+ if (response.success && response.token) {
320
+ this["token"] = response.token;
321
+ this["httpClient"].setAuthToken(response.token);
322
+ return response;
323
+ }
324
+ if (response.success && response.message === "OTP sent to your email.") {
325
+ return response;
326
+ }
327
+ if (response.success && response.message === "OTP verified successfully." && response.token) {
328
+ this["token"] = response.token;
329
+ this["httpClient"].setAuthToken(response.token);
330
+ return response;
331
+ }
332
+ throw new Error(response.message || "Login failed");
333
+ }
334
+ async verify(data) {
335
+ const response = await this["httpClient"].post("/api/v1/auth/verify", data);
336
+ if (response.success && response.token) {
337
+ this["token"] = response.token;
338
+ this["httpClient"].setAuthToken(response.token);
339
+ }
340
+ return response;
341
+ }
342
+ async logout() {
343
+ this["token"] = null;
344
+ this["httpClient"].removeAuthToken();
345
+ }
346
+ async getProfile() {
347
+ if (!this["token"]) {
348
+ throw new Error("Not authenticated");
349
+ }
350
+ const response = await this["httpClient"].get("/api/v1/user/me");
351
+ return response.user;
352
+ }
353
+ async getUserById(id) {
354
+ const response = await this["httpClient"].get(`/api/v1/user/${id}`);
355
+ return response.user;
356
+ }
357
+ async updateProfile(data) {
358
+ if (!this["token"]) {
359
+ throw new Error("Not authenticated");
360
+ }
361
+ const response = await this["httpClient"].post("/api/v1/user/update/name", data);
362
+ if (response.success && response.token) {
363
+ this["token"] = response.token;
364
+ this["httpClient"].setAuthToken(response.token);
365
+ }
366
+ return response;
367
+ }
368
+ async getAllUsers() {
369
+ if (!this["token"]) {
370
+ throw new Error("Not authenticated");
371
+ }
372
+ const response = await this["httpClient"].get("/api/v1/user/all");
373
+ return response.users;
374
+ }
375
+ };
376
+
377
+ // src/nextjs/server-auth.ts
378
+ var NextServerAuth = class extends AuthClient {
379
+ constructor(config) {
380
+ super(config);
381
+ }
382
+ // Parse token from request headers
383
+ static parseTokenFromHeaders(headers) {
384
+ const authHeader = headers.get("authorization");
385
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
386
+ return null;
387
+ }
388
+ return authHeader.substring(7);
389
+ }
390
+ // Parse token from cookies
391
+ static parseTokenFromCookies(cookies) {
392
+ const cookieArray = cookies.split(";");
393
+ for (const cookie of cookieArray) {
394
+ const [name, value] = cookie.trim().split("=");
395
+ if (name === "auth_token") {
396
+ return decodeURIComponent(value);
397
+ }
398
+ }
399
+ return null;
400
+ }
401
+ // Parse token from Next.js request object
402
+ static parseTokenFromRequest(req) {
403
+ if (req.headers) {
404
+ const authHeader = req.headers.authorization || req.headers.Authorization;
405
+ if (authHeader && authHeader.startsWith("Bearer ")) {
406
+ return authHeader.substring(7);
407
+ }
408
+ }
409
+ if (req.cookies) {
410
+ return req.cookies.auth_token || null;
411
+ }
412
+ if (req.headers && req.headers.cookie) {
413
+ return this.parseTokenFromCookies(req.headers.cookie);
414
+ }
415
+ return null;
416
+ }
417
+ // Verify token and get user
418
+ async verifyToken(token) {
419
+ try {
420
+ this["httpClient"].setAuthToken(token);
421
+ const user = await this.getProfile();
422
+ return user;
423
+ } catch (error) {
424
+ console.error("Token verification failed:", error);
425
+ return null;
426
+ }
427
+ }
428
+ // Create authenticated client with token
429
+ static createAuthenticatedClient(config, token) {
430
+ const client = new NextServerAuth(config);
431
+ client["httpClient"].setAuthToken(token);
432
+ client["token"] = token;
433
+ return client;
434
+ }
435
+ };
436
+
437
+ exports.AuthClient = AuthClient;
438
+ exports.AuthService = AuthService;
439
+ exports.HttpClient = HttpClient;
440
+ exports.NextServerAuth = NextServerAuth;
441
+ //# sourceMappingURL=out.js.map
442
+ //# sourceMappingURL=index.next.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/http-client.ts","../src/core/auth-service.ts","../src/node/auth-client.ts","../src/nextjs/server-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import axios, { AxiosInstance, AxiosRequestConfig, AxiosError } from 'axios';\r\n\r\nexport class HttpClient {\r\n private axiosInstance: AxiosInstance;\r\n private csrfToken: string | null = null;\r\n\r\n constructor(baseUrl: string, defaultHeaders: Record<string, string> = {}) {\r\n this.axiosInstance = axios.create({\r\n baseURL: baseUrl.replace(/\\/$/, ''),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...defaultHeaders\r\n },\r\n withCredentials: true, // Include cookies for CSRF\r\n timeout: 30000 // 30 second timeout\r\n });\r\n\r\n // Request interceptor to add CSRF token\r\n this.axiosInstance.interceptors.request.use(\r\n (config) => {\r\n // Add CSRF token to mutating requests\r\n if (this.csrfToken && ['post', 'put', 'delete', 'patch'].includes(config.method?.toLowerCase() || '')) {\r\n config.headers['x-csrf-token'] = this.csrfToken;\r\n }\r\n return config;\r\n },\r\n (error) => Promise.reject(error)\r\n );\r\n\r\n // Response interceptor for error handling and CSRF token refresh\r\n this.axiosInstance.interceptors.response.use(\r\n (response) => response,\r\n async (error: AxiosError) => {\r\n const originalRequest = error.config as AxiosRequestConfig & { _retry?: boolean };\r\n\r\n // Handle CSRF token refresh on 403\r\n if (error.response?.status === 403 && !originalRequest._retry) {\r\n originalRequest._retry = true;\r\n\r\n try {\r\n await this.refreshCsrfToken();\r\n if (originalRequest.headers) {\r\n originalRequest.headers['x-csrf-token'] = this.csrfToken!;\r\n }\r\n return this.axiosInstance(originalRequest);\r\n } catch (refreshError) {\r\n return Promise.reject(refreshError);\r\n }\r\n }\r\n\r\n return Promise.reject(error);\r\n }\r\n );\r\n }\r\n\r\n public async get<T>(endpoint: string, headers?: Record<string, string>): Promise<T> {\r\n const response = await this.axiosInstance.get<T>(endpoint, { headers });\r\n return response.data;\r\n }\r\n\r\n public async post<T>(endpoint: string, data?: any, headers?: Record<string, string>): Promise<T> {\r\n const response = await this.axiosInstance.post<T>(endpoint, data, { headers });\r\n return response.data;\r\n }\r\n\r\n public async put<T>(endpoint: string, data?: any, headers?: Record<string, string>): Promise<T> {\r\n const response = await this.axiosInstance.put<T>(endpoint, data, { headers });\r\n return response.data;\r\n }\r\n\r\n public async delete<T>(endpoint: string, headers?: Record<string, string>): Promise<T> {\r\n const response = await this.axiosInstance.delete<T>(endpoint, { headers });\r\n return response.data;\r\n }\r\n\r\n public setAuthToken(token: string): void {\r\n this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`;\r\n }\r\n\r\n public removeAuthToken(): void {\r\n delete this.axiosInstance.defaults.headers.common['Authorization'];\r\n }\r\n\r\n public setCsrfToken(token: string): void {\r\n this.csrfToken = token;\r\n }\r\n\r\n public getCsrfToken(): string | null {\r\n return this.csrfToken;\r\n }\r\n\r\n public removeCsrfToken(): void {\r\n this.csrfToken = null;\r\n }\r\n\r\n private async refreshCsrfToken(): Promise<void> {\r\n try {\r\n const response = await this.axiosInstance.get<{ csrfToken: string }>('/api/v1/auth/csrf-token');\r\n this.csrfToken = response.data.csrfToken;\r\n } catch (error) {\r\n console.error('Failed to refresh CSRF token:', error);\r\n throw error;\r\n }\r\n }\r\n}","import { HttpClient } from './http-client';\r\nimport {\r\n AuthResponse,\r\n LoginData,\r\n VerifyData,\r\n UpdateUserData,\r\n User,\r\n AuthConfig,\r\n RegisterData,\r\n OAuthProvider,\r\n CsrfTokenResponse\r\n} from '../types';\r\n\r\nexport class AuthService {\r\n private httpClient: HttpClient;\r\n private config: AuthConfig;\r\n private token: string | null = null;\r\n\r\n constructor(config: AuthConfig) {\r\n this.config = {\r\n localStorageKey: 'auth_token',\r\n csrfEnabled: true,\r\n ...config\r\n };\r\n\r\n this.httpClient = new HttpClient(this.config.baseUrl);\r\n this.loadTokenFromStorage();\r\n\r\n // Initialize CSRF token if enabled\r\n if (this.config.csrfEnabled && typeof window !== 'undefined') {\r\n this.refreshCsrfToken();\r\n }\r\n }\r\n\r\n private loadTokenFromStorage(): void {\r\n if (typeof window !== 'undefined' && this.config.localStorageKey) {\r\n try {\r\n const token = localStorage.getItem(this.config.localStorageKey);\r\n if (token) {\r\n this.token = token;\r\n this.httpClient.setAuthToken(token);\r\n }\r\n } catch (error) {\r\n console.warn('Failed to load token from storage:', error);\r\n }\r\n }\r\n }\r\n\r\n private saveTokenToStorage(token: string): void {\r\n if (typeof window !== 'undefined' && this.config.localStorageKey) {\r\n try {\r\n localStorage.setItem(this.config.localStorageKey, token);\r\n } catch (error) {\r\n console.warn('Failed to save token to storage:', error);\r\n }\r\n }\r\n }\r\n\r\n private removeTokenFromStorage(): void {\r\n if (typeof window !== 'undefined' && this.config.localStorageKey) {\r\n try {\r\n localStorage.removeItem(this.config.localStorageKey);\r\n } catch (error) {\r\n console.warn('Failed to remove token from storage:', error);\r\n }\r\n }\r\n }\r\n\r\n public isAuthenticated(): boolean {\r\n return !!this.token;\r\n }\r\n\r\n public getToken(): string | null {\r\n return this.token;\r\n }\r\n\r\n public getCurrentUser(): User | null {\r\n if (!this.token) return null;\r\n\r\n try {\r\n const payload = JSON.parse(atob(this.token.split('.')[1]));\r\n return payload.user || null;\r\n } catch (error) {\r\n console.error('Failed to parse user from token:', error);\r\n return null;\r\n }\r\n }\r\n\r\n // CSRF Token Management\r\n public async refreshCsrfToken(): Promise<void> {\r\n if (!this.config.csrfEnabled) return;\r\n\r\n try {\r\n const response = await this.httpClient.get<CsrfTokenResponse>('/api/v1/auth/csrf-token');\r\n if (response.csrfToken) {\r\n this.httpClient.setCsrfToken(response.csrfToken);\r\n }\r\n } catch (error) {\r\n console.error('Failed to get CSRF token:', error);\r\n }\r\n }\r\n\r\n public getCsrfToken(): string | null {\r\n return this.httpClient.getCsrfToken();\r\n }\r\n\r\n // OAuth Methods\r\n public loginWithOAuth(provider: OAuthProvider): void {\r\n if (typeof window === 'undefined') {\r\n throw new Error('OAuth login is only available in browser environments');\r\n }\r\n\r\n const oauthUrl = `${this.config.baseUrl}/api/v1/auth/oauth/${provider}`;\r\n window.location.href = oauthUrl;\r\n }\r\n\r\n public linkOAuthProvider(provider: OAuthProvider): void {\r\n if (typeof window === 'undefined') {\r\n throw new Error('OAuth linking is only available in browser environments');\r\n }\r\n\r\n if (!this.token) {\r\n throw new Error('Must be authenticated to link OAuth provider');\r\n }\r\n\r\n const linkUrl = `${this.config.baseUrl}/api/v1/auth/oauth/${provider}/link`;\r\n window.location.href = linkUrl;\r\n }\r\n\r\n public async unlinkOAuthProvider(provider: OAuthProvider): Promise<AuthResponse> {\r\n if (!this.token) {\r\n throw new Error('Not authenticated');\r\n }\r\n\r\n const response = await this.httpClient.delete<AuthResponse>(\r\n `/api/v1/auth/oauth/${provider}/unlink`\r\n );\r\n return response;\r\n }\r\n\r\n // Standard Auth Methods\r\n public async login(data: LoginData): Promise<AuthResponse> {\r\n const response = await this.httpClient.post<AuthResponse>('/api/v1/auth/login', data);\r\n\r\n if (response.success && response.token) {\r\n this.token = response.token;\r\n this.httpClient.setAuthToken(response.token);\r\n this.saveTokenToStorage(response.token);\r\n return response;\r\n }\r\n\r\n if (response.success && response.message === 'OTP sent to your email.') {\r\n return response;\r\n }\r\n\r\n if (response.success && response.message === 'OTP verified successfully.' && response.token) {\r\n this.token = response.token;\r\n this.httpClient.setAuthToken(response.token);\r\n this.saveTokenToStorage(response.token);\r\n return response;\r\n }\r\n\r\n throw new Error(response.message || 'Login failed');\r\n }\r\n\r\n public async register(data: RegisterData): Promise<AuthResponse> {\r\n const registerData = { ...data };\r\n if (!registerData.frontendBaseUrl && typeof window !== 'undefined') {\r\n registerData.frontendBaseUrl =\r\n process.env.FRONTEND_BASE_URL ||\r\n process.env.NEXT_PUBLIC_FRONTEND_BASE_URL ||\r\n process.env.REACT_APP_FRONTEND_BASE_URL ||\r\n process.env.NEXT_PUBLIC_APP_URL ||\r\n window.location.origin;\r\n }\r\n\r\n const response = await this.httpClient.post<AuthResponse>('/api/v1/auth/register', registerData);\r\n\r\n if (response.success && response.message === 'Registration data saved. Verification email sent. Please check your inbox.') {\r\n return response;\r\n }\r\n\r\n throw new Error(response.message || 'Registration failed');\r\n }\r\n\r\n public async verify(data: VerifyData): Promise<AuthResponse> {\r\n const response = await this.httpClient.post<AuthResponse>('/api/v1/auth/verify', data);\r\n\r\n if (response.success && response.token) {\r\n this.token = response.token;\r\n this.httpClient.setAuthToken(response.token);\r\n this.saveTokenToStorage(response.token);\r\n }\r\n\r\n return response;\r\n }\r\n\r\n public async verifyEmailToken(token: string): Promise<AuthResponse> {\r\n const response = await this.httpClient.get<AuthResponse>(`/api/v1/auth/verify-email?token=${token}`);\r\n\r\n if (response.success && response.token) {\r\n this.token = response.token;\r\n this.httpClient.setAuthToken(response.token);\r\n this.saveTokenToStorage(response.token);\r\n }\r\n\r\n return response;\r\n }\r\n\r\n public async logout(): Promise<void> {\r\n this.token = null;\r\n this.httpClient.removeAuthToken();\r\n this.httpClient.removeCsrfToken();\r\n this.removeTokenFromStorage();\r\n }\r\n\r\n public async getProfile(): Promise<User> {\r\n if (!this.token) {\r\n throw new Error('Not authenticated');\r\n }\r\n\r\n const response = await this.httpClient.get<{ user: User }>('/api/v1/user/me');\r\n return response.user;\r\n }\r\n\r\n public async updateProfile(data: UpdateUserData): Promise<AuthResponse> {\r\n if (!this.token) {\r\n throw new Error('Not authenticated');\r\n }\r\n\r\n const response = await this.httpClient.post<AuthResponse>('/api/v1/user/update/user', data);\r\n\r\n if (response.success && response.token) {\r\n this.token = response.token;\r\n this.httpClient.setAuthToken(response.token);\r\n this.saveTokenToStorage(response.token);\r\n }\r\n\r\n return response;\r\n }\r\n\r\n public async getAllUsers(): Promise<User[]> {\r\n if (!this.token) {\r\n throw new Error('Not authenticated');\r\n }\r\n\r\n const response = await this.httpClient.get<{ users: User[] }>('/api/v1/user/all');\r\n return response.users;\r\n }\r\n\r\n public async getUserById(id: string): Promise<User> {\r\n const response = await this.httpClient.get<{ user: User }>(`/api/v1/user/${id}`);\r\n return response.user;\r\n }\r\n\r\n public async forgotPassword(email: string): Promise<AuthResponse> {\r\n let frontendBaseUrl: string | undefined;\r\n if (typeof window !== 'undefined') {\r\n frontendBaseUrl =\r\n process.env.FRONTEND_BASE_URL ||\r\n process.env.NEXT_PUBLIC_FRONTEND_BASE_URL ||\r\n process.env.REACT_APP_FRONTEND_BASE_URL ||\r\n process.env.NEXT_PUBLIC_APP_URL ||\r\n window.location.origin;\r\n }\r\n\r\n const response = await this.httpClient.post<AuthResponse>('/api/v1/auth/forgot-password', { email });\r\n return response;\r\n }\r\n\r\n public async resetPassword(token: string, password: string): Promise<AuthResponse> {\r\n const response = await this.httpClient.post<AuthResponse>('/api/v1/auth/reset-password', { token, password });\r\n return response;\r\n }\r\n}","import { AuthService } from '../core/auth-service';\r\nimport { \r\n AuthResponse, \r\n LoginData, \r\n VerifyData, \r\n UpdateUserData, \r\n User,\r\n AuthConfig,\r\n RegisterData\r\n} from '../types';\r\n\r\nexport class AuthClient extends AuthService {\r\n constructor(config: AuthConfig) {\r\n super(config);\r\n }\r\n\r\n // Override methods that require browser-specific features\r\n // For Node.js, token persistence must be handled manually\r\n \r\n public async register(data: RegisterData): Promise<AuthResponse> {\r\n // Automatically add frontend base URL if not provided\r\n const registerData = { ...data };\r\n if (!registerData.frontendBaseUrl) {\r\n // Check for environment variable\r\n registerData.frontendBaseUrl = \r\n process.env.FRONTEND_BASE_URL || \r\n process.env.NEXT_PUBLIC_FRONTEND_BASE_URL ||\r\n process.env.REACT_APP_FRONTEND_BASE_URL;\r\n }\r\n \r\n const response = await this['httpClient'].post<AuthResponse>('/api/v1/auth/register', registerData);\r\n \r\n if (response.success && response.message === 'Registration data saved. Verification email sent. Please check your inbox.') {\r\n return response;\r\n }\r\n \r\n throw new Error(response.message || 'Registration failed');\r\n }\r\n\r\n public async login(data: LoginData): Promise<AuthResponse> {\r\n const response = await this['httpClient'].post<AuthResponse>('/api/v1/auth/login', data);\r\n \r\n // Handle successful login with token\r\n if (response.success && response.token) {\r\n this['token'] = response.token;\r\n this['httpClient'].setAuthToken(response.token);\r\n // Note: In Node.js, you need to handle token persistence manually\r\n return response;\r\n }\r\n \r\n // Handle OTP sent response\r\n if (response.success && response.message === 'OTP sent to your email.') {\r\n return response;\r\n }\r\n \r\n // Handle verification response\r\n if (response.success && response.message === 'OTP verified successfully.' && response.token) {\r\n this['token'] = response.token;\r\n this['httpClient'].setAuthToken(response.token);\r\n // Note: In Node.js, you need to handle token persistence manually\r\n return response;\r\n }\r\n \r\n throw new Error(response.message || 'Login failed');\r\n }\r\n\r\n public async verify(data: VerifyData): Promise<AuthResponse> {\r\n const response = await this['httpClient'].post<AuthResponse>('/api/v1/auth/verify', data);\r\n \r\n if (response.success && response.token) {\r\n this['token'] = response.token;\r\n this['httpClient'].setAuthToken(response.token);\r\n // Note: In Node.js, you need to handle token persistence manually\r\n }\r\n \r\n return response;\r\n }\r\n\r\n public async logout(): Promise<void> {\r\n this['token'] = null;\r\n this['httpClient'].removeAuthToken();\r\n // Note: In Node.js, you need to handle token removal manually\r\n }\r\n\r\n public async getProfile(): Promise<User> {\r\n if (!this['token']) {\r\n throw new Error('Not authenticated');\r\n }\r\n \r\n const response = await this['httpClient'].get<{ user: User }>('/api/v1/user/me');\r\n return response.user;\r\n }\r\n\r\n public async getUserById(id: string): Promise<User> {\r\n const response = await this['httpClient'].get<{ user: User }>(`/api/v1/user/${id}`);\r\n return response.user;\r\n }\r\n\r\n public async updateProfile(data: UpdateUserData): Promise<AuthResponse> {\r\n if (!this['token']) {\r\n throw new Error('Not authenticated');\r\n }\r\n \r\n const response = await this['httpClient'].post<AuthResponse>('/api/v1/user/update/name', data);\r\n \r\n if (response.success && response.token) {\r\n this['token'] = response.token;\r\n this['httpClient'].setAuthToken(response.token);\r\n // Note: In Node.js, you need to handle token persistence manually\r\n }\r\n \r\n return response;\r\n }\r\n\r\n public async getAllUsers(): Promise<User[]> {\r\n if (!this['token']) {\r\n throw new Error('Not authenticated');\r\n }\r\n \r\n const response = await this['httpClient'].get<{ users: User[] }>('/api/v1/user/all');\r\n return response.users;\r\n }\r\n}","import { AuthClient } from '../node/auth-client';\r\nimport { AuthConfig, User, RegisterData } from '../types';\r\n\r\n// Server-side authentication utility for Next.js\r\nexport class NextServerAuth extends AuthClient {\r\n constructor(config: AuthConfig) {\r\n super(config);\r\n }\r\n\r\n // Parse token from request headers\r\n public static parseTokenFromHeaders(headers: Headers): string | null {\r\n const authHeader = headers.get('authorization');\r\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\r\n return null;\r\n }\r\n return authHeader.substring(7); // Remove 'Bearer ' prefix\r\n }\r\n\r\n // Parse token from cookies\r\n public static parseTokenFromCookies(cookies: string): string | null {\r\n const cookieArray = cookies.split(';');\r\n for (const cookie of cookieArray) {\r\n const [name, value] = cookie.trim().split('=');\r\n if (name === 'auth_token') {\r\n return decodeURIComponent(value);\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n // Parse token from Next.js request object\r\n public static parseTokenFromRequest(req: any): string | null {\r\n // Try to get token from headers first\r\n if (req.headers) {\r\n const authHeader = req.headers.authorization || req.headers.Authorization;\r\n if (authHeader && authHeader.startsWith('Bearer ')) {\r\n return authHeader.substring(7);\r\n }\r\n }\r\n\r\n // Try to get token from cookies\r\n if (req.cookies) {\r\n return req.cookies.auth_token || null;\r\n }\r\n\r\n // Try to get token from cookie header\r\n if (req.headers && req.headers.cookie) {\r\n return this.parseTokenFromCookies(req.headers.cookie);\r\n }\r\n\r\n return null;\r\n }\r\n\r\n // Verify token and get user\r\n public async verifyToken(token: string): Promise<User | null> {\r\n try {\r\n // Set the token for this request\r\n (this as any)['httpClient'].setAuthToken(token);\r\n \r\n // Get user profile to verify token\r\n const user = await this.getProfile();\r\n return user;\r\n } catch (error) {\r\n console.error('Token verification failed:', error);\r\n return null;\r\n }\r\n }\r\n\r\n // Create authenticated client with token\r\n public static createAuthenticatedClient(config: AuthConfig, token: string): NextServerAuth {\r\n const client = new NextServerAuth(config);\r\n (client as any)['httpClient'].setAuthToken(token);\r\n (client as any)['token'] = token;\r\n return client;\r\n }\r\n}"]}