@@ -366,6 +366,65 @@ describe('Clerk singleton', () => {
366
366
} ) ;
367
367
} ) ;
368
368
369
+ it ( 'redirects the user to the /v1/client/touch endpoint if the cookie_expires_at is less than 8 days away' , async ( ) => {
370
+ mockSession . touch . mockReturnValue ( Promise . resolve ( ) ) ;
371
+ mockClientFetch . mockReturnValue (
372
+ Promise . resolve ( {
373
+ activeSessions : [ mockSession ] ,
374
+ cookieExpiresAt : new Date ( Date . now ( ) + 2 * 24 * 60 * 60 * 1000 ) , // 2 days from now
375
+ isEligibleForTouch : ( ) => true ,
376
+ buildTouchUrl : ( ) =>
377
+ `https://clerk.example.com/v1/client/touch?redirect_url=${ mockWindowLocation . href } /redirect-url-path` ,
378
+ } ) ,
379
+ ) ;
380
+
381
+ const sut = new Clerk ( productionPublishableKey ) ;
382
+ sut . navigate = jest . fn ( ) ;
383
+ await sut . load ( ) ;
384
+ await sut . setActive ( { session : mockSession as any as ActiveSessionResource , redirectUrl : '/redirect-url-path' } ) ;
385
+ const redirectUrl = new URL ( ( sut . navigate as jest . Mock ) . mock . calls [ 0 ] ) ;
386
+ expect ( redirectUrl . pathname ) . toEqual ( '/v1/client/touch' ) ;
387
+ expect ( redirectUrl . searchParams . get ( 'redirect_url' ) ) . toEqual ( `${ mockWindowLocation . href } /redirect-url-path` ) ;
388
+ } ) ;
389
+
390
+ it ( 'does not redirect the user to the /v1/client/touch endpoint if the cookie_expires_at is more than 8 days away' , async ( ) => {
391
+ mockSession . touch . mockReturnValue ( Promise . resolve ( ) ) ;
392
+ mockClientFetch . mockReturnValue (
393
+ Promise . resolve ( {
394
+ activeSessions : [ mockSession ] ,
395
+ cookieExpiresAt : new Date ( Date . now ( ) + 10 * 24 * 60 * 60 * 1000 ) , // 10 days from now
396
+ isEligibleForTouch : ( ) => false ,
397
+ buildTouchUrl : ( ) =>
398
+ `https://clerk.example.com/v1/client/touch?redirect_url=${ mockWindowLocation . href } /redirect-url-path` ,
399
+ } ) ,
400
+ ) ;
401
+
402
+ const sut = new Clerk ( productionPublishableKey ) ;
403
+ sut . navigate = jest . fn ( ) ;
404
+ await sut . load ( ) ;
405
+ await sut . setActive ( { session : mockSession as any as ActiveSessionResource , redirectUrl : '/redirect-url-path' } ) ;
406
+ expect ( sut . navigate ) . toHaveBeenCalledWith ( '/redirect-url-path' ) ;
407
+ } ) ;
408
+
409
+ it ( 'does not redirect the user to the /v1/client/touch endpoint if the cookie_expires_at is not set' , async ( ) => {
410
+ mockSession . touch . mockReturnValue ( Promise . resolve ( ) ) ;
411
+ mockClientFetch . mockReturnValue (
412
+ Promise . resolve ( {
413
+ activeSessions : [ mockSession ] ,
414
+ cookieExpiresAt : null ,
415
+ isEligibleForTouch : ( ) => false ,
416
+ buildTouchUrl : ( ) =>
417
+ `https://clerk.example.com/v1/client/touch?redirect_url=${ mockWindowLocation . href } /redirect-url-path` ,
418
+ } ) ,
419
+ ) ;
420
+
421
+ const sut = new Clerk ( productionPublishableKey ) ;
422
+ sut . navigate = jest . fn ( ) ;
423
+ await sut . load ( ) ;
424
+ await sut . setActive ( { session : mockSession as any as ActiveSessionResource , redirectUrl : '/redirect-url-path' } ) ;
425
+ expect ( sut . navigate ) . toHaveBeenCalledWith ( '/redirect-url-path' ) ;
426
+ } ) ;
427
+
369
428
mockNativeRuntime ( ( ) => {
370
429
it ( 'calls session.touch in a non-standard browser' , async ( ) => {
371
430
mockClientFetch . mockReturnValue ( Promise . resolve ( { activeSessions : [ mockSession ] } ) ) ;
@@ -496,6 +555,7 @@ describe('Clerk singleton', () => {
496
555
expect ( sut . setActive ) . toHaveBeenCalledWith ( {
497
556
session : null ,
498
557
beforeEmit : expect . any ( Function ) ,
558
+ redirectUrl : '/' ,
499
559
} ) ;
500
560
} ) ;
501
561
} ) ;
@@ -518,7 +578,11 @@ describe('Clerk singleton', () => {
518
578
expect ( mockClientDestroy ) . not . toHaveBeenCalled ( ) ;
519
579
expect ( mockClientRemoveSessions ) . toHaveBeenCalled ( ) ;
520
580
expect ( mockSession1 . remove ) . not . toHaveBeenCalled ( ) ;
521
- expect ( sut . setActive ) . toHaveBeenCalledWith ( { session : null , beforeEmit : expect . any ( Function ) } ) ;
581
+ expect ( sut . setActive ) . toHaveBeenCalledWith ( {
582
+ session : null ,
583
+ beforeEmit : expect . any ( Function ) ,
584
+ redirectUrl : '/' ,
585
+ } ) ;
522
586
} ) ;
523
587
} ) ;
524
588
@@ -561,7 +625,11 @@ describe('Clerk singleton', () => {
561
625
await waitFor ( ( ) => {
562
626
expect ( mockSession1 . remove ) . toHaveBeenCalled ( ) ;
563
627
expect ( mockClientDestroy ) . not . toHaveBeenCalled ( ) ;
564
- expect ( sut . setActive ) . toHaveBeenCalledWith ( { session : null , beforeEmit : expect . any ( Function ) } ) ;
628
+ expect ( sut . setActive ) . toHaveBeenCalledWith ( {
629
+ session : null ,
630
+ beforeEmit : expect . any ( Function ) ,
631
+ redirectUrl : '/' ,
632
+ } ) ;
565
633
} ) ;
566
634
} ) ;
567
635
@@ -582,7 +650,11 @@ describe('Clerk singleton', () => {
582
650
await waitFor ( ( ) => {
583
651
expect ( mockSession1 . remove ) . toHaveBeenCalled ( ) ;
584
652
expect ( mockClientDestroy ) . not . toHaveBeenCalled ( ) ;
585
- expect ( sut . setActive ) . toHaveBeenCalledWith ( { session : null , beforeEmit : expect . any ( Function ) } ) ;
653
+ expect ( sut . setActive ) . toHaveBeenCalledWith ( {
654
+ session : null ,
655
+ beforeEmit : expect . any ( Function ) ,
656
+ redirectUrl : '/after-sign-out' ,
657
+ } ) ;
586
658
expect ( sut . navigate ) . toHaveBeenCalledWith ( '/after-sign-out' ) ;
587
659
} ) ;
588
660
} ) ;
@@ -1096,6 +1168,16 @@ describe('Clerk singleton', () => {
1096
1168
} ) ;
1097
1169
1098
1170
it ( 'redirects the user to the signInForceRedirectUrl if one was provided' , async ( ) => {
1171
+ const sessionId = 'sess_1yDceUR8SIKtQ0gIOO8fNsW7nhe' ;
1172
+ const mockSession = {
1173
+ id : sessionId ,
1174
+ remove : jest . fn ( ) ,
1175
+ status : 'active' ,
1176
+ user : { } ,
1177
+ touch : jest . fn ( ( ) => Promise . resolve ( ) ) ,
1178
+ getToken : jest . fn ( ) ,
1179
+ lastActiveToken : { getRawString : ( ) => 'mocked-token' } ,
1180
+ } ;
1099
1181
mockEnvironmentFetch . mockReturnValue (
1100
1182
Promise . resolve ( {
1101
1183
authConfig : { } ,
@@ -1110,6 +1192,7 @@ describe('Clerk singleton', () => {
1110
1192
1111
1193
mockClientFetch . mockReturnValue (
1112
1194
Promise . resolve ( {
1195
+ sessions : [ mockSession ] ,
1113
1196
activeSessions : [ ] ,
1114
1197
signIn : new SignIn ( null ) ,
1115
1198
signUp : new SignUp ( {
@@ -1124,24 +1207,19 @@ describe('Clerk singleton', () => {
1124
1207
long_message : "You're already signed in" ,
1125
1208
message : "You're already signed in" ,
1126
1209
meta : {
1127
- session_id : 'sess_1yDceUR8SIKtQ0gIOO8fNsW7nhe' ,
1210
+ session_id : sessionId ,
1128
1211
} ,
1129
1212
} ,
1130
1213
} ,
1131
1214
} ,
1132
1215
} as any as SignUpJSON ) ,
1216
+ isEligibleForTouch : ( ) => false ,
1133
1217
} ) ,
1134
1218
) ;
1135
1219
1136
- const mockSetActive = jest . fn ( async ( setActiveOpts : any ) => {
1137
- await setActiveOpts . beforeEmit ( ) ;
1138
- } ) ;
1139
-
1140
1220
const sut = new Clerk ( productionPublishableKey ) ;
1141
1221
await sut . load ( mockedLoadOptions ) ;
1142
- sut . setActive = mockSetActive as any ;
1143
-
1144
- sut . handleRedirectCallback ( {
1222
+ await sut . handleRedirectCallback ( {
1145
1223
signInForceRedirectUrl : '/custom-sign-in' ,
1146
1224
} ) ;
1147
1225
@@ -1151,6 +1229,16 @@ describe('Clerk singleton', () => {
1151
1229
} ) ;
1152
1230
1153
1231
it ( 'gives priority to signInForceRedirectUrl if signInForceRedirectUrl and signInFallbackRedirectUrl were provided ' , async ( ) => {
1232
+ const sessionId = 'sess_1yDceUR8SIKtQ0gIOO8fNsW7nhe' ;
1233
+ const mockSession = {
1234
+ id : sessionId ,
1235
+ remove : jest . fn ( ) ,
1236
+ status : 'active' ,
1237
+ user : { } ,
1238
+ touch : jest . fn ( ( ) => Promise . resolve ( ) ) ,
1239
+ getToken : jest . fn ( ) ,
1240
+ lastActiveToken : { getRawString : ( ) => 'mocked-token' } ,
1241
+ } ;
1154
1242
mockEnvironmentFetch . mockReturnValue (
1155
1243
Promise . resolve ( {
1156
1244
authConfig : { } ,
@@ -1165,6 +1253,7 @@ describe('Clerk singleton', () => {
1165
1253
1166
1254
mockClientFetch . mockReturnValue (
1167
1255
Promise . resolve ( {
1256
+ sessions : [ mockSession ] ,
1168
1257
activeSessions : [ ] ,
1169
1258
signIn : new SignIn ( null ) ,
1170
1259
signUp : new SignUp ( {
@@ -1179,24 +1268,20 @@ describe('Clerk singleton', () => {
1179
1268
long_message : "You're already signed in" ,
1180
1269
message : "You're already signed in" ,
1181
1270
meta : {
1182
- session_id : 'sess_1yDceUR8SIKtQ0gIOO8fNsW7nhe' ,
1271
+ session_id : sessionId ,
1183
1272
} ,
1184
1273
} ,
1185
1274
} ,
1186
1275
} ,
1187
1276
} as any as SignUpJSON ) ,
1277
+ isEligibleForTouch : ( ) => false ,
1188
1278
} ) ,
1189
1279
) ;
1190
1280
1191
- const mockSetActive = jest . fn ( async ( setActiveOpts : any ) => {
1192
- await setActiveOpts . beforeEmit ( ) ;
1193
- } ) ;
1194
-
1195
1281
const sut = new Clerk ( productionPublishableKey ) ;
1196
1282
await sut . load ( mockedLoadOptions ) ;
1197
- sut . setActive = mockSetActive as any ;
1198
1283
1199
- sut . handleRedirectCallback ( {
1284
+ await sut . handleRedirectCallback ( {
1200
1285
signInForceRedirectUrl : '/custom-sign-in' ,
1201
1286
signInFallbackRedirectUrl : '/redirect-to' ,
1202
1287
} as any ) ;
@@ -1654,7 +1739,7 @@ describe('Clerk singleton', () => {
1654
1739
await waitFor ( ( ) => {
1655
1740
expect ( mockSetActive ) . toHaveBeenCalledWith ( {
1656
1741
session : createdSessionId ,
1657
- beforeEmit : expect . any ( Function ) ,
1742
+ redirectUrl : redirectUrlComplete ,
1658
1743
} ) ;
1659
1744
} ) ;
1660
1745
} ) ;
@@ -1714,7 +1799,7 @@ describe('Clerk singleton', () => {
1714
1799
await waitFor ( ( ) => {
1715
1800
expect ( mockSetActive ) . toHaveBeenCalledWith ( {
1716
1801
session : createdSessionId ,
1717
- beforeEmit : expect . any ( Function ) ,
1802
+ redirectUrl : redirectUrlComplete ,
1718
1803
} ) ;
1719
1804
} ) ;
1720
1805
} ) ;
0 commit comments