{"version":3,"file":"oauth.mjs","sources":["../../../../../../../lib/auth/oauth/oauth.ts"],"sourcesContent":["import {isbot} from 'isbot';\n\nimport {throwFailedRequest} from '../../clients/common';\nimport ProcessedQuery from '../../utils/processed-query';\nimport {ConfigInterface} from '../../base-types';\nimport * as ShopifyErrors from '../../error';\nimport {validateHmac} from '../../utils/hmac-validator';\nimport {sanitizeShop} from '../../utils/shop-validator';\nimport {Session} from '../../session/session';\nimport {\n  abstractConvertRequest,\n  abstractConvertIncomingResponse,\n  abstractConvertResponse,\n  abstractConvertHeaders,\n  AdapterResponse,\n  AdapterHeaders,\n  Cookies,\n  NormalizedResponse,\n  NormalizedRequest,\n} from '../../../runtime/http';\nimport {logger, ShopifyLogger} from '../../logger';\nimport {DataType} from '../../clients/types';\nimport {fetchRequestFactory} from '../../utils/fetch-request';\n\nimport {\n  SESSION_COOKIE_NAME,\n  STATE_COOKIE_NAME,\n  BeginParams,\n  CallbackParams,\n  AuthQuery,\n  AccessTokenResponse,\n} from './types';\nimport {nonce} from './nonce';\nimport {safeCompare} from './safe-compare';\nimport {createSession} from './create-session';\n\nexport type OAuthBegin = (beginParams: BeginParams) => Promise<AdapterResponse>;\n\nexport interface CallbackResponse<T = AdapterHeaders> {\n  headers: T;\n  session: Session;\n}\n\nexport type OAuthCallback = <T = AdapterHeaders>(\n  callbackParams: CallbackParams,\n) => Promise<CallbackResponse<T>>;\n\ninterface BotLog {\n  request: NormalizedRequest;\n  log: ShopifyLogger;\n  func: string;\n}\n\nconst logForBot = ({request, log, func}: BotLog) => {\n  log.debug(`Possible bot request to auth ${func}: `, {\n    userAgent: request.headers['User-Agent'],\n  });\n};\n\nexport function begin(config: ConfigInterface): OAuthBegin {\n  return async ({\n    shop,\n    callbackPath,\n    isOnline,\n    ...adapterArgs\n  }: BeginParams): Promise<AdapterResponse> => {\n    throwIfCustomStoreApp(\n      config.isCustomStoreApp,\n      'Cannot perform OAuth for private apps',\n    );\n\n    const log = logger(config);\n    log.info('Beginning OAuth', {shop, isOnline, callbackPath});\n\n    const request = await abstractConvertRequest(adapterArgs);\n    const response = await abstractConvertIncomingResponse(adapterArgs);\n\n    let userAgent = request.headers['User-Agent'];\n    if (Array.isArray(userAgent)) {\n      userAgent = userAgent[0];\n    }\n    if (isbot(userAgent)) {\n      logForBot({request, log, func: 'begin'});\n      response.statusCode = 410;\n      return abstractConvertResponse(response, adapterArgs);\n    }\n\n    const cookies = new Cookies(request, response, {\n      keys: [config.apiSecretKey],\n      secure: true,\n    });\n\n    const state = nonce();\n\n    await cookies.setAndSign(STATE_COOKIE_NAME, state, {\n      expires: new Date(Date.now() + 60000),\n      sameSite: 'lax',\n      secure: true,\n      path: callbackPath,\n    });\n\n    const scopes = config.scopes ? config.scopes.toString() : '';\n    const query = {\n      client_id: config.apiKey,\n      scope: scopes,\n      redirect_uri: `${config.hostScheme}://${config.hostName}${callbackPath}`,\n      state,\n      'grant_options[]': isOnline ? 'per-user' : '',\n    };\n    const processedQuery = new ProcessedQuery();\n    processedQuery.putAll(query);\n\n    const cleanShop = sanitizeShop(config)(shop, true)!;\n    const redirectUrl = `https://${cleanShop}/admin/oauth/authorize${processedQuery.stringify()}`;\n    response.statusCode = 302;\n    response.statusText = 'Found';\n    response.headers = {\n      ...response.headers,\n      ...cookies.response.headers!,\n      Location: redirectUrl,\n    };\n\n    log.debug(`OAuth started, redirecting to ${redirectUrl}`, {shop, isOnline});\n\n    return abstractConvertResponse(response, adapterArgs);\n  };\n}\n\nexport function callback(config: ConfigInterface): OAuthCallback {\n  return async function callback<T = AdapterHeaders>({\n    expiring,\n    ...adapterArgs\n  }: CallbackParams): Promise<CallbackResponse<T>> {\n    throwIfCustomStoreApp(\n      config.isCustomStoreApp,\n      'Cannot perform OAuth for private apps',\n    );\n\n    const log = logger(config);\n\n    const request = await abstractConvertRequest(adapterArgs);\n\n    const query = new URL(\n      request.url,\n      `${config.hostScheme}://${config.hostName}`,\n    ).searchParams;\n    const shop = query.get('shop')!;\n\n    const response = {} as NormalizedResponse;\n    let userAgent = request.headers['User-Agent'];\n    if (Array.isArray(userAgent)) {\n      userAgent = userAgent[0];\n    }\n    if (isbot(userAgent)) {\n      logForBot({request, log, func: 'callback'});\n      throw new ShopifyErrors.BotActivityDetected(\n        'Invalid OAuth callback initiated by bot',\n      );\n    }\n\n    log.info('Completing OAuth', {shop});\n\n    const cookies = new Cookies(request, response, {\n      keys: [config.apiSecretKey],\n      secure: true,\n    });\n\n    const stateFromCookie = await cookies.getAndVerify(STATE_COOKIE_NAME);\n    cookies.deleteCookie(STATE_COOKIE_NAME);\n    if (!stateFromCookie) {\n      log.error('Could not find OAuth cookie', {shop});\n\n      throw new ShopifyErrors.CookieNotFound(\n        `Cannot complete OAuth process. Could not find an OAuth cookie for shop url: ${shop}`,\n      );\n    }\n\n    const authQuery: AuthQuery = Object.fromEntries(query.entries());\n    if (!(await validQuery({config, query: authQuery, stateFromCookie}))) {\n      log.error('Invalid OAuth callback', {shop, stateFromCookie});\n\n      throw new ShopifyErrors.InvalidOAuthError('Invalid OAuth callback.');\n    }\n\n    log.debug('OAuth request is valid, requesting access token', {shop});\n\n    const body = {\n      client_id: config.apiKey,\n      client_secret: config.apiSecretKey,\n      code: query.get('code'),\n      expiring: expiring ? '1' : '0',\n    };\n\n    const cleanShop = sanitizeShop(config)(query.get('shop')!, true)!;\n\n    const postResponse = await fetchRequestFactory(config)(\n      `https://${cleanShop}/admin/oauth/access_token`,\n      {\n        method: 'POST',\n        body: JSON.stringify(body),\n        headers: {\n          'Content-Type': DataType.JSON,\n          Accept: DataType.JSON,\n        },\n      },\n    );\n\n    if (!postResponse.ok) {\n      throwFailedRequest(await postResponse.json(), false, postResponse);\n    }\n\n    const session: Session = createSession({\n      accessTokenResponse: await postResponse.json<AccessTokenResponse>(),\n      shop: cleanShop,\n      state: stateFromCookie,\n      config,\n    });\n\n    if (!config.isEmbeddedApp) {\n      await cookies.setAndSign(SESSION_COOKIE_NAME, session.id, {\n        expires: session.expires,\n        sameSite: 'lax',\n        secure: true,\n        path: '/',\n      });\n    }\n\n    return {\n      headers: (await abstractConvertHeaders(\n        cookies.response.headers!,\n        adapterArgs,\n      )) as T,\n      session,\n    };\n  };\n}\n\nasync function validQuery({\n  config,\n  query,\n  stateFromCookie,\n}: {\n  config: ConfigInterface;\n  query: AuthQuery;\n  stateFromCookie: string;\n}): Promise<boolean> {\n  return (\n    (await validateHmac(config)(query)) &&\n    safeCompare(query.state!, stateFromCookie)\n  );\n}\n\nfunction throwIfCustomStoreApp(\n  isCustomStoreApp: boolean,\n  message: string,\n): void {\n  if (isCustomStoreApp) {\n    throw new ShopifyErrors.PrivateAppError(message);\n  }\n}\n"],"names":["ShopifyErrors.BotActivityDetected","ShopifyErrors.CookieNotFound","ShopifyErrors.InvalidOAuthError","ShopifyErrors.PrivateAppError"],"mappings":"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"}