@dotpress/auth 1.3.2 → 2.0.0-alpha.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.
@@ -1,466 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import { getCookieSettings, setAuthCookies, clearAuthCookies, detectAuthMode, extractTokensFromRequest, extractAccessToken, calculateExpiration, } from '../../lib/cookies.js';
3
- import { setSettings } from '../../lib/settings.js';
4
- describe('Cookie Utilities', () => {
5
- beforeEach(() => {
6
- // Reset settings before each test
7
- setSettings({
8
- keys: {
9
- secretKey: 'test-secret',
10
- publicKey: 'test-public',
11
- },
12
- dataProvider: {
13
- storeRefreshToken: vi.fn(),
14
- findRefreshToken: vi.fn(),
15
- markRefreshTokenAsUsed: vi.fn(),
16
- revokeTokens: vi.fn(),
17
- findUserById: vi.fn(),
18
- findUserIdentifiers: vi.fn(),
19
- },
20
- });
21
- });
22
- describe('getCookieSettings', () => {
23
- it('should return default settings when no cookies config provided', () => {
24
- const settings = getCookieSettings();
25
- expect(settings).toMatchObject({
26
- enabled: false,
27
- httpOnly: true,
28
- secure: expect.any(Boolean),
29
- sameSite: 'lax',
30
- path: '/',
31
- accessTokenName: 'dotpress_access_token',
32
- refreshTokenName: 'dotpress_refresh_token',
33
- accessTokenInCookie: false,
34
- });
35
- });
36
- it('should merge custom settings with defaults', () => {
37
- setSettings({
38
- keys: {
39
- secretKey: 'test-secret',
40
- publicKey: 'test-public',
41
- },
42
- dataProvider: {},
43
- cookies: {
44
- enabled: true,
45
- domain: '.example.com',
46
- accessTokenName: 'custom_access',
47
- },
48
- });
49
- const settings = getCookieSettings();
50
- expect(settings).toMatchObject({
51
- enabled: true,
52
- domain: '.example.com',
53
- accessTokenName: 'custom_access',
54
- refreshTokenName: 'dotpress_refresh_token', // Default
55
- });
56
- });
57
- });
58
- describe('setAuthCookies', () => {
59
- it('should not set cookies when cookies are disabled', () => {
60
- // Ensure cookies are disabled
61
- setSettings({
62
- keys: {
63
- secretKey: 'test-secret',
64
- publicKey: 'test-public',
65
- },
66
- dataProvider: {},
67
- cookies: {
68
- enabled: false,
69
- },
70
- });
71
- const mockRes = {
72
- cookie: vi.fn(),
73
- };
74
- setAuthCookies(mockRes, { accessToken: 'acc-token', refreshToken: 'ref-token' }, 3600);
75
- expect(mockRes.cookie).not.toHaveBeenCalled();
76
- });
77
- it('should set refresh token cookie when enabled', () => {
78
- setSettings({
79
- keys: {
80
- secretKey: 'test-secret',
81
- publicKey: 'test-public',
82
- },
83
- dataProvider: {},
84
- cookies: {
85
- enabled: true,
86
- secure: false,
87
- },
88
- });
89
- const mockRes = {
90
- cookie: vi.fn(),
91
- };
92
- setAuthCookies(mockRes, { accessToken: 'acc-token', refreshToken: 'ref-token' }, 3600);
93
- expect(mockRes.cookie).toHaveBeenCalledWith('dotpress_refresh_token', 'ref-token', expect.objectContaining({
94
- httpOnly: true,
95
- secure: false,
96
- sameSite: 'lax',
97
- path: '/',
98
- maxAge: 3600000,
99
- }));
100
- // Access token should NOT be set by default
101
- expect(mockRes.cookie).toHaveBeenCalledTimes(1);
102
- });
103
- it('should set both cookies when accessTokenInCookie is true', () => {
104
- setSettings({
105
- keys: {
106
- secretKey: 'test-secret',
107
- publicKey: 'test-public',
108
- },
109
- dataProvider: {},
110
- cookies: {
111
- enabled: true,
112
- secure: false,
113
- accessTokenInCookie: true,
114
- },
115
- });
116
- const mockRes = {
117
- cookie: vi.fn(),
118
- };
119
- setAuthCookies(mockRes, { accessToken: 'acc-token', refreshToken: 'ref-token' }, 3600);
120
- expect(mockRes.cookie).toHaveBeenCalledTimes(2);
121
- expect(mockRes.cookie).toHaveBeenCalledWith('dotpress_access_token', 'acc-token', expect.any(Object));
122
- expect(mockRes.cookie).toHaveBeenCalledWith('dotpress_refresh_token', 'ref-token', expect.any(Object));
123
- });
124
- it('should use custom cookie names', () => {
125
- setSettings({
126
- keys: {
127
- secretKey: 'test-secret',
128
- publicKey: 'test-public',
129
- },
130
- dataProvider: {},
131
- cookies: {
132
- enabled: true,
133
- secure: false,
134
- accessTokenName: 'my_access',
135
- refreshTokenName: 'my_refresh',
136
- },
137
- });
138
- const mockRes = {
139
- cookie: vi.fn(),
140
- };
141
- setAuthCookies(mockRes, { accessToken: 'acc-token', refreshToken: 'ref-token' }, 3600);
142
- expect(mockRes.cookie).toHaveBeenCalledWith('my_refresh', 'ref-token', expect.any(Object));
143
- });
144
- it('should set domain when configured', () => {
145
- setSettings({
146
- keys: {
147
- secretKey: 'test-secret',
148
- publicKey: 'test-public',
149
- },
150
- dataProvider: {},
151
- cookies: {
152
- enabled: true,
153
- secure: false,
154
- domain: '.example.com',
155
- },
156
- });
157
- const mockRes = {
158
- cookie: vi.fn(),
159
- };
160
- setAuthCookies(mockRes, { accessToken: 'acc-token', refreshToken: 'ref-token' }, 3600);
161
- expect(mockRes.cookie).toHaveBeenCalledWith('dotpress_refresh_token', 'ref-token', expect.objectContaining({
162
- domain: '.example.com',
163
- }));
164
- });
165
- });
166
- describe('clearAuthCookies', () => {
167
- it('should not clear cookies when disabled', () => {
168
- // Ensure cookies are disabled
169
- setSettings({
170
- keys: {
171
- secretKey: 'test-secret',
172
- publicKey: 'test-public',
173
- },
174
- dataProvider: {},
175
- cookies: {
176
- enabled: false,
177
- },
178
- });
179
- const mockRes = {
180
- clearCookie: vi.fn(),
181
- };
182
- clearAuthCookies(mockRes);
183
- expect(mockRes.clearCookie).not.toHaveBeenCalled();
184
- });
185
- it('should clear refresh token cookie when enabled', () => {
186
- setSettings({
187
- keys: {
188
- secretKey: 'test-secret',
189
- publicKey: 'test-public',
190
- },
191
- dataProvider: {},
192
- cookies: {
193
- enabled: true,
194
- secure: false,
195
- },
196
- });
197
- const mockRes = {
198
- clearCookie: vi.fn(),
199
- };
200
- clearAuthCookies(mockRes);
201
- expect(mockRes.clearCookie).toHaveBeenCalledWith('dotpress_refresh_token', expect.objectContaining({
202
- httpOnly: true,
203
- secure: false,
204
- sameSite: 'lax',
205
- path: '/',
206
- }));
207
- });
208
- it('should clear both cookies when accessTokenInCookie is true', () => {
209
- setSettings({
210
- keys: {
211
- secretKey: 'test-secret',
212
- publicKey: 'test-public',
213
- },
214
- dataProvider: {},
215
- cookies: {
216
- enabled: true,
217
- secure: false,
218
- accessTokenInCookie: true,
219
- },
220
- });
221
- const mockRes = {
222
- clearCookie: vi.fn(),
223
- };
224
- clearAuthCookies(mockRes);
225
- expect(mockRes.clearCookie).toHaveBeenCalledTimes(2);
226
- expect(mockRes.clearCookie).toHaveBeenCalledWith('dotpress_access_token', expect.any(Object));
227
- expect(mockRes.clearCookie).toHaveBeenCalledWith('dotpress_refresh_token', expect.any(Object));
228
- });
229
- });
230
- describe('detectAuthMode', () => {
231
- it('should return "cookie" when refresh token cookie is present', () => {
232
- const mockReq = {
233
- cookies: {
234
- dotpress_refresh_token: 'ref-token',
235
- },
236
- };
237
- const mode = detectAuthMode(mockReq);
238
- expect(mode).toBe('cookie');
239
- });
240
- it('should return "body" when refresh token is in body', () => {
241
- const mockReq = {
242
- cookies: {},
243
- body: {
244
- refreshToken: 'ref-token',
245
- },
246
- };
247
- const mode = detectAuthMode(mockReq);
248
- expect(mode).toBe('body');
249
- });
250
- it('should prioritize cookies over body', () => {
251
- const mockReq = {
252
- cookies: {
253
- dotpress_refresh_token: 'cookie-ref-token',
254
- },
255
- body: {
256
- refreshToken: 'body-ref-token',
257
- },
258
- };
259
- const mode = detectAuthMode(mockReq);
260
- expect(mode).toBe('cookie');
261
- });
262
- it('should return null when no tokens found', () => {
263
- const mockReq = {
264
- cookies: {},
265
- body: {},
266
- };
267
- const mode = detectAuthMode(mockReq);
268
- expect(mode).toBeNull();
269
- });
270
- it('should work with custom cookie names', () => {
271
- setSettings({
272
- keys: {
273
- secretKey: 'test-secret',
274
- publicKey: 'test-public',
275
- },
276
- dataProvider: {},
277
- cookies: {
278
- enabled: true,
279
- refreshTokenName: 'custom_refresh',
280
- },
281
- });
282
- const mockReq = {
283
- cookies: {
284
- custom_refresh: 'ref-token',
285
- },
286
- };
287
- const mode = detectAuthMode(mockReq);
288
- expect(mode).toBe('cookie');
289
- });
290
- });
291
- describe('extractTokensFromRequest', () => {
292
- it('should extract tokens from cookies', () => {
293
- // Ensure cookies are enabled with default settings
294
- setSettings({
295
- keys: {
296
- secretKey: 'test-secret',
297
- publicKey: 'test-public',
298
- },
299
- dataProvider: {},
300
- cookies: {
301
- enabled: true,
302
- },
303
- });
304
- const mockReq = {
305
- cookies: {
306
- dotpress_refresh_token: 'ref-token',
307
- },
308
- body: {
309
- accessToken: 'acc-token-from-body',
310
- },
311
- };
312
- const tokens = extractTokensFromRequest(mockReq);
313
- expect(tokens).toEqual({
314
- accessToken: 'acc-token-from-body',
315
- refreshToken: 'ref-token',
316
- });
317
- });
318
- it('should extract tokens from body when no cookies', () => {
319
- const mockReq = {
320
- cookies: {},
321
- body: {
322
- accessToken: 'acc-token',
323
- refreshToken: 'ref-token',
324
- },
325
- };
326
- const tokens = extractTokensFromRequest(mockReq);
327
- expect(tokens).toEqual({
328
- accessToken: 'acc-token',
329
- refreshToken: 'ref-token',
330
- });
331
- });
332
- it('should extract both tokens from cookies when accessTokenInCookie is true', () => {
333
- setSettings({
334
- keys: {
335
- secretKey: 'test-secret',
336
- publicKey: 'test-public',
337
- },
338
- dataProvider: {},
339
- cookies: {
340
- enabled: true,
341
- accessTokenInCookie: true,
342
- },
343
- });
344
- const mockReq = {
345
- cookies: {
346
- dotpress_access_token: 'acc-token-cookie',
347
- dotpress_refresh_token: 'ref-token-cookie',
348
- },
349
- body: {},
350
- };
351
- const tokens = extractTokensFromRequest(mockReq);
352
- expect(tokens).toEqual({
353
- accessToken: 'acc-token-cookie',
354
- refreshToken: 'ref-token-cookie',
355
- });
356
- });
357
- it('should return null when tokens are missing', () => {
358
- const mockReq = {
359
- cookies: {
360
- dotpress_refresh_token: 'ref-token',
361
- },
362
- body: {},
363
- };
364
- const tokens = extractTokensFromRequest(mockReq);
365
- expect(tokens).toBeNull();
366
- });
367
- });
368
- describe('extractAccessToken', () => {
369
- it('should prioritize Authorization header', () => {
370
- const mockReq = {
371
- headers: {
372
- authorization: 'Bearer header-token',
373
- },
374
- cookies: {
375
- dotpress_access_token: 'cookie-token',
376
- },
377
- body: {
378
- accessToken: 'body-token',
379
- },
380
- };
381
- const token = extractAccessToken(mockReq);
382
- expect(token).toBe('header-token');
383
- });
384
- it('should extract from cookie when no header and accessTokenInCookie is true', () => {
385
- setSettings({
386
- keys: {
387
- secretKey: 'test-secret',
388
- publicKey: 'test-public',
389
- },
390
- dataProvider: {},
391
- cookies: {
392
- enabled: true,
393
- accessTokenInCookie: true,
394
- },
395
- });
396
- const mockReq = {
397
- headers: {},
398
- cookies: {
399
- dotpress_access_token: 'cookie-token',
400
- },
401
- body: {
402
- accessToken: 'body-token',
403
- },
404
- };
405
- const token = extractAccessToken(mockReq);
406
- expect(token).toBe('cookie-token');
407
- });
408
- it('should extract from body as fallback', () => {
409
- const mockReq = {
410
- headers: {},
411
- cookies: {},
412
- body: {
413
- accessToken: 'body-token',
414
- },
415
- };
416
- const token = extractAccessToken(mockReq);
417
- expect(token).toBe('body-token');
418
- });
419
- it('should return null when no token found', () => {
420
- const mockReq = {
421
- headers: {},
422
- cookies: {},
423
- body: {},
424
- };
425
- const token = extractAccessToken(mockReq);
426
- expect(token).toBeNull();
427
- });
428
- it('should handle Authorization header without Bearer prefix', () => {
429
- const mockReq = {
430
- headers: {
431
- authorization: 'invalid-format',
432
- },
433
- cookies: {},
434
- body: {},
435
- };
436
- const token = extractAccessToken(mockReq);
437
- expect(token).toBeNull();
438
- });
439
- });
440
- describe('calculateExpiration', () => {
441
- it('should calculate correct expiration timestamp', () => {
442
- const expiresInSeconds = 3600;
443
- const before = Date.now();
444
- const result = calculateExpiration(expiresInSeconds);
445
- const after = Date.now();
446
- expect(result.expiresIn).toBe(3600);
447
- expect(result.expiresAt).toBeDefined();
448
- const expiresAt = new Date(result.expiresAt).getTime();
449
- expect(expiresAt).toBeGreaterThanOrEqual(before + 3600 * 1000);
450
- expect(expiresAt).toBeLessThanOrEqual(after + 3600 * 1000);
451
- });
452
- it('should return ISO string format for expiresAt', () => {
453
- const result = calculateExpiration(1800);
454
- expect(result.expiresAt).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
455
- });
456
- it('should handle different TTL values', () => {
457
- const result1 = calculateExpiration(60); // 1 minute
458
- const result2 = calculateExpiration(86400); // 1 day
459
- expect(result1.expiresIn).toBe(60);
460
- expect(result2.expiresIn).toBe(86400);
461
- const date1 = new Date(result1.expiresAt);
462
- const date2 = new Date(result2.expiresAt);
463
- expect(date2.getTime() - date1.getTime()).toBeGreaterThan(86000000); // Roughly 1 day
464
- });
465
- });
466
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,225 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi, beforeAll, afterEach, } from 'vitest';
2
- import jwt from 'jsonwebtoken';
3
- import { setSettings } from '../../lib/settings.js';
4
- import * as tokenFns from '../../lib/tokens.js';
5
- import * as generators from '../../lib/generators.js';
6
- describe('Tokens', () => {
7
- const dataProvider = {
8
- storeRefreshToken: vi.fn(),
9
- findRefreshToken: vi.fn(),
10
- markRefreshTokenAsUsed: vi.fn(),
11
- revokeTokens: vi.fn(),
12
- findUserById: vi.fn(),
13
- findUserIdentifiers: vi.fn(),
14
- };
15
- beforeAll(() => {
16
- setSettings({
17
- keys: {
18
- secretKey: 'secret_111222',
19
- publicKey: 'public_111222',
20
- },
21
- issuer: 'auth.myapp.com',
22
- accessTokenTTL: 3600,
23
- dataProvider,
24
- });
25
- });
26
- beforeEach(() => {
27
- vi.useFakeTimers();
28
- vi.setSystemTime(new Date('2025-01-01T00:00:00Z'));
29
- vi.spyOn(generators, 'generateUUID').mockReturnValue('000-000-000-000-000');
30
- });
31
- afterEach(() => {
32
- vi.resetAllMocks();
33
- vi.useRealTimers();
34
- });
35
- describe('Function: createAccessTokenFromPayload()', () => {
36
- it('should generate token and return expected data', () => {
37
- // @ts-expect-error issues with jsonwebtoken types
38
- const jwtSignFn = vi.spyOn(jwt, 'sign').mockReturnValue('acc-1111111111');
39
- const output = tokenFns.createAccessTokenFromPayload({
40
- sub: '101',
41
- username: 'JaneDoe',
42
- auth_time: 1735689600000,
43
- });
44
- expect(jwtSignFn).toHaveBeenCalledTimes(1);
45
- expect(jwtSignFn).toHaveBeenCalledWith({
46
- sub: '101',
47
- username: 'JaneDoe',
48
- auth_time: 1735689600000,
49
- }, 'secret_111222', {
50
- algorithm: 'RS256',
51
- issuer: 'auth.myapp.com',
52
- expiresIn: 3600,
53
- jwtid: '000-000-000-000-000',
54
- });
55
- expect(output).toEqual({
56
- jwtId: '000-000-000-000-000',
57
- accessToken: 'acc-1111111111',
58
- });
59
- });
60
- });
61
- describe('Function: generateRefreshToken()', () => {
62
- it('should return token and hashed token', () => {
63
- const output = tokenFns.generateRefreshToken();
64
- expect(output).toEqual({
65
- token: expect.any(String),
66
- tokenHash: expect.any(String),
67
- });
68
- });
69
- });
70
- describe('Function: generateTokensForUser()', () => {
71
- it('should generate tokens and return expected data', async () => {
72
- const storeRefreshTokenFn = vi
73
- .mocked(dataProvider.storeRefreshToken)
74
- .mockResolvedValue();
75
- // @ts-expect-error issues with jsonwebtoken types
76
- vi.spyOn(jwt, 'sign').mockReturnValue('acc-1111111111');
77
- const output = await tokenFns.generateTokensForUser({
78
- userId: '110',
79
- username: 'JaneDoe',
80
- });
81
- expect(storeRefreshTokenFn).toHaveBeenCalledTimes(1);
82
- expect(storeRefreshTokenFn).toHaveBeenCalledWith({
83
- token: expect.any(String),
84
- tokenHash: expect.any(String),
85
- userId: '110',
86
- jwtId: '000-000-000-000-000',
87
- expiresAt: new Date('2025-01-15T00:00:00.000Z'),
88
- });
89
- expect(output).toEqual({
90
- accessToken: 'acc-1111111111',
91
- refreshToken: expect.any(String),
92
- });
93
- });
94
- });
95
- describe('Function: generateTokensFromRefreshToken()', () => {
96
- beforeEach(() => {
97
- // @ts-expect-error issues with jsonwebtoken types
98
- vi.spyOn(jwt, 'verify').mockReturnValue({
99
- sub: '110',
100
- jti: 'jwt900',
101
- });
102
- });
103
- it('should throw error if token not found', async () => {
104
- const findRefreshTokenSpy = vi
105
- .spyOn(dataProvider, 'findRefreshToken')
106
- .mockResolvedValue(undefined);
107
- await expect(tokenFns.generateTokensFromRefreshToken({
108
- accessToken: 'acc100',
109
- refreshToken: 'refr100',
110
- })).rejects.toThrow('Invalid_Refresh_Token');
111
- expect(findRefreshTokenSpy).toHaveBeenCalledTimes(1);
112
- });
113
- it('should throw error if token is revoked found', async () => {
114
- const findRefreshTokenSpy = vi
115
- .spyOn(dataProvider, 'findRefreshToken')
116
- .mockResolvedValue({
117
- userId: '110',
118
- jwtId: 'jwt900',
119
- expiresAt: new Date('2025-01-15T00:00:00.000Z'),
120
- isUsed: false,
121
- revokedAt: new Date(),
122
- });
123
- await expect(tokenFns.generateTokensFromRefreshToken({
124
- accessToken: 'acc100',
125
- refreshToken: 'refr100',
126
- })).rejects.toThrow('Invalid_Refresh_Token');
127
- expect(findRefreshTokenSpy).toHaveBeenCalledTimes(1);
128
- });
129
- it('should throw error if token is used', async () => {
130
- const findRefreshTokenSpy = vi
131
- .spyOn(dataProvider, 'findRefreshToken')
132
- .mockResolvedValue({
133
- userId: '110',
134
- jwtId: 'jwt900',
135
- expiresAt: new Date('2025-01-15T00:00:00.000Z'),
136
- isUsed: true,
137
- revokedAt: null,
138
- });
139
- await expect(tokenFns.generateTokensFromRefreshToken({
140
- accessToken: 'acc100',
141
- refreshToken: 'refr100',
142
- })).rejects.toThrow('Invalid_Refresh_Token');
143
- expect(findRefreshTokenSpy).toHaveBeenCalledTimes(1);
144
- });
145
- it('should throw error if userId mismatches', async () => {
146
- const findRefreshTokenSpy = vi
147
- .spyOn(dataProvider, 'findRefreshToken')
148
- .mockResolvedValue({
149
- userId: '200',
150
- jwtId: 'jwt900',
151
- expiresAt: new Date('2025-01-15T00:00:00.000Z'),
152
- isUsed: false,
153
- revokedAt: null,
154
- });
155
- await expect(tokenFns.generateTokensFromRefreshToken({
156
- accessToken: 'acc100',
157
- refreshToken: 'refr100',
158
- })).rejects.toThrow('Invalid_Refresh_Token');
159
- expect(findRefreshTokenSpy).toHaveBeenCalledTimes(1);
160
- });
161
- it('should throw error if jwtid mismatches', async () => {
162
- const findRefreshTokenSpy = vi
163
- .spyOn(dataProvider, 'findRefreshToken')
164
- .mockResolvedValue({
165
- userId: '110',
166
- jwtId: 'jwt100',
167
- expiresAt: new Date('2025-01-15T00:00:00.000Z'),
168
- isUsed: false,
169
- revokedAt: null,
170
- });
171
- await expect(tokenFns.generateTokensFromRefreshToken({
172
- accessToken: 'acc100',
173
- refreshToken: 'refr100',
174
- })).rejects.toThrow('Invalid_Refresh_Token');
175
- expect(findRefreshTokenSpy).toHaveBeenCalledTimes(1);
176
- });
177
- it('should throw error if refresh token is expired', async () => {
178
- const findRefreshTokenSpy = vi
179
- .spyOn(dataProvider, 'findRefreshToken')
180
- .mockResolvedValue({
181
- userId: '110',
182
- jwtId: 'jwt900',
183
- expiresAt: new Date('2024-12-31T00:00:00.000Z'),
184
- isUsed: false,
185
- revokedAt: null,
186
- });
187
- await expect(tokenFns.generateTokensFromRefreshToken({
188
- accessToken: 'acc100',
189
- refreshToken: 'refr100',
190
- })).rejects.toThrow('Expired_Refresh_Token');
191
- expect(findRefreshTokenSpy).toHaveBeenCalledTimes(1);
192
- });
193
- it('should generate new tokens if refresh token is valid', async () => {
194
- // @ts-expect-error issues with jsonwebtoken types
195
- vi.spyOn(jwt, 'sign').mockReturnValue('acc-1111111111');
196
- const findRefreshTokenSpy = vi
197
- .spyOn(dataProvider, 'findRefreshToken')
198
- .mockResolvedValue({
199
- userId: '110',
200
- jwtId: 'jwt900',
201
- expiresAt: new Date('2025-01-15T00:00:00.000Z'),
202
- isUsed: false,
203
- revokedAt: null,
204
- });
205
- const storeRefreshTokenFn = vi
206
- .mocked(dataProvider.storeRefreshToken)
207
- .mockResolvedValue();
208
- const markRefreshTokenAsUsedFn = vi
209
- .mocked(dataProvider.markRefreshTokenAsUsed)
210
- .mockResolvedValue();
211
- const output = await tokenFns.generateTokensFromRefreshToken({
212
- accessToken: 'acc100',
213
- refreshToken: 'refr100',
214
- });
215
- expect(findRefreshTokenSpy).toHaveBeenCalledTimes(1);
216
- expect(storeRefreshTokenFn).toHaveBeenCalledTimes(1);
217
- expect(markRefreshTokenAsUsedFn).toHaveBeenCalledTimes(1);
218
- expect(output).toEqual({
219
- userId: '110',
220
- accessToken: 'acc-1111111111',
221
- refreshToken: expect.any(String),
222
- });
223
- });
224
- });
225
- });