{"version":3,"file":"token-exchange.mjs","sources":["../../../../../../../lib/auth/oauth/token-exchange.ts"],"sourcesContent":["import {throwFailedRequest} from '../../clients/common';\nimport {decodeSessionToken} from '../../session/decode-session-token';\nimport {sanitizeShop} from '../../utils/shop-validator';\nimport {ConfigInterface} from '../../base-types';\nimport {Session} from '../../session/session';\nimport {DataType} from '../../clients/types';\nimport {fetchRequestFactory} from '../../utils/fetch-request';\n\nimport {createSession} from './create-session';\nimport {AccessTokenResponse} from './types';\n\nexport enum RequestedTokenType {\n  OnlineAccessToken = 'urn:shopify:params:oauth:token-type:online-access-token',\n  OfflineAccessToken = 'urn:shopify:params:oauth:token-type:offline-access-token',\n}\n\nconst TokenExchangeGrantType =\n  'urn:ietf:params:oauth:grant-type:token-exchange';\nconst IdTokenType = 'urn:ietf:params:oauth:token-type:id_token';\n\nexport interface TokenExchangeParams {\n  shop: string;\n  sessionToken: string;\n  requestedTokenType: RequestedTokenType;\n  expiring?: boolean;\n}\n\nexport type TokenExchange = (\n  params: TokenExchangeParams,\n) => Promise<{session: Session}>;\n\nexport function tokenExchange(config: ConfigInterface): TokenExchange {\n  return async ({\n    shop,\n    sessionToken,\n    requestedTokenType,\n    expiring,\n  }: TokenExchangeParams) => {\n    await decodeSessionToken(config)(sessionToken);\n\n    const body = {\n      client_id: config.apiKey,\n      client_secret: config.apiSecretKey,\n      grant_type: TokenExchangeGrantType,\n      subject_token: sessionToken,\n      subject_token_type: IdTokenType,\n      requested_token_type: requestedTokenType,\n      expiring: expiring ? '1' : '0',\n    };\n\n    const cleanShop = sanitizeShop(config)(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    return {\n      session: createSession({\n        accessTokenResponse: await postResponse.json<AccessTokenResponse>(),\n        shop: cleanShop,\n        // We need to keep this as an empty string as our template DB schemas have this required\n        state: '',\n        config,\n      }),\n    };\n  };\n}\n"],"names":[],"mappings":";;;;;;;IAWY;AAAZ,CAAA,UAAY,kBAAkB,EAAA;AAC5B,IAAA,kBAAA,CAAA,mBAAA,CAAA,GAAA,yDAA6E;AAC7E,IAAA,kBAAA,CAAA,oBAAA,CAAA,GAAA,0DAA+E;AACjF,CAAC,EAHW,kBAAkB,KAAlB,kBAAkB,GAAA,EAAA,CAAA,CAAA;AAK9B,MAAM,sBAAsB,GAC1B,iDAAiD;AACnD,MAAM,WAAW,GAAG,2CAA2C;AAazD,SAAU,aAAa,CAAC,MAAuB,EAAA;AACnD,IAAA,OAAO,OAAO,EACZ,IAAI,EACJ,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GACY,KAAI;AACxB,QAAA,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC;AAE9C,QAAA,MAAM,IAAI,GAAG;YACX,SAAS,EAAE,MAAM,CAAC,MAAM;YACxB,aAAa,EAAE,MAAM,CAAC,YAAY;AAClC,YAAA,UAAU,EAAE,sBAAsB;AAClC,YAAA,aAAa,EAAE,YAAY;AAC3B,YAAA,kBAAkB,EAAE,WAAW;AAC/B,YAAA,oBAAoB,EAAE,kBAAkB;YACxC,QAAQ,EAAE,QAAQ,GAAG,GAAG,GAAG,GAAG;SAC/B;QAED,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAE;QAEnD,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CACpD,CAAA,QAAA,EAAW,SAAS,CAAA,yBAAA,CAA2B,EAC/C;AACE,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AAC1B,YAAA,OAAO,EAAE;gBACP,cAAc,EAAE,QAAQ,CAAC,IAAI;gBAC7B,MAAM,EAAE,QAAQ,CAAC,IAAI;AACtB,aAAA;AACF,SAAA,CACF;AAED,QAAA,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE;YACpB,kBAAkB,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC;QACpE;QAEA,OAAO;YACL,OAAO,EAAE,aAAa,CAAC;AACrB,gBAAA,mBAAmB,EAAE,MAAM,YAAY,CAAC,IAAI,EAAuB;AACnE,gBAAA,IAAI,EAAE,SAAS;;AAEf,gBAAA,KAAK,EAAE,EAAE;gBACT,MAAM;aACP,CAAC;SACH;AACH,IAAA,CAAC;AACH;;;;"}