{"version":3,"file":"auth-code-flow.mjs","sources":["../../../../../../../src/server/authenticate/admin/strategies/auth-code-flow.ts"],"sourcesContent":["import {\n  CookieNotFound,\n  GraphqlQueryError,\n  HttpResponseError,\n  InvalidHmacError,\n  InvalidOAuthError,\n  Session,\n  Shopify,\n} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {\n  beginAuth,\n  handleClientErrorFactory,\n  redirectToAuthPage,\n  redirectToShopifyOrAppRoot,\n  redirectWithExitIframe,\n  triggerAfterAuthHook,\n  validateShopAndHostParams,\n} from '../helpers';\nimport {AppConfig, AppConfigArg} from '../../../config-types';\nimport {getSessionTokenHeader} from '../../helpers';\nimport {HandleAdminClientError} from '../../../clients';\nimport type {\n  ApiConfigWithFutureFlags,\n  ApiFutureFlags,\n} from '../../../future/flags';\n\nimport {AuthorizationStrategy, SessionContext, OnErrorOptions} from './types';\n\nexport class AuthCodeFlowStrategy<\n  Config extends AppConfigArg,\n> implements AuthorizationStrategy {\n  protected api: Shopify<\n    ApiConfigWithFutureFlags<Config['future']>,\n    ApiFutureFlags<Config['future']>\n  >;\n\n  protected config: AppConfig;\n  protected logger: Shopify['logger'];\n\n  public constructor({api, config, logger}: BasicParams) {\n    this.api = api;\n    this.config = config;\n    this.logger = logger;\n  }\n\n  public async respondToOAuthRequests(request: Request): Promise<void | never> {\n    const {api, config} = this;\n\n    const url = new URL(request.url);\n    const isAuthRequest = url.pathname === config.auth.path;\n    const isAuthCallbackRequest = url.pathname === config.auth.callbackPath;\n\n    if (isAuthRequest || isAuthCallbackRequest) {\n      const shop = api.utils.sanitizeShop(url.searchParams.get('shop')!);\n      if (!shop) throw new Response('Shop param is invalid', {status: 400});\n\n      if (isAuthRequest) {\n        throw await this.handleAuthBeginRequest(request, shop);\n      } else {\n        throw await this.handleAuthCallbackRequest(request, shop);\n      }\n    }\n\n    if (!getSessionTokenHeader(request)) {\n      // This is a document request that doesn't contain a session token. We check if the app is installed.\n      // If the app isn't installed, we initiate the OAuth auth code flow.\n      // Requests with a header can only happen after the app is installed.\n      await this.ensureInstalledOnShop(request);\n    }\n  }\n\n  public async authenticate(\n    request: Request,\n    sessionContext: SessionContext,\n  ): Promise<Session | never> {\n    const {api, config, logger} = this;\n\n    const {shop, session} = sessionContext;\n\n    if (!session) {\n      logger.debug('No session found, redirecting to OAuth', {shop});\n      await redirectToAuthPage({config, logger, api}, request, shop);\n    } else if (!session.isActive(config.scopes)) {\n      logger.debug(\n        'Found a session, but it has expired, redirecting to OAuth',\n        {shop},\n      );\n      await redirectToAuthPage({config, logger, api}, request, shop);\n    }\n\n    logger.debug('Found a valid session', {shop});\n\n    return session!;\n  }\n\n  public handleClientError(request: Request): HandleAdminClientError {\n    const {api, config, logger} = this;\n    return handleClientErrorFactory({\n      request,\n      onError: async ({session, error}: OnErrorOptions) => {\n        if (error.response.code === 401) {\n          throw await redirectToAuthPage(\n            {api, config, logger},\n            request,\n            session.shop,\n          );\n        }\n      },\n    });\n  }\n\n  private async ensureInstalledOnShop(request: Request) {\n    const {api, config, logger} = this;\n\n    validateShopAndHostParams({api, config, logger}, request);\n\n    const url = new URL(request.url);\n    let shop = url.searchParams.get('shop');\n\n    // Ensure app is installed\n    logger.debug('Ensuring app is installed on shop', {shop});\n\n    if (!(await this.hasValidOfflineId(request))) {\n      logger.info(\"Could not find a shop, can't authenticate request\");\n      throw new Response(undefined, {\n        status: 400,\n        statusText: 'Bad Request',\n      });\n    }\n\n    const offlineSession = await this.getOfflineSession(request);\n    const isEmbedded = url.searchParams.get('embedded') === '1';\n\n    if (!offlineSession) {\n      logger.info(\"Shop hasn't installed app yet, redirecting to OAuth\", {\n        shop,\n      });\n      if (isEmbedded) {\n        redirectWithExitIframe({api, config, logger}, request, shop!);\n      } else {\n        throw await beginAuth({api, config, logger}, request, false, shop!);\n      }\n    }\n\n    shop = shop || offlineSession.shop;\n\n    if (config.isEmbeddedApp && !isEmbedded) {\n      try {\n        logger.debug('Ensuring offline session is valid before embedding', {\n          shop,\n        });\n        await this.testSession(offlineSession);\n\n        logger.debug('Offline session is still valid, embedding app', {shop});\n      } catch (error) {\n        await this.handleInvalidOfflineSession(error, request, shop);\n      }\n    }\n  }\n\n  private async handleAuthBeginRequest(\n    request: Request,\n    shop: string,\n  ): Promise<never> {\n    const {api, config, logger} = this;\n\n    logger.info('Handling OAuth begin request', {shop});\n\n    // If we're loading from an iframe, we need to break out of it\n    if (\n      config.isEmbeddedApp &&\n      request.headers.get('Sec-Fetch-Dest') === 'iframe'\n    ) {\n      logger.debug('Auth request in iframe detected, exiting iframe', {shop});\n      throw redirectWithExitIframe({api, config, logger}, request, shop);\n    } else {\n      throw await beginAuth({api, config, logger}, request, false, shop);\n    }\n  }\n\n  private async handleAuthCallbackRequest(\n    request: Request,\n    shop: string,\n  ): Promise<never> {\n    const {api, config, logger} = this;\n\n    logger.info('Handling OAuth callback request', {shop});\n\n    try {\n      const {session, headers: responseHeaders} = await api.auth.callback({\n        rawRequest: request,\n        expiring: config.future.expiringOfflineAccessTokens,\n      });\n\n      await config.sessionStorage!.storeSession(session);\n\n      if (config.useOnlineTokens && !session.isOnline) {\n        logger.info('Requesting online access token for offline session', {\n          shop,\n        });\n        await beginAuth({api, config, logger}, request, true, shop);\n      }\n\n      logger.debug('Request is valid, loaded session from OAuth callback', {\n        shop: session.shop,\n        isOnline: session.isOnline,\n      });\n\n      await triggerAfterAuthHook({api, config, logger}, session, request, this);\n\n      throw await redirectToShopifyOrAppRoot(\n        request,\n        {api, config, logger},\n        responseHeaders,\n      );\n    } catch (error) {\n      if (error instanceof Response) throw error;\n\n      throw await this.oauthCallbackError(error, request, shop);\n    }\n  }\n\n  private async getOfflineSession(\n    request: Request,\n  ): Promise<Session | undefined> {\n    const offlineId = await this.getOfflineSessionId(request);\n    return this.config.sessionStorage!.loadSession(offlineId!);\n  }\n\n  private async hasValidOfflineId(request: Request) {\n    return Boolean(await this.getOfflineSessionId(request));\n  }\n\n  private async getOfflineSessionId(\n    request: Request,\n  ): Promise<string | undefined> {\n    const {api} = this;\n    const url = new URL(request.url);\n    const shop = url.searchParams.get('shop');\n\n    return shop\n      ? api.session.getOfflineId(shop)\n      : api.session.getCurrentId({isOnline: false, rawRequest: request});\n  }\n\n  private async testSession(session: Session): Promise<void> {\n    const {api} = this;\n\n    const client = new api.clients.Graphql({\n      session,\n    });\n\n    await client.request(`#graphql\n      query shopifyAppShopName {\n        shop {\n          name\n        }\n      }\n    `);\n  }\n\n  private async oauthCallbackError(\n    error: Error,\n    request: Request,\n    shop: string,\n  ) {\n    const {logger} = this;\n    logger.error('Error during OAuth callback', {shop, error: error.message});\n\n    if (error instanceof CookieNotFound) {\n      return this.handleAuthBeginRequest(request, shop);\n    }\n\n    if (\n      error instanceof InvalidHmacError ||\n      error instanceof InvalidOAuthError\n    ) {\n      return new Response(undefined, {\n        status: 400,\n        statusText: 'Invalid OAuth Request',\n      });\n    }\n\n    return new Response(undefined, {\n      status: 500,\n      statusText: 'Internal Server Error',\n    });\n  }\n\n  private async handleInvalidOfflineSession(\n    error: Error,\n    request: Request,\n    shop: string,\n  ) {\n    const {api, logger, config} = this;\n    if (error instanceof HttpResponseError) {\n      if (error.response.code === 401) {\n        logger.info('Shop session is no longer valid, redirecting to OAuth', {\n          shop,\n        });\n        throw await beginAuth({api, config, logger}, request, false, shop);\n      } else {\n        const message = JSON.stringify(error.response.body, null, 2);\n        logger.error(`Unexpected error during session validation: ${message}`, {\n          shop,\n        });\n\n        throw new Response(undefined, {\n          status: error.response.code,\n          statusText: error.response.statusText,\n        });\n      }\n    } else if (error instanceof GraphqlQueryError) {\n      const context: Record<string, string> = {shop};\n      if (error.response) {\n        context.response = JSON.stringify(error.body);\n      }\n\n      logger.error(\n        `Unexpected error during session validation: ${error.message}`,\n        context,\n      );\n\n      throw new Response(undefined, {\n        status: 500,\n        statusText: 'Internal Server Error',\n      });\n    }\n  }\n}\n"],"names":[],"mappings":"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"}