{"version":3,"file":"oauth.mjs","sources":["../../src/components/oauth.ts"],"sourcesContent":["import { useEffect, useState } from \"react\"\nimport { parse as parseUrl, UrlWithParsedQuery } from \"url\"\n\nimport { ConnectOAuthRequestedPayload } from \"@mxenabled/widget-post-message-definitions\"\n\nimport { WebViewRef } from \"./webview\"\nimport { onUrlChange } from \"../platform/deeplink\"\nimport { loadUrlInBrowser, LoadUrlInBrowserProps } from \"./load_url_in_browser\"\n\nexport function makeDefaultConnectOnOAuthRequested(props: LoadUrlInBrowserProps) {\n  return function ({ url }: ConnectOAuthRequestedPayload) {\n    loadUrlInBrowser(url, props)\n  }\n}\n\n/* Used when handling and parsing an OAuth deeplink. This is what the OAuth\n * flow uses to communicate state and status back to the app.\n */\nconst OAuthCompleteHost = \"oauth_complete\"\nconst OAuthStatusSuccess = \"success\"\n\n/* Used when sending a postMessage to the widget. This is what the app uses to\n * communicate the result of an OAuth request after it is redirected back to\n * the app.\n */\nconst OAuthTypeSuccess = \"oauthComplete/success\"\nconst OAuthTypeError = \"oauthComplete/error\"\n\ntype OAuthSuccessRedirectEvent = {\n  type: \"success\"\n  success: boolean\n  memberGuid: string\n}\n\ntype OAuthErrorRedirectEvent = {\n  type: \"error\"\n  success: boolean\n}\n\nexport type OAuthRedirectEvent = OAuthSuccessRedirectEvent | OAuthErrorRedirectEvent\n\nexport type OAuthProps = {\n  sendOAuthPostMessage?: (webViewRef: WebViewRef, msg: string) => void\n}\n\nexport function useOAuthDeeplink(\n  webViewRef: WebViewRef,\n  props: OAuthProps,\n): OAuthRedirectEvent | null {\n  const [ev, setEvent] = useState<OAuthRedirectEvent | null>(null)\n\n  useEffect(() => {\n    return onUrlChange(({ url: rawUrl }) => {\n      const url = parseUrl(rawUrl, true)\n\n      /**\n       * When the ui_message_webview_url_scheme setting is used, our backend\n       * will generate a URL which looks like this:\n       *\n       *   <scheme>://<event>?<query>\n       *\n       * For URLs like these, we need to check the host.\n       *\n       * However, when a client is using Expo in dev/qa mode and doesn't have\n       * access to their app's scheme, they rely on the client_redirect_url\n       * setting which must use the host to specify Expo's application\n       * location. In this case, the redirect URL has to have the specified\n       * event as part of the path:\n       *\n       *   exp://<ip>/--/<event>?<query>\n       *\n       * For URLs like these, we need to check the path.\n       */\n      const isOAuthEventUrl =\n        url.host === OAuthCompleteHost || url.pathname?.includes(OAuthCompleteHost)\n      if (!isOAuthEventUrl) {\n        return\n      }\n\n      const event = buildOAuthRedirectEvent(url)\n      setEvent(event)\n      postOAuthMessage(event, webViewRef, props)\n    })\n  }, [])\n\n  return ev\n}\n\nfunction buildOAuthRedirectEvent(url: UrlWithParsedQuery): OAuthRedirectEvent {\n  const success = url.query[\"status\"] === OAuthStatusSuccess\n  const memberGuid = url.query[\"amp;member_guid\"] || url.query[\"member_guid\"]\n  if (success && typeof memberGuid === \"string\") {\n    return { type: \"success\", success, memberGuid }\n  }\n\n  return { type: \"error\", success: false }\n}\n\nfunction postOAuthMessage(ev: OAuthRedirectEvent, webViewRef: WebViewRef, props: OAuthProps) {\n  if (!webViewRef.current) {\n    return\n  }\n\n  let type: string\n  let metadata: Record<string, unknown>\n  if (ev.type === \"success\") {\n    type = OAuthTypeSuccess\n    metadata = { member_guid: ev.memberGuid }\n  } else {\n    type = OAuthTypeError\n    metadata = {}\n  }\n\n  const message = JSON.stringify({ mx: true, type, metadata })\n\n  if (props.sendOAuthPostMessage) {\n    props.sendOAuthPostMessage(webViewRef, message)\n  } else {\n    webViewRef.current.postMessage(message)\n  }\n}\n"],"names":["makeDefaultConnectOnOAuthRequested","props","url","loadUrlInBrowser","OAuthCompleteHost","OAuthStatusSuccess","OAuthTypeSuccess","OAuthTypeError","useOAuthDeeplink","webViewRef","ev","setEvent","useState","useEffect","onUrlChange","rawUrl","parseUrl","event","buildOAuthRedirectEvent","postOAuthMessage","success","memberGuid","type","metadata","message"],"mappings":";;;;AASO,SAASA,EAAmCC,GAA8B;AAC/E,SAAO,SAAU,EAAE,KAAAC,KAAqC;AACtD,IAAAC,EAAiBD,GAAKD,CAAK;AAAA,EAC7B;AACF;AAKA,MAAMG,IAAoB,kBACpBC,IAAqB,WAMrBC,IAAmB,yBACnBC,IAAiB;AAmBhB,SAASC,EACdC,GACAR,GAC2B;AAC3B,QAAM,CAACS,GAAIC,CAAQ,IAAIC,EAAoC,IAAI;AAE/D,SAAAC,EAAU,MACDC,EAAY,CAAC,EAAE,KAAKC,QAAa;AACtC,UAAMb,IAAMc,EAASD,GAAQ,EAAI;AAsBjC,QAAI,EADFb,EAAI,SAASE,KAAqBF,EAAI,UAAU,SAASE,CAAiB;AAE1E;AAGF,UAAMa,IAAQC,EAAwBhB,CAAG;AACzC,IAAAS,EAASM,CAAK,GACdE,EAAiBF,GAAOR,GAAYR,CAAK;AAAA,EAC3C,CAAC,GACA,CAAA,CAAE,GAEES;AACT;AAEA,SAASQ,EAAwBhB,GAA6C;AAC5E,QAAMkB,IAAUlB,EAAI,MAAM,WAAcG,GAClCgB,IAAanB,EAAI,MAAM,iBAAiB,KAAKA,EAAI,MAAM;AAC7D,SAAIkB,KAAW,OAAOC,KAAe,WAC5B,EAAE,MAAM,WAAW,SAAAD,GAAS,YAAAC,EAAA,IAG9B,EAAE,MAAM,SAAS,SAAS,GAAA;AACnC;AAEA,SAASF,EAAiBT,GAAwBD,GAAwBR,GAAmB;AAC3F,MAAI,CAACQ,EAAW;AACd;AAGF,MAAIa,GACAC;AACJ,EAAIb,EAAG,SAAS,aACdY,IAAOhB,GACPiB,IAAW,EAAE,aAAab,EAAG,WAAA,MAE7BY,IAAOf,GACPgB,IAAW,CAAA;AAGb,QAAMC,IAAU,KAAK,UAAU,EAAE,IAAI,IAAM,MAAAF,GAAM,UAAAC,GAAU;AAE3D,EAAItB,EAAM,uBACRA,EAAM,qBAAqBQ,GAAYe,CAAO,IAE9Cf,EAAW,QAAQ,YAAYe,CAAO;AAE1C;"}