@@ -7,17 +7,11 @@ import {
77 setLastSeenAuthMethod ,
88 setLastSeenUserIdAfterAuth ,
99} from './session.js'
10- import {
11- exchangeAccessForApplicationTokens ,
12- exchangeCustomPartnerToken ,
13- refreshAccessToken ,
14- InvalidGrantError ,
15- } from './session/exchange.js'
10+ import { exchangeCustomPartnerToken , refreshAccessToken , InvalidGrantError } from './session/exchange.js'
1611import { allDefaultScopes } from './session/scopes.js'
1712import { store as storeSessions , fetch as fetchSessions , remove as secureRemove } from './session/store.js'
18- import { ApplicationToken , IdentityToken , Sessions } from './session/schema.js'
13+ import { IdentityToken , Sessions } from './session/schema.js'
1914import { validateSession } from './session/validate.js'
20- import { applicationId } from './session/identity.js'
2115import { pollForDeviceAuthorization , requestDeviceAuthorization } from './session/device-authorization.js'
2216import { getCurrentSessionId } from './conf-store.js'
2317import * as fqdnModule from '../../public/node/context/fqdn.js'
@@ -50,54 +44,15 @@ const validIdentityToken: IdentityToken = {
5044}
5145
5246const validTokens : OAuthSession = {
53- admin : { token : 'admin_token ' , storeFqdn : 'mystore.myshopify.com' } ,
54- storefront : 'storefront_token ' ,
55- partners : 'partners_token ' ,
47+ admin : { token : 'access_token ' , storeFqdn : 'mystore.myshopify.com' } ,
48+ storefront : 'access_token ' ,
49+ partners : 'access_token ' ,
5650 userId,
5751}
5852
59- const appTokens : Record < string , ApplicationToken > = {
60- // Admin APIs includes domain in the key
61- 'mystore.myshopify.com-admin' : {
62- accessToken : 'admin_token' ,
63- expiresAt : futureDate ,
64- scopes : [ 'scope' , 'scope2' ] ,
65- } ,
66- 'storefront-renderer' : {
67- accessToken : 'storefront_token' ,
68- expiresAt : futureDate ,
69- scopes : [ 'scope1' ] ,
70- } ,
71- partners : {
72- accessToken : 'partners_token' ,
73- expiresAt : futureDate ,
74- scopes : [ 'scope2' ] ,
75- } ,
76- 'business-platform' : {
77- accessToken : 'business_platform_token' ,
78- expiresAt : futureDate ,
79- scopes : [ 'scope3' ] ,
80- } ,
81- }
82-
83- const partnersToken : ApplicationToken = {
84- accessToken : 'custom_partners_token' ,
85- expiresAt : futureDate ,
86- scopes : [ 'scope2' ] ,
87- }
88-
8953const fqdn = 'fqdn.com'
9054
9155const validSessions : Sessions = {
92- [ fqdn ] : {
93- [ userId ] : {
94- identity : validIdentityToken ,
95- applications : appTokens ,
96- } ,
97- } ,
98- }
99-
100- const invalidSessions : Sessions = {
10156 [ fqdn ] : {
10257 [ userId ] : {
10358 identity : validIdentityToken ,
@@ -107,7 +62,6 @@ const invalidSessions: Sessions = {
10762}
10863
10964vi . mock ( '../../public/node/context/local.js' )
110- vi . mock ( './session/identity' )
11165vi . mock ( './session/authorize' )
11266vi . mock ( './session/exchange' )
11367vi . mock ( './session/scopes' )
@@ -123,11 +77,9 @@ vi.mock('../../public/node/system.js')
12377
12478beforeEach ( ( ) => {
12579 vi . spyOn ( fqdnModule , 'identityFqdn' ) . mockResolvedValue ( fqdn )
126- vi . mocked ( exchangeAccessForApplicationTokens ) . mockResolvedValue ( appTokens )
12780 vi . mocked ( refreshAccessToken ) . mockResolvedValue ( validIdentityToken )
128- vi . mocked ( applicationId ) . mockImplementation ( ( app ) => app )
12981 vi . mocked ( exchangeCustomPartnerToken ) . mockResolvedValue ( {
130- accessToken : partnersToken . accessToken ,
82+ accessToken : 'custom_partners_token' ,
13183 userId : validIdentityToken . userId ,
13284 } )
13385 vi . mocked ( partnersRequest ) . mockResolvedValue ( undefined )
@@ -162,7 +114,6 @@ describe('ensureAuthenticated when previous session is invalid', () => {
162114 const got = await ensureAuthenticated ( defaultApplications )
163115
164116 // Then
165- expect ( exchangeAccessForApplicationTokens ) . toBeCalled ( )
166117 expect ( refreshAccessToken ) . not . toBeCalled ( )
167118 expect ( businessPlatformRequest ) . toHaveBeenCalled ( )
168119 expect ( storeSessions ) . toHaveBeenCalledOnce ( )
@@ -202,16 +153,16 @@ The CLI is currently unable to prompt for reauthentication.`,
202153 test ( 'executes complete auth flow if session is for a different fqdn' , async ( ) => {
203154 // Given
204155 vi . mocked ( validateSession ) . mockResolvedValueOnce ( 'needs_full_auth' )
205- vi . mocked ( fetchSessions ) . mockResolvedValue ( invalidSessions )
156+ vi . mocked ( fetchSessions ) . mockResolvedValue ( validSessions )
206157 const expectedSessions = {
207- ...invalidSessions ,
158+ ...validSessions ,
208159 [ fqdn ] : {
209160 [ userId ] : {
210161 identity : {
211162 ...validIdentityToken ,
212163 alias : 'user@example.com' ,
213164 } ,
214- applications : appTokens ,
165+ applications : { } ,
215166 } ,
216167 } ,
217168 }
@@ -220,7 +171,7 @@ The CLI is currently unable to prompt for reauthentication.`,
220171 const got = await ensureAuthenticated ( defaultApplications )
221172
222173 // Then
223- expect ( exchangeAccessForApplicationTokens ) . toBeCalled ( )
174+
224175 expect ( refreshAccessToken ) . not . toBeCalled ( )
225176 expect ( storeSessions ) . toBeCalledWith ( expectedSessions )
226177 expect ( got ) . toEqual ( validTokens )
@@ -239,7 +190,7 @@ The CLI is currently unable to prompt for reauthentication.`,
239190 const got = await ensureAuthenticated ( defaultApplications )
240191
241192 // Then
242- expect ( exchangeAccessForApplicationTokens ) . toBeCalled ( )
193+
243194 expect ( businessPlatformRequest ) . toHaveBeenCalled ( )
244195 expect ( storeSessions ) . toHaveBeenCalledOnce ( )
245196
@@ -250,26 +201,20 @@ The CLI is currently unable to prompt for reauthentication.`,
250201 expect ( got ) . toEqual ( validTokens )
251202 } )
252203
253- test ( 'falls back to userId when no business platform token available ' , async ( ) => {
204+ test ( 'uses identity token to fetch email during full auth flow ' , async ( ) => {
254205 // Given
255206 vi . mocked ( validateSession ) . mockResolvedValueOnce ( 'needs_full_auth' )
256207 vi . mocked ( fetchSessions ) . mockResolvedValue ( undefined )
257- const appTokensWithoutBusinessPlatform = {
258- 'mystore.myshopify.com-admin' : appTokens [ 'mystore.myshopify.com-admin' ] ! ,
259- 'storefront-renderer' : appTokens [ 'storefront-renderer' ] ! ,
260- partners : appTokens . partners ! ,
261- }
262- vi . mocked ( exchangeAccessForApplicationTokens ) . mockResolvedValueOnce ( appTokensWithoutBusinessPlatform )
263208
264209 // When
265210 const got = await ensureAuthenticated ( defaultApplications )
266211
267212 // Then
268- expect ( businessPlatformRequest ) . not . toHaveBeenCalled ( )
213+ expect ( businessPlatformRequest ) . toHaveBeenCalledWith ( expect . any ( String ) , 'access_token' )
269214
270- // Verify the session was stored with userId as alias (fallback)
215+ // Verify the session was stored with email as alias
271216 const storedSession = vi . mocked ( storeSessions ) . mock . calls [ 0 ] ! [ 0 ]
272- expect ( storedSession [ fqdn ] ! [ userId ] ! . identity . alias ) . toBe ( userId )
217+ expect ( storedSession [ fqdn ] ! [ userId ] ! . identity . alias ) . toBe ( 'user@example.com' )
273218 } )
274219
275220 test ( 'executes complete auth flow if requesting additional scopes' , async ( ) => {
@@ -281,7 +226,7 @@ The CLI is currently unable to prompt for reauthentication.`,
281226 const got = await ensureAuthenticated ( defaultApplications )
282227
283228 // Then
284- expect ( exchangeAccessForApplicationTokens ) . toBeCalled ( )
229+
285230 expect ( refreshAccessToken ) . not . toBeCalled ( )
286231 expect ( businessPlatformRequest ) . toHaveBeenCalled ( )
287232 expect ( storeSessions ) . toHaveBeenCalledOnce ( )
@@ -307,7 +252,7 @@ describe('when existing session is valid', () => {
307252 const got = await ensureAuthenticated ( defaultApplications )
308253
309254 // Then
310- expect ( exchangeAccessForApplicationTokens ) . not . toBeCalled ( )
255+
311256 expect ( refreshAccessToken ) . not . toBeCalled ( )
312257 expect ( got ) . toEqual ( validTokens )
313258 await expect ( getLastSeenUserIdAfterAuth ( ) ) . resolves . toBe ( '1234-5678' )
@@ -320,13 +265,18 @@ describe('when existing session is valid', () => {
320265 vi . mocked ( validateSession ) . mockResolvedValueOnce ( 'ok' )
321266 vi . mocked ( fetchSessions ) . mockResolvedValue ( validSessions )
322267 vi . mocked ( getPartnersToken ) . mockReturnValue ( 'custom_cli_token' )
323- const expected = { ...validTokens , partners : 'custom_partners_token' }
268+ const expected = {
269+ admin : { token : 'access_token' , storeFqdn : 'mystore.myshopify.com' } ,
270+ storefront : 'access_token' ,
271+ partners : 'custom_partners_token' ,
272+ userId,
273+ }
324274
325275 // When
326276 const got = await ensureAuthenticated ( defaultApplications )
327277
328278 // Then
329- expect ( exchangeAccessForApplicationTokens ) . not . toBeCalled ( )
279+
330280 expect ( refreshAccessToken ) . not . toBeCalled ( )
331281 expect ( got ) . toEqual ( expected )
332282 await expect ( getLastSeenUserIdAfterAuth ( ) ) . resolves . toBe ( '1234-5678' )
@@ -344,8 +294,16 @@ describe('when existing session is valid', () => {
344294
345295 // Then
346296 expect ( refreshAccessToken ) . toBeCalled ( )
347- expect ( exchangeAccessForApplicationTokens ) . toBeCalled ( )
348- expect ( storeSessions ) . toBeCalledWith ( validSessions )
297+
298+ const expectedSessions = {
299+ [ fqdn ] : {
300+ [ userId ] : {
301+ identity : validIdentityToken ,
302+ applications : { } ,
303+ } ,
304+ } ,
305+ }
306+ expect ( storeSessions ) . toBeCalledWith ( expectedSessions )
349307 expect ( got ) . toEqual ( validTokens )
350308 await expect ( getLastSeenUserIdAfterAuth ( ) ) . resolves . toBe ( '1234-5678' )
351309 await expect ( getLastSeenAuthMethod ( ) ) . resolves . toEqual ( 'device_auth' )
@@ -364,8 +322,16 @@ describe('when existing session is expired', () => {
364322
365323 // Then
366324 expect ( refreshAccessToken ) . toBeCalled ( )
367- expect ( exchangeAccessForApplicationTokens ) . toBeCalled ( )
368- expect ( storeSessions ) . toBeCalledWith ( validSessions )
325+
326+ const expectedSessions = {
327+ [ fqdn ] : {
328+ [ userId ] : {
329+ identity : validIdentityToken ,
330+ applications : { } ,
331+ } ,
332+ } ,
333+ }
334+ expect ( storeSessions ) . toBeCalledWith ( expectedSessions )
369335 expect ( got ) . toEqual ( validTokens )
370336 await expect ( getLastSeenUserIdAfterAuth ( ) ) . resolves . toBe ( '1234-5678' )
371337 await expect ( getLastSeenAuthMethod ( ) ) . resolves . toEqual ( 'device_auth' )
@@ -385,7 +351,7 @@ describe('when existing session is expired', () => {
385351
386352 // Then
387353 expect ( refreshAccessToken ) . toBeCalled ( )
388- expect ( exchangeAccessForApplicationTokens ) . toBeCalled ( )
354+
389355 expect ( businessPlatformRequest ) . toHaveBeenCalled ( )
390356 expect ( storeSessions ) . toHaveBeenCalledOnce ( )
391357
@@ -644,7 +610,15 @@ describe('ensureAuthenticated email fetch functionality', () => {
644610 const got = await ensureAuthenticated ( defaultApplications )
645611
646612 // Then
647- expect ( storeSessions ) . toBeCalledWith ( validSessions )
613+ const expectedSessions = {
614+ [ fqdn ] : {
615+ [ userId ] : {
616+ identity : validIdentityToken ,
617+ applications : { } ,
618+ } ,
619+ } ,
620+ }
621+ expect ( storeSessions ) . toBeCalledWith ( expectedSessions )
648622 expect ( got ) . toEqual ( validTokens )
649623 } )
650624
@@ -659,7 +633,15 @@ describe('ensureAuthenticated email fetch functionality', () => {
659633 // Then
660634 // The email fetch is not called during refresh - the session keeps its existing alias
661635 expect ( businessPlatformRequest ) . not . toHaveBeenCalled ( )
662- expect ( storeSessions ) . toBeCalledWith ( validSessions )
636+ const expectedSessions = {
637+ [ fqdn ] : {
638+ [ userId ] : {
639+ identity : validIdentityToken ,
640+ applications : { } ,
641+ } ,
642+ } ,
643+ }
644+ expect ( storeSessions ) . toBeCalledWith ( expectedSessions )
663645 expect ( got ) . toEqual ( validTokens )
664646 } )
665647
0 commit comments