Once the existing app is updated with new access scopes, the app gets redirected to the authorization page to get the new access token. After providing authorization, the new access token should get stored in the session storage, and the app should work seamlessly with the new access token and scopes. But the new access token does not get stored in the session storage, the app works with the old access token and scopes which is failing the app.
Expected behavior
If scopes are updated, new offline access token (with new scopes) should get stored as part of the session storage.
Actual behavior
If scopes are updated, new offline access token (with new scopes) does not get stored as part of the session storage.
Steps to reproduce the problem
1: Create an app with remix template.
2: Provide the fewer access scopes than required for the app:
6: Try to access the app on the store.
7: You correctly get redirected to the authorization page.
8: Provide Authorization to the app.
9: The should work seamlessly with new access token and scopes.
Debug logs
11:54:33 │ remix │ [shopify-api/INFO] version 11.0.1, environment Remix
11:54:33 │ remix │ (node:31285) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
11:54:33 │ remix │ (Use node --trace-warnings ... to show where the warning was created)
11:54:33 │ remix │ [shopify-app/INFO] Authenticating admin request
11:54:33 │ remix │ [shopify-app/DEBUG] Attempting to authenticate session token | {sessionToken:{"search":""}}
11:54:33 │ remix │ [shopify-app/DEBUG] Validating session token
11:54:33 │ remix │ [shopify-app/DEBUG] Session token is valid | {payload: }
11:54:33 │ remix │ [shopify-app/DEBUG] Session token is valid | {shop: .myshopify.com, payload: [object Object]}
11:54:33 │ remix │ [shopify-app/DEBUG] Loading session from storage | {sessionId: offline_.myshopify.com}
11:54:33 │ remix │ [shopify-app/DEBUG] Request is valid, loaded session from session token | {shop: .myshopify.com, isOnline: false}
11:54:33 │ remix │ [shopify-app/INFO] Authenticating admin request
11:54:33 │ remix │ [shopify-app/DEBUG] Attempting to authenticate session token | {sessionToken:{"search":""}}
11:54:33 │ remix │ [shopify-app/DEBUG] Validating session token
11:54:33 │ remix │ [shopify-app/DEBUG] Session token is valid | {payload: }
11:54:33 │ remix │ [shopify-app/DEBUG] Session token is valid | {shop: .myshopify.com, payload: [object Object]}
11:54:33 │ remix │ [shopify-app/DEBUG] Loading session from storage | {sessionId: offline_.myshopify.com}
11:54:33 │ remix │ [shopify-app/DEBUG] Request is valid, loaded session from session token | {shop: .myshopify.com, isOnline: false}
Additional context and analysis
The issue seems to be with the @shopify/shopify-app-remix package. In token exchange strategy, existingSession from session storage is also being passed as SessionContext. If the existingSession is valid then it sends back old access token.
As the scopes are updated and new session token is created, the code should request for new "Offline access token" by calling exchangeToken.
Issue summary
Before opening this issue, I have:
@shopify/shopify-api
package and version: 11.0.1@shopify/shopify-app-remix
package and version: 3.0.1{ logger: { level: LogSeverity.Debug } }
in my configuration, when applicableDescription
Once the existing app is updated with new access scopes, the app gets redirected to the authorization page to get the new access token. After providing authorization, the new access token should get stored in the session storage, and the app should work seamlessly with the new access token and scopes. But the new access token does not get stored in the session storage, the app works with the old access token and scopes which is failing the app.
Expected behavior
If scopes are updated, new offline access token (with new scopes) should get stored as part of the session storage.
Actual behavior
If scopes are updated, new offline access token (with new scopes) does not get stored as part of the session storage.
Steps to reproduce the problem
1: Create an app with remix template. 2: Provide the fewer access scopes than required for the app:
3: Install the app on the development store. 4: Try to access the app on the store. 5: Update the access scopes:
6: Try to access the app on the store. 7: You correctly get redirected to the authorization page. 8: Provide Authorization to the app. 9: The should work seamlessly with new access token and scopes.
Debug logs
11:54:33 │ remix │ [shopify-api/INFO] version 11.0.1, environment Remix 11:54:33 │ remix │ (node:31285) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time 11:54:33 │ remix │ (Use"}}
11:54:33 │ remix │ [shopify-app/DEBUG] Validating session token
11:54:33 │ remix │ [shopify-app/DEBUG] Session token is valid | {payload: }
11:54:33 │ remix │ [shopify-app/DEBUG] Session token is valid | {shop: .myshopify.com, payload: [object Object]}
11:54:33 │ remix │ [shopify-app/DEBUG] Loading session from storage | {sessionId: offline_.myshopify.com}
11:54:33 │ remix │ [shopify-app/DEBUG] Request is valid, loaded session from session token | {shop: .myshopify.com, isOnline: false}
11:54:33 │ remix │ [shopify-app/INFO] Authenticating admin request
11:54:33 │ remix │ [shopify-app/DEBUG] Attempting to authenticate session token | {sessionToken:{"search":""}}
11:54:33 │ remix │ [shopify-app/DEBUG] Validating session token
11:54:33 │ remix │ [shopify-app/DEBUG] Session token is valid | {payload: }
11:54:33 │ remix │ [shopify-app/DEBUG] Session token is valid | {shop: .myshopify.com, payload: [object Object]}
11:54:33 │ remix │ [shopify-app/DEBUG] Loading session from storage | {sessionId: offline_.myshopify.com}
11:54:33 │ remix │ [shopify-app/DEBUG] Request is valid, loaded session from session token | {shop: .myshopify.com, isOnline: false}
node --trace-warnings ...
to show where the warning was created) 11:54:33 │ remix │ [shopify-app/INFO] Authenticating admin request 11:54:33 │ remix │ [shopify-app/DEBUG] Attempting to authenticate session token | {sessionToken:{"search":"Additional context and analysis
The issue seems to be with the
@shopify/shopify-app-remix
package. In token exchange strategy, existingSession from session storage is also being passed asSessionContext
. If the existingSession is valid then it sends back old access token. As the scopes are updated and new session token is created, the code should request for new "Offline access token" by callingexchangeToken
.Check the codes here: https://github.com/Shopify/shopify-app-js/blob/9805a753de13a535741550b70dcc8c32e48df0da/packages/apps/shopify-app-remix/src/server/authenticate/admin/authenticate.ts#L132C7-L141C10
https://github.com/Shopify/shopify-app-js/blob/9805a753de13a535741550b70dcc8c32e48df0da/packages/apps/shopify-app-remix/src/server/authenticate/admin/strategies/token-exchange.ts#L54C5-L93C8