@geekmidas/auth 0.0.1 → 0.0.3

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 ADDED
@@ -0,0 +1,362 @@
1
+ # @geekmidas/auth
2
+
3
+ A comprehensive authentication library providing JWT token management, secure storage, and client-side token handling for TypeScript applications.
4
+
5
+ ## Features
6
+
7
+ - **JWT Token Management**: Generate, verify, and refresh JWT access and refresh tokens
8
+ - **Multiple Storage Options**: LocalStorage, Memory, and Cache-based token storage
9
+ - **Automatic Token Refresh**: Seamless token refresh with expiration handling
10
+ - **Type-Safe**: Full TypeScript support with complete type inference
11
+ - **Framework Agnostic**: Works with any JavaScript framework or vanilla JS
12
+ - **OpenAuth Integration**: Built on top of @openauthjs/openauth for standards compliance
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pnpm add @geekmidas/auth
18
+ ```
19
+
20
+ ## Package Exports
21
+
22
+ The package provides multiple entry points for different use cases:
23
+
24
+ - `@geekmidas/auth` - Main client-side exports
25
+ - `@geekmidas/auth/client` - Client-side token management
26
+ - `@geekmidas/auth/server` - Server-side token management
27
+
28
+ ## Client-Side Usage
29
+
30
+ ### Basic Token Client
31
+
32
+ ```typescript
33
+ import { TokenClient, LocalStorageTokenStorage } from '@geekmidas/auth/client';
34
+
35
+ // Create a token client with localStorage
36
+ const client = new TokenClient({
37
+ storage: new LocalStorageTokenStorage(),
38
+ refreshEndpoint: '/api/auth/refresh',
39
+ onTokenRefresh: (tokens) => {
40
+ console.log('Tokens refreshed:', tokens);
41
+ },
42
+ onTokenExpired: () => {
43
+ console.log('Tokens expired, redirect to login');
44
+ window.location.href = '/login';
45
+ },
46
+ });
47
+
48
+ // Store tokens after login
49
+ await client.setTokens('access_token', 'refresh_token');
50
+
51
+ // Get a valid access token (automatically refreshes if expired)
52
+ const accessToken = await client.getValidAccessToken();
53
+
54
+ // Create authorization headers
55
+ const headers = await client.createValidAuthHeaders();
56
+ // Returns: { Authorization: 'Bearer access_token' }
57
+ ```
58
+
59
+ ### Token Storage Options
60
+
61
+ #### LocalStorage (Browser)
62
+
63
+ ```typescript
64
+ import { LocalStorageTokenStorage } from '@geekmidas/auth/client';
65
+
66
+ const storage = new LocalStorageTokenStorage(
67
+ 'my_access_token', // Custom access token key
68
+ 'my_refresh_token' // Custom refresh token key
69
+ );
70
+ ```
71
+
72
+ #### Memory Storage
73
+
74
+ ```typescript
75
+ import { MemoryTokenStorage } from '@geekmidas/auth/client';
76
+
77
+ // Ideal for server-side applications or testing
78
+ const storage = new MemoryTokenStorage();
79
+ ```
80
+
81
+ #### Cache Storage
82
+
83
+ ```typescript
84
+ import { CacheTokenStorage } from '@geekmidas/auth/client';
85
+ import { InMemoryCache } from '@geekmidas/cache/memory';
86
+
87
+ const cache = new InMemoryCache<string>();
88
+ const storage = new CacheTokenStorage(
89
+ cache,
90
+ 'access_token', // Access token key
91
+ 'refresh_token' // Refresh token key
92
+ );
93
+
94
+ // Supports TTL for automatic expiration
95
+ await storage.setAccessToken('token', 3600); // 1 hour TTL
96
+ ```
97
+
98
+ ### Token Validation
99
+
100
+ ```typescript
101
+ // Check if a token is expired
102
+ const isExpired = client.isTokenExpired(token);
103
+
104
+ // Get token expiration date
105
+ const expiration = client.getTokenExpiration(token);
106
+ console.log('Token expires at:', expiration);
107
+
108
+ // Get a valid token (refreshes automatically if needed)
109
+ const validToken = await client.getValidAccessToken();
110
+ ```
111
+
112
+ ### HTTP Client Integration
113
+
114
+ ```typescript
115
+ import { TokenClient } from '@geekmidas/auth/client';
116
+
117
+ class ApiClient {
118
+ constructor(private tokenClient: TokenClient) {}
119
+
120
+ async makeRequest(url: string, options: RequestInit = {}) {
121
+ const headers = await this.tokenClient.createValidAuthHeaders();
122
+
123
+ return fetch(url, {
124
+ ...options,
125
+ headers: {
126
+ ...options.headers,
127
+ ...headers,
128
+ },
129
+ });
130
+ }
131
+ }
132
+
133
+ const apiClient = new ApiClient(tokenClient);
134
+ const response = await apiClient.makeRequest('/api/users');
135
+ ```
136
+
137
+ ## Server-Side Usage
138
+
139
+ ### Token Manager
140
+
141
+ ```typescript
142
+ import { TokenManager } from '@geekmidas/auth/server';
143
+
144
+ const tokenManager = new TokenManager({
145
+ accessTokenSecret: process.env.ACCESS_TOKEN_SECRET!,
146
+ refreshTokenSecret: process.env.REFRESH_TOKEN_SECRET!,
147
+ accessTokenExpiresIn: '15m',
148
+ refreshTokenExpiresIn: '7d',
149
+ });
150
+
151
+ // Generate token pair
152
+ const tokens = tokenManager.generateTokenPair({
153
+ userId: 'user123',
154
+ email: 'user@example.com',
155
+ role: 'admin',
156
+ });
157
+
158
+ // Verify tokens
159
+ try {
160
+ const payload = tokenManager.verifyAccessToken(accessToken);
161
+ console.log('User ID:', payload.userId);
162
+ } catch (error) {
163
+ console.error('Invalid token:', error.message);
164
+ }
165
+
166
+ // Refresh access token
167
+ try {
168
+ const newAccessToken = tokenManager.refreshAccessToken(refreshToken);
169
+ } catch (error) {
170
+ console.error('Refresh failed:', error.message);
171
+ }
172
+ ```
173
+
174
+ ### Token Validation Middleware
175
+
176
+ ```typescript
177
+ import { TokenManager } from '@geekmidas/auth/server';
178
+
179
+ const tokenManager = new TokenManager({
180
+ accessTokenSecret: process.env.ACCESS_TOKEN_SECRET!,
181
+ refreshTokenSecret: process.env.REFRESH_TOKEN_SECRET!,
182
+ });
183
+
184
+ function authenticateToken(req: Request, res: Response, next: NextFunction) {
185
+ const authHeader = req.headers.authorization;
186
+ const token = authHeader && authHeader.split(' ')[1];
187
+
188
+ if (!token) {
189
+ return res.status(401).json({ error: 'Access token required' });
190
+ }
191
+
192
+ try {
193
+ const payload = tokenManager.verifyAccessToken(token);
194
+ req.user = payload;
195
+ next();
196
+ } catch (error) {
197
+ return res.status(403).json({ error: 'Invalid or expired token' });
198
+ }
199
+ }
200
+ ```
201
+
202
+ ## API Reference
203
+
204
+ ### TokenClient
205
+
206
+ The main client for managing tokens on the client-side.
207
+
208
+ #### Constructor Options
209
+
210
+ ```typescript
211
+ interface TokenClientOptions {
212
+ storage?: TokenStorage; // Token storage implementation
213
+ refreshEndpoint?: string; // API endpoint for token refresh
214
+ onTokenRefresh?: (tokens: { // Callback on successful refresh
215
+ accessToken: string;
216
+ refreshToken?: string;
217
+ }) => void;
218
+ onTokenExpired?: () => void; // Callback when tokens expire
219
+ }
220
+ ```
221
+
222
+ #### Methods
223
+
224
+ - `getAccessToken(): Promise<string | null>` - Get stored access token
225
+ - `getRefreshToken(): Promise<string | null>` - Get stored refresh token
226
+ - `setTokens(accessToken, refreshToken?, accessTtl?, refreshTtl?): Promise<void>` - Store tokens
227
+ - `clearTokens(): Promise<void>` - Clear all stored tokens
228
+ - `isTokenExpired(token: string): boolean` - Check if token is expired
229
+ - `getTokenExpiration(token: string): Date | null` - Get token expiration date
230
+ - `refreshTokens(): Promise<boolean>` - Refresh tokens via API
231
+ - `getValidAccessToken(): Promise<string | null>` - Get valid token (auto-refresh)
232
+ - `createAuthHeaders(): Promise<Record<string, string>>` - Create auth headers
233
+ - `createValidAuthHeaders(): Promise<Record<string, string>>` - Create auth headers with valid token
234
+
235
+ ### TokenStorage Interface
236
+
237
+ ```typescript
238
+ interface TokenStorage {
239
+ getAccessToken(): Promise<string | null> | string | null;
240
+ setAccessToken(token: string, ttl?: number): Promise<void> | void;
241
+ getRefreshToken(): Promise<string | null> | string | null;
242
+ setRefreshToken(token: string, ttl?: number): Promise<void> | void;
243
+ clearTokens(): Promise<void> | void;
244
+ }
245
+ ```
246
+
247
+ ### TokenManager
248
+
249
+ Server-side JWT token management.
250
+
251
+ #### Constructor Options
252
+
253
+ ```typescript
254
+ interface TokenManagerOptions {
255
+ accessTokenSecret: string; // Secret for signing access tokens
256
+ refreshTokenSecret: string; // Secret for signing refresh tokens
257
+ accessTokenExpiresIn?: string; // Access token expiration (default: '15m')
258
+ refreshTokenExpiresIn?: string; // Refresh token expiration (default: '7d')
259
+ }
260
+ ```
261
+
262
+ #### Methods
263
+
264
+ - `generateTokenPair(payload: TokenPayload): TokenPair` - Generate access and refresh tokens
265
+ - `verifyAccessToken(token: string): DecodedToken` - Verify and decode access token
266
+ - `verifyRefreshToken(token: string): DecodedToken` - Verify and decode refresh token
267
+ - `refreshAccessToken(refreshToken: string): string` - Generate new access token from refresh token
268
+ - `decodeToken(token: string): DecodedToken | null` - Decode token without verification
269
+ - `isTokenExpired(token: string): boolean` - Check if token is expired
270
+ - `getTokenExpiration(token: string): Date | null` - Get token expiration date
271
+
272
+ ### Types
273
+
274
+ ```typescript
275
+ interface TokenPayload {
276
+ userId: string;
277
+ email?: string;
278
+ [key: string]: any;
279
+ }
280
+
281
+ interface TokenPair {
282
+ accessToken: string;
283
+ refreshToken: string;
284
+ }
285
+
286
+ interface DecodedToken extends TokenPayload {
287
+ iat: number; // Issued at
288
+ exp: number; // Expiration time
289
+ }
290
+ ```
291
+
292
+ ## Error Handling
293
+
294
+ The library provides descriptive error messages for common scenarios:
295
+
296
+ ```typescript
297
+ try {
298
+ const payload = tokenManager.verifyAccessToken(token);
299
+ } catch (error) {
300
+ if (error.message.includes('Invalid access token')) {
301
+ // Handle invalid token
302
+ } else if (error.message.includes('expired')) {
303
+ // Handle expired token
304
+ }
305
+ }
306
+ ```
307
+
308
+ ## Security Best Practices
309
+
310
+ 1. **Use Strong Secrets**: Ensure your JWT secrets are cryptographically secure and different for access and refresh tokens.
311
+
312
+ 2. **Short Access Token Expiration**: Keep access tokens short-lived (15 minutes recommended).
313
+
314
+ 3. **Secure Token Storage**: Use appropriate storage based on your environment:
315
+ - Browser: LocalStorage or secure cookies
316
+ - Server: Memory or secure cache
317
+ - Mobile: Secure keychain/keystore
318
+
319
+ 4. **HTTPS Only**: Always use HTTPS in production to prevent token interception.
320
+
321
+ 5. **Token Rotation**: Implement refresh token rotation for enhanced security.
322
+
323
+ ## Testing
324
+
325
+ The package includes comprehensive test utilities:
326
+
327
+ ```typescript
328
+ import { MemoryTokenStorage, TokenClient } from '@geekmidas/auth/client';
329
+
330
+ // Use memory storage for tests
331
+ const storage = new MemoryTokenStorage();
332
+ const client = new TokenClient({ storage });
333
+
334
+ // Mock refresh endpoint with MSW
335
+ import { http, HttpResponse } from 'msw';
336
+
337
+ const server = setupServer(
338
+ http.post('/auth/refresh', () => {
339
+ return HttpResponse.json({
340
+ accessToken: 'new-access-token',
341
+ refreshToken: 'new-refresh-token',
342
+ });
343
+ }),
344
+ );
345
+ ```
346
+
347
+ ## Migration Guide
348
+
349
+ ### From v0.0.x
350
+
351
+ The auth package is currently in initial development. Breaking changes may occur between minor versions until v1.0.0.
352
+
353
+ ## Dependencies
354
+
355
+ - `@openauthjs/openauth` - OpenAuth integration
356
+ - `@geekmidas/cache` - Cache storage support
357
+ - `jsonwebtoken` - JWT token operations
358
+ - `@types/ms` - Time duration types
359
+
360
+ ## License
361
+
362
+ MIT License - see the LICENSE file for details.
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,70 @@
1
+ import { Cache } from "@geekmidas/cache";
2
+
3
+ //#region src/client.d.ts
4
+ interface TokenStorage {
5
+ getAccessToken(): Promise<string | null> | string | null;
6
+ setAccessToken(token: string, ttl?: number): Promise<void> | void;
7
+ getRefreshToken(): Promise<string | null> | string | null;
8
+ setRefreshToken(token: string, ttl?: number): Promise<void> | void;
9
+ clearTokens(): Promise<void> | void;
10
+ }
11
+ declare class LocalStorageTokenStorage implements TokenStorage {
12
+ private accessTokenKey;
13
+ private refreshTokenKey;
14
+ constructor(accessTokenKey?: string, refreshTokenKey?: string);
15
+ getAccessToken(): string | null;
16
+ setAccessToken(token: string, ttl?: number): void;
17
+ getRefreshToken(): string | null;
18
+ setRefreshToken(token: string, ttl?: number): void;
19
+ clearTokens(): void;
20
+ }
21
+ declare class MemoryTokenStorage implements TokenStorage {
22
+ private accessToken;
23
+ private refreshToken;
24
+ getAccessToken(): string | null;
25
+ setAccessToken(token: string, ttl?: number): void;
26
+ getRefreshToken(): string | null;
27
+ setRefreshToken(token: string, ttl?: number): void;
28
+ clearTokens(): void;
29
+ }
30
+ interface TokenClientOptions {
31
+ storage?: TokenStorage;
32
+ refreshEndpoint?: string;
33
+ onTokenRefresh?: (tokens: {
34
+ accessToken: string;
35
+ refreshToken?: string;
36
+ }) => void;
37
+ onTokenExpired?: () => void;
38
+ }
39
+ declare class TokenClient {
40
+ private storage;
41
+ private refreshEndpoint?;
42
+ private onTokenRefresh?;
43
+ private onTokenExpired?;
44
+ constructor(options?: TokenClientOptions);
45
+ getAccessToken(): Promise<string | null>;
46
+ getRefreshToken(): Promise<string | null>;
47
+ setTokens(accessToken: string, refreshToken?: string, accessTtl?: number, refreshTtl?: number): Promise<void>;
48
+ clearTokens(): Promise<void>;
49
+ isTokenExpired(token: string): boolean;
50
+ getTokenExpiration(token: string): Date | null;
51
+ refreshTokens(): Promise<boolean>;
52
+ getValidAccessToken(): Promise<string | null>;
53
+ createAuthHeaders(): Promise<Record<string, string>>;
54
+ createValidAuthHeaders(): Promise<Record<string, string>>;
55
+ }
56
+ //#endregion
57
+ //#region src/cacheTokenStorage.d.ts
58
+ declare class CacheTokenStorage implements TokenStorage {
59
+ private cache;
60
+ private accessTokenKey;
61
+ private refreshTokenKey;
62
+ constructor(cache: Cache<string>, accessTokenKey?: string, refreshTokenKey?: string);
63
+ getAccessToken(): Promise<string | null>;
64
+ setAccessToken(token: string, ttl?: number): Promise<void>;
65
+ getRefreshToken(): Promise<string | null>;
66
+ setRefreshToken(token: string, ttl?: number): Promise<void>;
67
+ clearTokens(): Promise<void>;
68
+ }
69
+ //#endregion
70
+ export { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage };
@@ -0,0 +1,70 @@
1
+ import { Cache } from "@geekmidas/cache";
2
+
3
+ //#region src/client.d.ts
4
+ interface TokenStorage {
5
+ getAccessToken(): Promise<string | null> | string | null;
6
+ setAccessToken(token: string, ttl?: number): Promise<void> | void;
7
+ getRefreshToken(): Promise<string | null> | string | null;
8
+ setRefreshToken(token: string, ttl?: number): Promise<void> | void;
9
+ clearTokens(): Promise<void> | void;
10
+ }
11
+ declare class LocalStorageTokenStorage implements TokenStorage {
12
+ private accessTokenKey;
13
+ private refreshTokenKey;
14
+ constructor(accessTokenKey?: string, refreshTokenKey?: string);
15
+ getAccessToken(): string | null;
16
+ setAccessToken(token: string, ttl?: number): void;
17
+ getRefreshToken(): string | null;
18
+ setRefreshToken(token: string, ttl?: number): void;
19
+ clearTokens(): void;
20
+ }
21
+ declare class MemoryTokenStorage implements TokenStorage {
22
+ private accessToken;
23
+ private refreshToken;
24
+ getAccessToken(): string | null;
25
+ setAccessToken(token: string, ttl?: number): void;
26
+ getRefreshToken(): string | null;
27
+ setRefreshToken(token: string, ttl?: number): void;
28
+ clearTokens(): void;
29
+ }
30
+ interface TokenClientOptions {
31
+ storage?: TokenStorage;
32
+ refreshEndpoint?: string;
33
+ onTokenRefresh?: (tokens: {
34
+ accessToken: string;
35
+ refreshToken?: string;
36
+ }) => void;
37
+ onTokenExpired?: () => void;
38
+ }
39
+ declare class TokenClient {
40
+ private storage;
41
+ private refreshEndpoint?;
42
+ private onTokenRefresh?;
43
+ private onTokenExpired?;
44
+ constructor(options?: TokenClientOptions);
45
+ getAccessToken(): Promise<string | null>;
46
+ getRefreshToken(): Promise<string | null>;
47
+ setTokens(accessToken: string, refreshToken?: string, accessTtl?: number, refreshTtl?: number): Promise<void>;
48
+ clearTokens(): Promise<void>;
49
+ isTokenExpired(token: string): boolean;
50
+ getTokenExpiration(token: string): Date | null;
51
+ refreshTokens(): Promise<boolean>;
52
+ getValidAccessToken(): Promise<string | null>;
53
+ createAuthHeaders(): Promise<Record<string, string>>;
54
+ createValidAuthHeaders(): Promise<Record<string, string>>;
55
+ }
56
+ //#endregion
57
+ //#region src/cacheTokenStorage.d.ts
58
+ declare class CacheTokenStorage implements TokenStorage {
59
+ private cache;
60
+ private accessTokenKey;
61
+ private refreshTokenKey;
62
+ constructor(cache: Cache<string>, accessTokenKey?: string, refreshTokenKey?: string);
63
+ getAccessToken(): Promise<string | null>;
64
+ setAccessToken(token: string, ttl?: number): Promise<void>;
65
+ getRefreshToken(): Promise<string | null>;
66
+ setRefreshToken(token: string, ttl?: number): Promise<void>;
67
+ clearTokens(): Promise<void>;
68
+ }
69
+ //#endregion
70
+ export { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage };
@@ -0,0 +1,2 @@
1
+ import { CacheTokenStorage } from "./cacheTokenStorage-yNUpDD8W.cjs";
2
+ export { CacheTokenStorage };
@@ -0,0 +1,2 @@
1
+ import { CacheTokenStorage } from "./cacheTokenStorage-BlpcZwef.mjs";
2
+ export { CacheTokenStorage };
@@ -0,0 +1,2 @@
1
+ import { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage } from "./cacheTokenStorage-yNUpDD8W.cjs";
2
+ export { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage };
@@ -0,0 +1,2 @@
1
+ import { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage } from "./cacheTokenStorage-BlpcZwef.mjs";
2
+ export { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage };
@@ -0,0 +1,3 @@
1
+ import { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage } from "./cacheTokenStorage-yNUpDD8W.cjs";
2
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-mpzJKLvX.cjs";
3
+ export { CacheTokenStorage, DecodedToken, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenManager, TokenManagerOptions, TokenPair, TokenPayload, TokenStorage };
@@ -0,0 +1,3 @@
1
+ import { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage } from "./cacheTokenStorage-BlpcZwef.mjs";
2
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-CCcFk2Py.mjs";
3
+ export { CacheTokenStorage, DecodedToken, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenManager, TokenManagerOptions, TokenPair, TokenPayload, TokenStorage };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,3 @@
1
+ import { CacheTokenStorage } from "./cacheTokenStorage-yNUpDD8W.cjs";
2
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-mpzJKLvX.cjs";
3
+ export { CacheTokenStorage, DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
@@ -0,0 +1,3 @@
1
+ import { CacheTokenStorage } from "./cacheTokenStorage-BlpcZwef.mjs";
2
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-CCcFk2Py.mjs";
3
+ export { CacheTokenStorage, DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
@@ -0,0 +1,38 @@
1
+ import ms from "ms";
2
+
3
+ //#region src/tokenManager.d.ts
4
+ interface TokenPayload {
5
+ userId: string;
6
+ email?: string;
7
+ [key: string]: any;
8
+ }
9
+ interface TokenPair {
10
+ accessToken: string;
11
+ refreshToken: string;
12
+ }
13
+ interface TokenManagerOptions {
14
+ accessTokenSecret: string;
15
+ refreshTokenSecret: string;
16
+ accessTokenExpiresIn?: ms.StringValue;
17
+ refreshTokenExpiresIn?: ms.StringValue;
18
+ }
19
+ interface DecodedToken extends TokenPayload {
20
+ iat: number;
21
+ exp: number;
22
+ }
23
+ declare class TokenManager {
24
+ private accessTokenSecret;
25
+ private refreshTokenSecret;
26
+ private accessTokenExpiresIn;
27
+ private refreshTokenExpiresIn;
28
+ constructor(options: TokenManagerOptions);
29
+ generateTokenPair(payload: TokenPayload): TokenPair;
30
+ verifyAccessToken(token: string): DecodedToken;
31
+ verifyRefreshToken(token: string): DecodedToken;
32
+ refreshAccessToken(refreshToken: string): string;
33
+ decodeToken(token: string): DecodedToken | null;
34
+ isTokenExpired(token: string): boolean;
35
+ getTokenExpiration(token: string): Date | null;
36
+ }
37
+ //#endregion
38
+ export { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
@@ -0,0 +1,38 @@
1
+ import ms from "ms";
2
+
3
+ //#region src/tokenManager.d.ts
4
+ interface TokenPayload {
5
+ userId: string;
6
+ email?: string;
7
+ [key: string]: any;
8
+ }
9
+ interface TokenPair {
10
+ accessToken: string;
11
+ refreshToken: string;
12
+ }
13
+ interface TokenManagerOptions {
14
+ accessTokenSecret: string;
15
+ refreshTokenSecret: string;
16
+ accessTokenExpiresIn?: ms.StringValue;
17
+ refreshTokenExpiresIn?: ms.StringValue;
18
+ }
19
+ interface DecodedToken extends TokenPayload {
20
+ iat: number;
21
+ exp: number;
22
+ }
23
+ declare class TokenManager {
24
+ private accessTokenSecret;
25
+ private refreshTokenSecret;
26
+ private accessTokenExpiresIn;
27
+ private refreshTokenExpiresIn;
28
+ constructor(options: TokenManagerOptions);
29
+ generateTokenPair(payload: TokenPayload): TokenPair;
30
+ verifyAccessToken(token: string): DecodedToken;
31
+ verifyRefreshToken(token: string): DecodedToken;
32
+ refreshAccessToken(refreshToken: string): string;
33
+ decodeToken(token: string): DecodedToken | null;
34
+ isTokenExpired(token: string): boolean;
35
+ getTokenExpiration(token: string): Date | null;
36
+ }
37
+ //#endregion
38
+ export { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
@@ -0,0 +1,2 @@
1
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-mpzJKLvX.cjs";
2
+ export { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
@@ -0,0 +1,2 @@
1
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-CCcFk2Py.mjs";
2
+ export { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@geekmidas/auth",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
7
+ "types": "./dist/index.d.ts",
7
8
  "import": "./dist/index.mjs",
8
- "require": "./dist/index.cjs",
9
- "types": "./src/index.ts"
9
+ "require": "./dist/index.cjs"
10
10
  },
11
11
  "./server": {
12
+ "types": "./dist/server.d.ts",
12
13
  "import": "./dist/server.mjs",
13
- "require": "./dist/server.cjs",
14
- "types": "./src/server.ts"
14
+ "require": "./dist/server.cjs"
15
15
  },
16
16
  "./client": {
17
+ "types": "./dist/client.d.ts",
17
18
  "import": "./dist/client.mjs",
18
- "require": "./dist/client.cjs",
19
- "types": "./src/client.ts"
19
+ "require": "./dist/client.cjs"
20
20
  }
21
21
  },
22
22
  "publishConfig": {
@@ -27,7 +27,7 @@
27
27
  "@openauthjs/openauth": "~0.4.3",
28
28
  "jsonwebtoken": "^9.0.2",
29
29
  "@types/ms": "~2.1.0",
30
- "@geekmidas/cache": "0.0.3"
30
+ "@geekmidas/cache": "0.0.6"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/jsonwebtoken": "^9.0.5"
@@ -15,32 +15,32 @@ describe('CacheTokenStorage', () => {
15
15
  describe('access token operations', () => {
16
16
  it('should store and retrieve access token', async () => {
17
17
  await storage.setAccessToken('test-access-token');
18
-
18
+
19
19
  const token = await storage.getAccessToken();
20
-
20
+
21
21
  expect(token).toBe('test-access-token');
22
22
  });
23
23
 
24
24
  it('should return null when no access token exists', async () => {
25
25
  const token = await storage.getAccessToken();
26
-
26
+
27
27
  expect(token).toBeNull();
28
28
  });
29
29
 
30
30
  it('should store access token with TTL', async () => {
31
31
  await storage.setAccessToken('test-access-token', 3600);
32
-
32
+
33
33
  const token = await storage.getAccessToken();
34
-
34
+
35
35
  expect(token).toBe('test-access-token');
36
36
  });
37
37
 
38
38
  it('should overwrite existing access token', async () => {
39
39
  await storage.setAccessToken('first-token');
40
40
  await storage.setAccessToken('second-token');
41
-
41
+
42
42
  const token = await storage.getAccessToken();
43
-
43
+
44
44
  expect(token).toBe('second-token');
45
45
  });
46
46
  });
@@ -48,32 +48,32 @@ describe('CacheTokenStorage', () => {
48
48
  describe('refresh token operations', () => {
49
49
  it('should store and retrieve refresh token', async () => {
50
50
  await storage.setRefreshToken('test-refresh-token');
51
-
51
+
52
52
  const token = await storage.getRefreshToken();
53
-
53
+
54
54
  expect(token).toBe('test-refresh-token');
55
55
  });
56
56
 
57
57
  it('should return null when no refresh token exists', async () => {
58
58
  const token = await storage.getRefreshToken();
59
-
59
+
60
60
  expect(token).toBeNull();
61
61
  });
62
62
 
63
63
  it('should store refresh token with TTL', async () => {
64
64
  await storage.setRefreshToken('test-refresh-token', 7200);
65
-
65
+
66
66
  const token = await storage.getRefreshToken();
67
-
67
+
68
68
  expect(token).toBe('test-refresh-token');
69
69
  });
70
70
 
71
71
  it('should overwrite existing refresh token', async () => {
72
72
  await storage.setRefreshToken('first-refresh-token');
73
73
  await storage.setRefreshToken('second-refresh-token');
74
-
74
+
75
75
  const token = await storage.getRefreshToken();
76
-
76
+
77
77
  expect(token).toBe('second-refresh-token');
78
78
  });
79
79
  });
@@ -82,10 +82,10 @@ describe('CacheTokenStorage', () => {
82
82
  it('should store both tokens independently', async () => {
83
83
  await storage.setAccessToken('access-token');
84
84
  await storage.setRefreshToken('refresh-token');
85
-
85
+
86
86
  const accessToken = await storage.getAccessToken();
87
87
  const refreshToken = await storage.getRefreshToken();
88
-
88
+
89
89
  expect(accessToken).toBe('access-token');
90
90
  expect(refreshToken).toBe('refresh-token');
91
91
  });
@@ -93,24 +93,24 @@ describe('CacheTokenStorage', () => {
93
93
  it('should clear both tokens', async () => {
94
94
  await storage.setAccessToken('access-token');
95
95
  await storage.setRefreshToken('refresh-token');
96
-
96
+
97
97
  await storage.clearTokens();
98
-
98
+
99
99
  const accessToken = await storage.getAccessToken();
100
100
  const refreshToken = await storage.getRefreshToken();
101
-
101
+
102
102
  expect(accessToken).toBeNull();
103
103
  expect(refreshToken).toBeNull();
104
104
  });
105
105
 
106
106
  it('should clear tokens when some are missing', async () => {
107
107
  await storage.setAccessToken('access-token');
108
-
108
+
109
109
  await storage.clearTokens();
110
-
110
+
111
111
  const accessToken = await storage.getAccessToken();
112
112
  const refreshToken = await storage.getRefreshToken();
113
-
113
+
114
114
  expect(accessToken).toBeNull();
115
115
  expect(refreshToken).toBeNull();
116
116
  });
@@ -177,7 +177,7 @@ describe('CacheTokenStorage', () => {
177
177
  it('should work with multiple cache instances', async () => {
178
178
  const cache1 = new InMemoryCache<string>();
179
179
  const cache2 = new InMemoryCache<string>();
180
-
180
+
181
181
  const storage1 = new CacheTokenStorage(cache1);
182
182
  const storage2 = new CacheTokenStorage(cache2);
183
183
 
@@ -210,4 +210,4 @@ describe('CacheTokenStorage', () => {
210
210
  expect(refreshToken).toBe('initial-refresh');
211
211
  });
212
212
  });
213
- });
213
+ });
package/src/index.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export * from './tokenManager.js';
2
2
  export * from './client.js';
3
- export * from './cacheTokenStorage.js';
3
+ export * from './cacheTokenStorage.js';
package/src/server.ts CHANGED
@@ -6,6 +6,4 @@ export {
6
6
  type DecodedToken,
7
7
  } from './tokenManager.js';
8
8
 
9
- export {
10
- CacheTokenStorage,
11
- } from './cacheTokenStorage.js';
9
+ export { CacheTokenStorage } from './cacheTokenStorage.js';