@magic-ext/react-native-bare-oauth 27.0.0-canary.915.17279247601.0 → 27.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var P=Object.create;var d=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var S=Object.getPrototypeOf,$=Object.prototype.hasOwnProperty;var M=(e,t)=>{for(var r in t)d(e,r,{get:t[r],enumerable:!0})},h=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of E(t))!$.call(e,n)&&n!==r&&d(e,n,{get:()=>t[n],enumerable:!(o=T(t,n))||o.enumerable});return e};var y=(e,t,r)=>(r=e!=null?P(S(e)):{},h(t||!e||!e.__esModule?d(r,"default",{value:e,enumerable:!0}):r,e)),q=e=>h(d({},"__esModule",{value:!0}),e);var j={};M(j,{OAuthErrorCode:()=>O,OAuthExtension:()=>m,OAuthPayloadMethods:()=>g,createURI:()=>k,getResult:()=>D});module.exports=q(j);var C=require("react-native-inappbrowser-reborn"),w=require("@magic-sdk/react-native-bare"),x=require("react-native-device-info");var b=y(require("crypto-js/sha256")),v=y(require("crypto-js/enc-base64")),R="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",_=typeof window<"u"&&!!window.crypto,B=_&&!!window.crypto.subtle;function H(e){return Array.from(e).map(t=>R[t%R.length]).join("")}function I(e){let t=r=>r.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"");if(e instanceof ArrayBuffer){let r=new Uint8Array(e),o=Array.from(r).map(c=>String.fromCharCode(c)).join(""),n=btoa(o);return t(n)}return t(v.default.stringify(e))}async function N(e){if(B){let t=new TextEncoder().encode(e);return crypto.subtle.digest("SHA-256",t).then(I)}return I((0,b.default)(e))}function A(e){let t=new Uint8Array(e);if(_)window.crypto.getRandomValues(t);else for(let r=0;r<e;r+=1)t[r]=Math.floor(Math.random()*Math.floor(255));return H(t)}async function U(){let e=A(128),t=A(128),r=await N(t);return{verifier:t,challenge:r,state:e}}var g=(t=>(t.ParseRedirectResult="magic_oauth_parse_redirect_result",t))(g||{}),O=(i=>(i.InvalidRequest="invalid_request",i.InvalidClient="invalid_client",i.InvalidScope="invalid_scope",i.InvalidGrant="invalid_grant",i.UnauthorizedClient="unauthorized_client",i.UnsupportedResponseType="unsupported_response_type",i.UnsupportedGrantType="unsupported_grant_type",i.UnsupportedTokenType="unsupported_token_type",i.AccessDenied="access_denied",i.ServerError="server_error",i.TemporarilyUnavailable="temporarily_unavailable",i))(O||{});var m=class extends w.Extension.Internal{name="oauth";config={};compat={"magic-sdk":!1,"@magic-sdk/react-native-bare":">=13.0.0","@magic-sdk/react-native-expo":!1,"@magic-sdk/react-native":!1};loginWithPopup(t){return this.utils.createPromiEvent(async(r,o)=>{try{let{provider:n,query:c,redirectURI:u}=await k.call(this,t),p=`https://auth.magic.link/v1/oauth2/${n}/start?${c}`,a=await C.InAppBrowser.openAuth(p,u,{});if(a.type==="success"){let s=new URL(a.url).search;r(D.call(this,s.toString()))}else o(this.createError(a.type,"User has cancelled the authentication",{}))}catch(n){o(this.createError(n.message,"An error has occurred",{err:n}))}})}},l="oauth_redirect_metadata";async function k(e){await this.utils.storage.removeItem(l);let{provider:t,redirectURI:r,scope:o,loginHint:n}=e,{verifier:c,challenge:u,state:p}=await U(),a=(0,x.getBundleId)(),s=JSON.stringify({verifier:c,state:p});return await this.utils.storage.setItem(l,s),{query:[`magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,`magic_challenge=${encodeURIComponent(u)}`,`state=${encodeURIComponent(p)}`,`platform=${encodeURIComponent("rn")}`,o&&`scope=${encodeURIComponent(o.join(" "))}`,r&&`redirect_uri=${encodeURIComponent(r)}`,n&&`login_hint=${encodeURIComponent(n)}`,a&&`bundleId=${encodeURIComponent(a)}`].reduce((i,f)=>f?`${i}&${f}`:i),provider:t,redirectURI:r}}function D(e){return this.utils.createPromiEvent(async(t,r)=>{let o=await this.utils.storage.getItem(l),{verifier:n,state:c}=JSON.parse(o);this.utils.storage.removeItem(l);let u=this.utils.createJsonRpcRequestPayload("magic_oauth_parse_redirect_result",[e,n,c]),p=await this.request(u),a=p,s=p;s.error&&r(this.createError(s.error,s.error_description??"An error occurred.",{errorURI:s.error_uri,provider:s.provider})),t(a)})}0&&(module.exports={OAuthErrorCode,OAuthExtension,OAuthPayloadMethods,createURI,getResult});
1
+ "use strict";var p=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var I=(n,e)=>{for(var o in e)p(n,o,{get:e[o],enumerable:!0})},O=(n,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of y(e))!A.call(n,t)&&t!==o&&p(n,t,{get:()=>e[t],enumerable:!(r=v(e,t))||r.enumerable});return n};var b=n=>O(p({},"__esModule",{value:!0}),n);var U={};I(U,{OAuthErrorCode:()=>g,OAuthExtension:()=>l,OAuthPayloadMethods:()=>d,getResult:()=>m});module.exports=b(U);var h=require("react-native-inappbrowser-reborn"),R=require("@magic-sdk/react-native-bare");var d=(r=>(r.Start="magic_oauth_login_with_redirect_start",r.Verify="magic_oauth_login_with_redirect_verify",r.Popup="magic_oauth_login_with_popup",r))(d||{}),g=(i=>(i.InvalidRequest="invalid_request",i.InvalidClient="invalid_client",i.InvalidScope="invalid_scope",i.InvalidGrant="invalid_grant",i.UnauthorizedClient="unauthorized_client",i.UnsupportedResponseType="unsupported_response_type",i.UnsupportedGrantType="unsupported_grant_type",i.UnsupportedTokenType="unsupported_token_type",i.AccessDenied="access_denied",i.ServerError="server_error",i.TemporarilyUnavailable="temporarily_unavailable",i))(g||{});var l=class extends R.Extension.Internal{name="oauth";config={};compat={"magic-sdk":!1,"@magic-sdk/react-native-bare":">=13.0.0","@magic-sdk/react-native-expo":!1,"@magic-sdk/react-native":!1};loginWithPopup(e){return this.utils.createPromiEvent(async(o,r)=>{try{let t=this.utils.createJsonRpcRequestPayload("magic_oauth_login_with_redirect_start",[{...e,apiKey:this.sdk.apiKey,platform:"rn"}]),c=await this.request(t),s=c,a=c;if(a.error){r(this.createError(a.error,a.error_description??"An error occurred.",{errorURI:a.error_uri,provider:a.provider}));return}if(!s?.oauthAuthoriationURI){r(this.createError("NO_AUTH_URI","No authorization URI was returned",{}));return}let f=s.oauthAuthoriationURI,u=await h.InAppBrowser.openAuth(f,e.redirectURI,{});if(u.type==="success"){let _=new URL(u.url).search;o(m.call(this,_.toString()))}else r(this.createError(u.type,"User has cancelled the authentication",{}))}catch(t){r(this.createError(t.message,"An error has occurred",{err:t}))}})}};function m(n){return this.utils.createPromiEvent(async(e,o)=>{let r=this.utils.createJsonRpcRequestPayload("magic_oauth_login_with_redirect_verify",[{authorizationResponseParams:n,magicApiKey:this.sdk.apiKey,platform:"rn"}]),t=await this.request(r),c=t,s=t;s.error&&o(this.createError(s.error,s.error_description??"An error occurred.",{errorURI:s.error_uri,provider:s.provider})),e(c)})}0&&(module.exports={OAuthErrorCode,OAuthExtension,OAuthPayloadMethods,getResult});
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/index.ts", "../../src/crypto.ts", "../../src/types.ts"],
4
- "sourcesContent": ["import { InAppBrowser } from 'react-native-inappbrowser-reborn';\nimport { Extension } from '@magic-sdk/react-native-bare';\nimport { getBundleId } from 'react-native-device-info';\nimport { createCryptoChallenge } from './crypto';\nimport {\n OAuthErrorData,\n OAuthPayloadMethods,\n OAuthRedirectConfiguration,\n OAuthRedirectError,\n OAuthRedirectResult,\n} from './types';\n\nexport class OAuthExtension extends Extension.Internal<'oauth'> {\n name = 'oauth' as const;\n config = {};\n compat = {\n 'magic-sdk': false,\n '@magic-sdk/react-native-bare': '>=13.0.0',\n '@magic-sdk/react-native-expo': false,\n '@magic-sdk/react-native': false,\n };\n\n public loginWithPopup(configuration: OAuthRedirectConfiguration) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n try {\n const { provider, query, redirectURI } = await createURI.call(this, configuration);\n const url = `https://auth.magic.link/v1/oauth2/${provider}/start?${query}`;\n\n /**\n * Response Type Inspired by:\n * https://docs.expo.io/versions/latest/sdk/webbrowser/#returns\n */\n const res = await InAppBrowser.openAuth(url, redirectURI, {});\n\n if (res.type === 'success') {\n const queryString = new URL(res.url).search;\n\n resolve(getResult.call(this, queryString.toString()));\n } else {\n reject(this.createError<object>(res.type, 'User has cancelled the authentication', {}));\n }\n } catch (err: any) {\n reject(\n this.createError<object>(err.message, 'An error has occurred', {\n err,\n }),\n );\n }\n });\n }\n}\n\nconst OAUTH_REDIRECT_METADATA_KEY = 'oauth_redirect_metadata';\n\nexport async function createURI(this: OAuthExtension, configuration: OAuthRedirectConfiguration) {\n // Bust any old, in-progress OAuth flows.\n await this.utils.storage.removeItem(OAUTH_REDIRECT_METADATA_KEY);\n\n // Unpack configuration, generate crypto values, and persist to storage.\n const { provider, redirectURI, scope, loginHint } = configuration;\n const { verifier, challenge, state } = await createCryptoChallenge();\n const bundleId = getBundleId();\n\n /* Stringify for RN Async storage */\n const storedData = JSON.stringify({\n verifier,\n state,\n });\n\n await this.utils.storage.setItem(OAUTH_REDIRECT_METADATA_KEY, storedData);\n\n // Formulate the initial redirect query to Magic's OAuth hub.\n // Required fields:\n // - `magic_api_key`\n // - `magic_challenge`\n // - `state`\n // - `redirect_uri`\n // - `platform`\n // Optional fields:\n // - `bundleId`\n\n const query = [\n `magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,\n `magic_challenge=${encodeURIComponent(challenge)}`,\n `state=${encodeURIComponent(state)}`,\n `platform=${encodeURIComponent('rn')}`,\n scope && `scope=${encodeURIComponent(scope.join(' '))}`,\n redirectURI && `redirect_uri=${encodeURIComponent(redirectURI)}`,\n loginHint && `login_hint=${encodeURIComponent(loginHint)}`,\n bundleId && `bundleId=${encodeURIComponent(bundleId)}`,\n ].reduce((prev, next) => (next ? `${prev}&${next}` : prev));\n\n return {\n query,\n provider,\n redirectURI,\n };\n}\n\nexport function getResult(this: OAuthExtension, queryString: string) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n const json: string = (await this.utils.storage.getItem(OAUTH_REDIRECT_METADATA_KEY)) as string;\n\n const { verifier, state } = JSON.parse(json);\n\n // Remove the save OAuth state from storage, it stays in memory now...\n this.utils.storage.removeItem(OAUTH_REDIRECT_METADATA_KEY);\n\n const parseRedirectResult = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.ParseRedirectResult, [\n queryString,\n verifier,\n state,\n ]);\n\n // Parse the result, which may contain an OAuth-formatted error.\n const resultOrError = await this.request<OAuthRedirectResult | OAuthRedirectError>(parseRedirectResult);\n const maybeResult = resultOrError as OAuthRedirectResult;\n const maybeError = resultOrError as OAuthRedirectError;\n\n if (maybeError.error) {\n reject(\n this.createError<OAuthErrorData>(maybeError.error, maybeError.error_description ?? 'An error occurred.', {\n errorURI: maybeError.error_uri,\n provider: maybeError.provider,\n }),\n );\n }\n\n resolve(maybeResult);\n });\n}\n\nexport * from './types';\n", "import Crypto from 'crypto-js';\nimport sha256Fallback from 'crypto-js/sha256';\nimport Base64 from 'crypto-js/enc-base64';\n\nconst CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';\nconst HAS_CRYPTO = typeof window !== 'undefined' && !!(window.crypto as any);\nconst HAS_SUBTLE_CRYPTO = HAS_CRYPTO && !!(window.crypto.subtle as any);\n\n/**\n * Stringifies `bytes` using the OAuth 2.0 `code_verifier` character set.\n */\nfunction bytesToVerifierString(bytes: Uint8Array) {\n return Array.from(bytes)\n .map((value: number) => CHARSET[value % CHARSET.length])\n .join('');\n}\n\n/**\n * Stringifies argument (as CryptoJS `WordArray` or EcmaScript `ArrayBuffer`)\n * and encodes to URL-safe Base64.\n */\nfunction base64URLEncodeFromByteArray(arg: Crypto.lib.WordArray | ArrayBuffer): string {\n const makeURLSafe = (base64: string) => {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n };\n\n if (arg instanceof ArrayBuffer) {\n const bytes = new Uint8Array(arg);\n const utf8Binary = Array.from(bytes)\n .map(value => String.fromCharCode(value))\n .join('');\n\n const base64 = btoa(utf8Binary);\n return makeURLSafe(base64);\n }\n\n return makeURLSafe(Base64.stringify(arg));\n}\n\n/**\n * Produces a SHA-256 hash of the given `message`. This function first attempts\n * to use the browser's built-in `SubtleCrypto` API, falling back to\n * CryptoJS if required.\n */\nasync function sha256(message: string) {\n if (HAS_SUBTLE_CRYPTO) {\n const bytes = new TextEncoder().encode(message);\n return crypto.subtle.digest('SHA-256', bytes).then(base64URLEncodeFromByteArray);\n }\n\n return base64URLEncodeFromByteArray(sha256Fallback(message));\n}\n\n/**\n * Creates a cryptographically random string using the browser's built-in\n * `Crypto` API, falling back to `Math.random` if required.\n */\nfunction createRandomString(size: number) {\n const bytes = new Uint8Array(size);\n\n if (HAS_CRYPTO) {\n window.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < size; i += 1) bytes[i] = Math.floor(Math.random() * Math.floor(255));\n }\n\n return bytesToVerifierString(bytes);\n}\n\n/**\n * Creates OAuth 2.0-compatible `code_verifier`, `code_challenge`, and `state`\n * parameters.\n */\nexport async function createCryptoChallenge() {\n const state = createRandomString(128);\n const verifier = createRandomString(128);\n const challenge = await sha256(verifier);\n return { verifier, challenge, state };\n}\n", "import { MagicUserMetadata } from '@magic-sdk/types';\n\nexport enum OAuthPayloadMethods {\n ParseRedirectResult = 'magic_oauth_parse_redirect_result',\n}\n\nexport type OAuthProvider =\n | 'google'\n | 'facebook'\n | 'apple'\n | 'github'\n | 'bitbucket'\n | 'gitlab'\n | 'linkedin'\n | 'twitter'\n | 'discord'\n | 'twitch'\n | 'microsoft';\n\nexport interface OAuthErrorData {\n provider: OAuthProvider;\n errorURI?: string;\n}\n\nexport interface OpenIDConnectProfile {\n name?: string;\n familyName?: string;\n givenName?: string;\n middleName?: string;\n nickname?: string;\n preferredUsername?: string;\n profile?: string;\n picture?: string;\n website?: string;\n gender?: string;\n birthdate?: string;\n zoneinfo?: string;\n locale?: string;\n updatedAt?: number;\n}\n\nexport interface OpenIDConnectEmail {\n email?: string;\n emailVerified?: boolean;\n}\n\nexport interface OpenIDConnectPhone {\n phoneNumber?: string;\n phoneNumberVerified?: boolean;\n}\n\nexport interface OpenIDConnectAddress {\n address?: {\n formatted?: string;\n streetAddress?: string;\n locality?: string;\n region?: string;\n postalCode?: string;\n country?: string;\n };\n}\n\nexport type OpenIDConnectUserInfo = OpenIDConnectProfile &\n OpenIDConnectEmail &\n OpenIDConnectPhone &\n OpenIDConnectAddress & { sub?: string; sources?: Record<string, any> } & Record<string, any>;\n\nexport interface OAuthRedirectResult {\n oauth: {\n provider: OAuthProvider;\n scope: string[];\n accessToken: string;\n userHandle: string;\n userInfo: OpenIDConnectUserInfo;\n };\n\n magic: {\n idToken: string;\n userMetadata: MagicUserMetadata;\n };\n}\n\nexport interface OAuthRedirectError {\n provider: OAuthProvider;\n error: string;\n error_description?: string;\n error_uri?: string;\n}\n\nexport interface OAuthRedirectConfiguration {\n provider: OAuthProvider;\n redirectURI: string;\n scope?: string[];\n loginHint?: string;\n}\n\nexport enum OAuthErrorCode {\n InvalidRequest = 'invalid_request',\n InvalidClient = 'invalid_client',\n InvalidScope = 'invalid_scope',\n InvalidGrant = 'invalid_grant',\n UnauthorizedClient = 'unauthorized_client',\n UnsupportedResponseType = 'unsupported_response_type',\n UnsupportedGrantType = 'unsupported_grant_type',\n UnsupportedTokenType = 'unsupported_token_type',\n AccessDenied = 'access_denied',\n ServerError = 'server_error',\n TemporarilyUnavailable = 'temporarily_unavailable',\n}\n"],
5
- "mappings": "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",
6
- "names": ["index_exports", "__export", "OAuthErrorCode", "OAuthExtension", "OAuthPayloadMethods", "createURI", "getResult", "__toCommonJS", "import_react_native_inappbrowser_reborn", "import_react_native_bare", "import_react_native_device_info", "import_sha256", "import_enc_base64", "CHARSET", "HAS_CRYPTO", "HAS_SUBTLE_CRYPTO", "bytesToVerifierString", "bytes", "value", "base64URLEncodeFromByteArray", "arg", "makeURLSafe", "base64", "utf8Binary", "Base64", "sha256", "message", "sha256Fallback", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "configuration", "resolve", "reject", "provider", "query", "redirectURI", "createURI", "url", "res", "queryString", "getResult", "err", "OAUTH_REDIRECT_METADATA_KEY", "scope", "loginHint", "verifier", "challenge", "state", "createCryptoChallenge", "bundleId", "storedData", "prev", "next", "json", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
3
+ "sources": ["../../src/index.ts", "../../src/types.ts"],
4
+ "sourcesContent": ["import { InAppBrowser } from 'react-native-inappbrowser-reborn';\nimport { Extension } from '@magic-sdk/react-native-bare';\nimport {\n OAuthErrorData,\n OAuthPayloadMethods,\n OAuthRedirectConfiguration,\n OAuthRedirectError,\n OAuthRedirectResult,\n OAuthRedirectStartResult,\n} from './types';\n\nexport class OAuthExtension extends Extension.Internal<'oauth'> {\n name = 'oauth' as const;\n config = {};\n compat = {\n 'magic-sdk': false,\n '@magic-sdk/react-native-bare': '>=13.0.0',\n '@magic-sdk/react-native-expo': false,\n '@magic-sdk/react-native': false,\n };\n\n public loginWithPopup(configuration: OAuthRedirectConfiguration) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n try {\n const startPayload = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.Start, [\n {\n ...configuration,\n apiKey: this.sdk.apiKey,\n platform: 'rn',\n },\n ]);\n\n const result = await this.request<OAuthRedirectStartResult | OAuthRedirectError>(startPayload);\n const successResult = result as OAuthRedirectStartResult;\n const errorResult = result as OAuthRedirectError;\n\n if (errorResult.error) {\n reject(\n this.createError<OAuthErrorData>(errorResult.error, errorResult.error_description ?? 'An error occurred.', {\n errorURI: errorResult.error_uri,\n provider: errorResult.provider,\n }),\n );\n return;\n }\n\n if (!successResult?.oauthAuthoriationURI) {\n reject(this.createError<object>('NO_AUTH_URI', 'No authorization URI was returned', {}));\n return;\n }\n\n const url = successResult.oauthAuthoriationURI;\n const res = await InAppBrowser.openAuth(url, configuration.redirectURI, {});\n\n if (res.type === 'success') {\n const queryString = new URL(res.url).search;\n resolve(getResult.call(this, queryString.toString()));\n } else {\n reject(this.createError<object>(res.type, 'User has cancelled the authentication', {}));\n }\n } catch (err: any) {\n reject(\n this.createError<object>(err.message, 'An error has occurred', {\n err,\n }),\n );\n }\n });\n }\n}\n\nexport function getResult(this: OAuthExtension, queryString: string) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n const parseRedirectResult = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.Verify, [\n {\n authorizationResponseParams: queryString,\n magicApiKey: this.sdk.apiKey,\n platform: 'rn',\n },\n ]);\n\n // Parse the result, which may contain an OAuth-formatted error.\n const resultOrError = await this.request<OAuthRedirectResult | OAuthRedirectError>(parseRedirectResult);\n const maybeResult = resultOrError as OAuthRedirectResult;\n const maybeError = resultOrError as OAuthRedirectError;\n\n if (maybeError.error) {\n reject(\n this.createError<OAuthErrorData>(maybeError.error, maybeError.error_description ?? 'An error occurred.', {\n errorURI: maybeError.error_uri,\n provider: maybeError.provider,\n }),\n );\n }\n\n resolve(maybeResult);\n });\n}\n\nexport * from './types';\n", "import { MagicUserMetadata } from '@magic-sdk/types';\n\nexport enum OAuthPayloadMethods {\n Start = 'magic_oauth_login_with_redirect_start',\n Verify = 'magic_oauth_login_with_redirect_verify',\n Popup = 'magic_oauth_login_with_popup',\n}\n\nexport type OAuthProvider =\n | 'google'\n | 'facebook'\n | 'apple'\n | 'github'\n | 'bitbucket'\n | 'gitlab'\n | 'linkedin'\n | 'twitter'\n | 'discord'\n | 'twitch'\n | 'microsoft';\n\nexport interface OAuthErrorData {\n provider: OAuthProvider;\n errorURI?: string;\n}\n\nexport interface OpenIDConnectProfile {\n name?: string;\n familyName?: string;\n givenName?: string;\n middleName?: string;\n nickname?: string;\n preferredUsername?: string;\n profile?: string;\n picture?: string;\n website?: string;\n gender?: string;\n birthdate?: string;\n zoneinfo?: string;\n locale?: string;\n updatedAt?: number;\n}\n\nexport interface OpenIDConnectEmail {\n email?: string;\n emailVerified?: boolean;\n}\n\nexport interface OpenIDConnectPhone {\n phoneNumber?: string;\n phoneNumberVerified?: boolean;\n}\n\nexport interface OpenIDConnectAddress {\n address?: {\n formatted?: string;\n streetAddress?: string;\n locality?: string;\n region?: string;\n postalCode?: string;\n country?: string;\n };\n}\n\nexport type OpenIDConnectUserInfo = OpenIDConnectProfile &\n OpenIDConnectEmail &\n OpenIDConnectPhone &\n OpenIDConnectAddress & { sub?: string; sources?: Record<string, any> } & Record<string, any>;\n\nexport interface OAuthRedirectResult {\n oauth: {\n provider: OAuthProvider;\n scope: string[];\n accessToken: string;\n userHandle: string;\n userInfo: OpenIDConnectUserInfo;\n };\n\n magic: {\n idToken: string;\n userMetadata: MagicUserMetadata;\n };\n}\n\nexport interface OAuthRedirectError {\n provider: OAuthProvider;\n error: string;\n error_description?: string;\n error_uri?: string;\n}\n\nexport interface OAuthRedirectConfiguration {\n provider: OAuthProvider;\n redirectURI: string;\n scope?: string[];\n loginHint?: string;\n}\n\nexport enum OAuthErrorCode {\n InvalidRequest = 'invalid_request',\n InvalidClient = 'invalid_client',\n InvalidScope = 'invalid_scope',\n InvalidGrant = 'invalid_grant',\n UnauthorizedClient = 'unauthorized_client',\n UnsupportedResponseType = 'unsupported_response_type',\n UnsupportedGrantType = 'unsupported_grant_type',\n UnsupportedTokenType = 'unsupported_token_type',\n AccessDenied = 'access_denied',\n ServerError = 'server_error',\n TemporarilyUnavailable = 'temporarily_unavailable',\n}\n\nexport interface OAuthRedirectStartResult {\n oauthAuthoriationURI?: string;\n useMagicServerCallback?: boolean;\n shouldReturnURI?: boolean;\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oBAAAE,EAAA,mBAAAC,EAAA,wBAAAC,EAAA,cAAAC,IAAA,eAAAC,EAAAN,GAAA,IAAAO,EAA6B,4CAC7BC,EAA0B,wCCCnB,IAAKC,OACVA,EAAA,MAAQ,wCACRA,EAAA,OAAS,yCACTA,EAAA,MAAQ,+BAHEA,OAAA,IAgGAC,OACVA,EAAA,eAAiB,kBACjBA,EAAA,cAAgB,iBAChBA,EAAA,aAAe,gBACfA,EAAA,aAAe,gBACfA,EAAA,mBAAqB,sBACrBA,EAAA,wBAA0B,4BAC1BA,EAAA,qBAAuB,yBACvBA,EAAA,qBAAuB,yBACvBA,EAAA,aAAe,gBACfA,EAAA,YAAc,eACdA,EAAA,uBAAyB,0BAXfA,OAAA,IDvFL,IAAMC,EAAN,cAA6B,YAAU,QAAkB,CAC9D,KAAO,QACP,OAAS,CAAC,EACV,OAAS,CACP,YAAa,GACb,+BAAgC,WAChC,+BAAgC,GAChC,0BAA2B,EAC7B,EAEO,eAAeC,EAA2C,CAC/D,OAAO,KAAK,MAAM,iBAAsC,MAAOC,EAASC,IAAW,CACjF,GAAI,CACF,IAAMC,EAAe,KAAK,MAAM,oEAAuD,CACrF,CACE,GAAGH,EACH,OAAQ,KAAK,IAAI,OACjB,SAAU,IACZ,CACF,CAAC,EAEKI,EAAS,MAAM,KAAK,QAAuDD,CAAY,EACvFE,EAAgBD,EAChBE,EAAcF,EAEpB,GAAIE,EAAY,MAAO,CACrBJ,EACE,KAAK,YAA4BI,EAAY,MAAOA,EAAY,mBAAqB,qBAAsB,CACzG,SAAUA,EAAY,UACtB,SAAUA,EAAY,QACxB,CAAC,CACH,EACA,MACF,CAEA,GAAI,CAACD,GAAe,qBAAsB,CACxCH,EAAO,KAAK,YAAoB,cAAe,oCAAqC,CAAC,CAAC,CAAC,EACvF,MACF,CAEA,IAAMK,EAAMF,EAAc,qBACpBG,EAAM,MAAM,eAAa,SAASD,EAAKP,EAAc,YAAa,CAAC,CAAC,EAE1E,GAAIQ,EAAI,OAAS,UAAW,CAC1B,IAAMC,EAAc,IAAI,IAAID,EAAI,GAAG,EAAE,OACrCP,EAAQS,EAAU,KAAK,KAAMD,EAAY,SAAS,CAAC,CAAC,CACtD,MACEP,EAAO,KAAK,YAAoBM,EAAI,KAAM,wCAAyC,CAAC,CAAC,CAAC,CAE1F,OAASG,EAAU,CACjBT,EACE,KAAK,YAAoBS,EAAI,QAAS,wBAAyB,CAC7D,IAAAA,CACF,CAAC,CACH,CACF,CACF,CAAC,CACH,CACF,EAEO,SAASD,EAAgCD,EAAqB,CACnE,OAAO,KAAK,MAAM,iBAAsC,MAAOR,EAASC,IAAW,CACjF,IAAMU,EAAsB,KAAK,MAAM,qEAAwD,CAC7F,CACE,4BAA6BH,EAC7B,YAAa,KAAK,IAAI,OACtB,SAAU,IACZ,CACF,CAAC,EAGKI,EAAgB,MAAM,KAAK,QAAkDD,CAAmB,EAChGE,EAAcD,EACdE,EAAaF,EAEfE,EAAW,OACbb,EACE,KAAK,YAA4Ba,EAAW,MAAOA,EAAW,mBAAqB,qBAAsB,CACvG,SAAUA,EAAW,UACrB,SAAUA,EAAW,QACvB,CAAC,CACH,EAGFd,EAAQa,CAAW,CACrB,CAAC,CACH",
6
+ "names": ["index_exports", "__export", "OAuthErrorCode", "OAuthExtension", "OAuthPayloadMethods", "getResult", "__toCommonJS", "import_react_native_inappbrowser_reborn", "import_react_native_bare", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "configuration", "resolve", "reject", "startPayload", "result", "successResult", "errorResult", "url", "res", "queryString", "getResult", "err", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
7
7
  }
package/dist/es/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{InAppBrowser as C}from"react-native-inappbrowser-reborn";import{Extension as w}from"@magic-sdk/react-native-bare";import{getBundleId as x}from"react-native-device-info";import A from"crypto-js/sha256";import b from"crypto-js/enc-base64";var g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",h=typeof window<"u"&&!!window.crypto,v=h&&!!window.crypto.subtle;function _(t){return Array.from(t).map(e=>g[e%g.length]).join("")}function m(t){let e=r=>r.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"");if(t instanceof ArrayBuffer){let r=new Uint8Array(t),o=Array.from(r).map(c=>String.fromCharCode(c)).join(""),i=btoa(o);return e(i)}return e(b.stringify(t))}async function U(t){if(v){let e=new TextEncoder().encode(t);return crypto.subtle.digest("SHA-256",e).then(m)}return m(A(t))}function f(t){let e=new Uint8Array(t);if(h)window.crypto.getRandomValues(e);else for(let r=0;r<t;r+=1)e[r]=Math.floor(Math.random()*Math.floor(255));return _(e)}async function y(){let t=f(128),e=f(128),r=await U(e);return{verifier:e,challenge:r,state:t}}var R=(e=>(e.ParseRedirectResult="magic_oauth_parse_redirect_result",e))(R||{}),O=(n=>(n.InvalidRequest="invalid_request",n.InvalidClient="invalid_client",n.InvalidScope="invalid_scope",n.InvalidGrant="invalid_grant",n.UnauthorizedClient="unauthorized_client",n.UnsupportedResponseType="unsupported_response_type",n.UnsupportedGrantType="unsupported_grant_type",n.UnsupportedTokenType="unsupported_token_type",n.AccessDenied="access_denied",n.ServerError="server_error",n.TemporarilyUnavailable="temporarily_unavailable",n))(O||{});var I=class extends w.Internal{name="oauth";config={};compat={"magic-sdk":!1,"@magic-sdk/react-native-bare":">=13.0.0","@magic-sdk/react-native-expo":!1,"@magic-sdk/react-native":!1};loginWithPopup(e){return this.utils.createPromiEvent(async(r,o)=>{try{let{provider:i,query:c,redirectURI:u}=await k.call(this,e),p=`https://auth.magic.link/v1/oauth2/${i}/start?${c}`,a=await C.openAuth(p,u,{});if(a.type==="success"){let s=new URL(a.url).search;r(D.call(this,s.toString()))}else o(this.createError(a.type,"User has cancelled the authentication",{}))}catch(i){o(this.createError(i.message,"An error has occurred",{err:i}))}})}},d="oauth_redirect_metadata";async function k(t){await this.utils.storage.removeItem(d);let{provider:e,redirectURI:r,scope:o,loginHint:i}=t,{verifier:c,challenge:u,state:p}=await y(),a=x(),s=JSON.stringify({verifier:c,state:p});return await this.utils.storage.setItem(d,s),{query:[`magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,`magic_challenge=${encodeURIComponent(u)}`,`state=${encodeURIComponent(p)}`,`platform=${encodeURIComponent("rn")}`,o&&`scope=${encodeURIComponent(o.join(" "))}`,r&&`redirect_uri=${encodeURIComponent(r)}`,i&&`login_hint=${encodeURIComponent(i)}`,a&&`bundleId=${encodeURIComponent(a)}`].reduce((n,l)=>l?`${n}&${l}`:n),provider:e,redirectURI:r}}function D(t){return this.utils.createPromiEvent(async(e,r)=>{let o=await this.utils.storage.getItem(d),{verifier:i,state:c}=JSON.parse(o);this.utils.storage.removeItem(d);let u=this.utils.createJsonRpcRequestPayload("magic_oauth_parse_redirect_result",[t,i,c]),p=await this.request(u),a=p,s=p;s.error&&r(this.createError(s.error,s.error_description??"An error occurred.",{errorURI:s.error_uri,provider:s.provider})),e(a)})}export{O as OAuthErrorCode,I as OAuthExtension,R as OAuthPayloadMethods,k as createURI,D as getResult};
1
+ import{InAppBrowser as R}from"react-native-inappbrowser-reborn";import{Extension as m}from"@magic-sdk/react-native-bare";var p=(r=>(r.Start="magic_oauth_login_with_redirect_start",r.Verify="magic_oauth_login_with_redirect_verify",r.Popup="magic_oauth_login_with_popup",r))(p||{}),h=(e=>(e.InvalidRequest="invalid_request",e.InvalidClient="invalid_client",e.InvalidScope="invalid_scope",e.InvalidGrant="invalid_grant",e.UnauthorizedClient="unauthorized_client",e.UnsupportedResponseType="unsupported_response_type",e.UnsupportedGrantType="unsupported_grant_type",e.UnsupportedTokenType="unsupported_token_type",e.AccessDenied="access_denied",e.ServerError="server_error",e.TemporarilyUnavailable="temporarily_unavailable",e))(h||{});var d=class extends m.Internal{name="oauth";config={};compat={"magic-sdk":!1,"@magic-sdk/react-native-bare":">=13.0.0","@magic-sdk/react-native-expo":!1,"@magic-sdk/react-native":!1};loginWithPopup(o){return this.utils.createPromiEvent(async(a,r)=>{try{let i=this.utils.createJsonRpcRequestPayload("magic_oauth_login_with_redirect_start",[{...o,apiKey:this.sdk.apiKey,platform:"rn"}]),s=await this.request(i),t=s,n=s;if(n.error){r(this.createError(n.error,n.error_description??"An error occurred.",{errorURI:n.error_uri,provider:n.provider}));return}if(!t?.oauthAuthoriationURI){r(this.createError("NO_AUTH_URI","No authorization URI was returned",{}));return}let l=t.oauthAuthoriationURI,c=await R.openAuth(l,o.redirectURI,{});if(c.type==="success"){let g=new URL(c.url).search;a(f.call(this,g.toString()))}else r(this.createError(c.type,"User has cancelled the authentication",{}))}catch(i){r(this.createError(i.message,"An error has occurred",{err:i}))}})}};function f(u){return this.utils.createPromiEvent(async(o,a)=>{let r=this.utils.createJsonRpcRequestPayload("magic_oauth_login_with_redirect_verify",[{authorizationResponseParams:u,magicApiKey:this.sdk.apiKey,platform:"rn"}]),i=await this.request(r),s=i,t=i;t.error&&a(this.createError(t.error,t.error_description??"An error occurred.",{errorURI:t.error_uri,provider:t.provider})),o(s)})}export{h as OAuthErrorCode,d as OAuthExtension,p as OAuthPayloadMethods,f as getResult};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/index.ts", "../../src/crypto.ts", "../../src/types.ts"],
4
- "sourcesContent": ["import { InAppBrowser } from 'react-native-inappbrowser-reborn';\nimport { Extension } from '@magic-sdk/react-native-bare';\nimport { getBundleId } from 'react-native-device-info';\nimport { createCryptoChallenge } from './crypto';\nimport {\n OAuthErrorData,\n OAuthPayloadMethods,\n OAuthRedirectConfiguration,\n OAuthRedirectError,\n OAuthRedirectResult,\n} from './types';\n\nexport class OAuthExtension extends Extension.Internal<'oauth'> {\n name = 'oauth' as const;\n config = {};\n compat = {\n 'magic-sdk': false,\n '@magic-sdk/react-native-bare': '>=13.0.0',\n '@magic-sdk/react-native-expo': false,\n '@magic-sdk/react-native': false,\n };\n\n public loginWithPopup(configuration: OAuthRedirectConfiguration) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n try {\n const { provider, query, redirectURI } = await createURI.call(this, configuration);\n const url = `https://auth.magic.link/v1/oauth2/${provider}/start?${query}`;\n\n /**\n * Response Type Inspired by:\n * https://docs.expo.io/versions/latest/sdk/webbrowser/#returns\n */\n const res = await InAppBrowser.openAuth(url, redirectURI, {});\n\n if (res.type === 'success') {\n const queryString = new URL(res.url).search;\n\n resolve(getResult.call(this, queryString.toString()));\n } else {\n reject(this.createError<object>(res.type, 'User has cancelled the authentication', {}));\n }\n } catch (err: any) {\n reject(\n this.createError<object>(err.message, 'An error has occurred', {\n err,\n }),\n );\n }\n });\n }\n}\n\nconst OAUTH_REDIRECT_METADATA_KEY = 'oauth_redirect_metadata';\n\nexport async function createURI(this: OAuthExtension, configuration: OAuthRedirectConfiguration) {\n // Bust any old, in-progress OAuth flows.\n await this.utils.storage.removeItem(OAUTH_REDIRECT_METADATA_KEY);\n\n // Unpack configuration, generate crypto values, and persist to storage.\n const { provider, redirectURI, scope, loginHint } = configuration;\n const { verifier, challenge, state } = await createCryptoChallenge();\n const bundleId = getBundleId();\n\n /* Stringify for RN Async storage */\n const storedData = JSON.stringify({\n verifier,\n state,\n });\n\n await this.utils.storage.setItem(OAUTH_REDIRECT_METADATA_KEY, storedData);\n\n // Formulate the initial redirect query to Magic's OAuth hub.\n // Required fields:\n // - `magic_api_key`\n // - `magic_challenge`\n // - `state`\n // - `redirect_uri`\n // - `platform`\n // Optional fields:\n // - `bundleId`\n\n const query = [\n `magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,\n `magic_challenge=${encodeURIComponent(challenge)}`,\n `state=${encodeURIComponent(state)}`,\n `platform=${encodeURIComponent('rn')}`,\n scope && `scope=${encodeURIComponent(scope.join(' '))}`,\n redirectURI && `redirect_uri=${encodeURIComponent(redirectURI)}`,\n loginHint && `login_hint=${encodeURIComponent(loginHint)}`,\n bundleId && `bundleId=${encodeURIComponent(bundleId)}`,\n ].reduce((prev, next) => (next ? `${prev}&${next}` : prev));\n\n return {\n query,\n provider,\n redirectURI,\n };\n}\n\nexport function getResult(this: OAuthExtension, queryString: string) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n const json: string = (await this.utils.storage.getItem(OAUTH_REDIRECT_METADATA_KEY)) as string;\n\n const { verifier, state } = JSON.parse(json);\n\n // Remove the save OAuth state from storage, it stays in memory now...\n this.utils.storage.removeItem(OAUTH_REDIRECT_METADATA_KEY);\n\n const parseRedirectResult = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.ParseRedirectResult, [\n queryString,\n verifier,\n state,\n ]);\n\n // Parse the result, which may contain an OAuth-formatted error.\n const resultOrError = await this.request<OAuthRedirectResult | OAuthRedirectError>(parseRedirectResult);\n const maybeResult = resultOrError as OAuthRedirectResult;\n const maybeError = resultOrError as OAuthRedirectError;\n\n if (maybeError.error) {\n reject(\n this.createError<OAuthErrorData>(maybeError.error, maybeError.error_description ?? 'An error occurred.', {\n errorURI: maybeError.error_uri,\n provider: maybeError.provider,\n }),\n );\n }\n\n resolve(maybeResult);\n });\n}\n\nexport * from './types';\n", "import Crypto from 'crypto-js';\nimport sha256Fallback from 'crypto-js/sha256';\nimport Base64 from 'crypto-js/enc-base64';\n\nconst CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';\nconst HAS_CRYPTO = typeof window !== 'undefined' && !!(window.crypto as any);\nconst HAS_SUBTLE_CRYPTO = HAS_CRYPTO && !!(window.crypto.subtle as any);\n\n/**\n * Stringifies `bytes` using the OAuth 2.0 `code_verifier` character set.\n */\nfunction bytesToVerifierString(bytes: Uint8Array) {\n return Array.from(bytes)\n .map((value: number) => CHARSET[value % CHARSET.length])\n .join('');\n}\n\n/**\n * Stringifies argument (as CryptoJS `WordArray` or EcmaScript `ArrayBuffer`)\n * and encodes to URL-safe Base64.\n */\nfunction base64URLEncodeFromByteArray(arg: Crypto.lib.WordArray | ArrayBuffer): string {\n const makeURLSafe = (base64: string) => {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n };\n\n if (arg instanceof ArrayBuffer) {\n const bytes = new Uint8Array(arg);\n const utf8Binary = Array.from(bytes)\n .map(value => String.fromCharCode(value))\n .join('');\n\n const base64 = btoa(utf8Binary);\n return makeURLSafe(base64);\n }\n\n return makeURLSafe(Base64.stringify(arg));\n}\n\n/**\n * Produces a SHA-256 hash of the given `message`. This function first attempts\n * to use the browser's built-in `SubtleCrypto` API, falling back to\n * CryptoJS if required.\n */\nasync function sha256(message: string) {\n if (HAS_SUBTLE_CRYPTO) {\n const bytes = new TextEncoder().encode(message);\n return crypto.subtle.digest('SHA-256', bytes).then(base64URLEncodeFromByteArray);\n }\n\n return base64URLEncodeFromByteArray(sha256Fallback(message));\n}\n\n/**\n * Creates a cryptographically random string using the browser's built-in\n * `Crypto` API, falling back to `Math.random` if required.\n */\nfunction createRandomString(size: number) {\n const bytes = new Uint8Array(size);\n\n if (HAS_CRYPTO) {\n window.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < size; i += 1) bytes[i] = Math.floor(Math.random() * Math.floor(255));\n }\n\n return bytesToVerifierString(bytes);\n}\n\n/**\n * Creates OAuth 2.0-compatible `code_verifier`, `code_challenge`, and `state`\n * parameters.\n */\nexport async function createCryptoChallenge() {\n const state = createRandomString(128);\n const verifier = createRandomString(128);\n const challenge = await sha256(verifier);\n return { verifier, challenge, state };\n}\n", "import { MagicUserMetadata } from '@magic-sdk/types';\n\nexport enum OAuthPayloadMethods {\n ParseRedirectResult = 'magic_oauth_parse_redirect_result',\n}\n\nexport type OAuthProvider =\n | 'google'\n | 'facebook'\n | 'apple'\n | 'github'\n | 'bitbucket'\n | 'gitlab'\n | 'linkedin'\n | 'twitter'\n | 'discord'\n | 'twitch'\n | 'microsoft';\n\nexport interface OAuthErrorData {\n provider: OAuthProvider;\n errorURI?: string;\n}\n\nexport interface OpenIDConnectProfile {\n name?: string;\n familyName?: string;\n givenName?: string;\n middleName?: string;\n nickname?: string;\n preferredUsername?: string;\n profile?: string;\n picture?: string;\n website?: string;\n gender?: string;\n birthdate?: string;\n zoneinfo?: string;\n locale?: string;\n updatedAt?: number;\n}\n\nexport interface OpenIDConnectEmail {\n email?: string;\n emailVerified?: boolean;\n}\n\nexport interface OpenIDConnectPhone {\n phoneNumber?: string;\n phoneNumberVerified?: boolean;\n}\n\nexport interface OpenIDConnectAddress {\n address?: {\n formatted?: string;\n streetAddress?: string;\n locality?: string;\n region?: string;\n postalCode?: string;\n country?: string;\n };\n}\n\nexport type OpenIDConnectUserInfo = OpenIDConnectProfile &\n OpenIDConnectEmail &\n OpenIDConnectPhone &\n OpenIDConnectAddress & { sub?: string; sources?: Record<string, any> } & Record<string, any>;\n\nexport interface OAuthRedirectResult {\n oauth: {\n provider: OAuthProvider;\n scope: string[];\n accessToken: string;\n userHandle: string;\n userInfo: OpenIDConnectUserInfo;\n };\n\n magic: {\n idToken: string;\n userMetadata: MagicUserMetadata;\n };\n}\n\nexport interface OAuthRedirectError {\n provider: OAuthProvider;\n error: string;\n error_description?: string;\n error_uri?: string;\n}\n\nexport interface OAuthRedirectConfiguration {\n provider: OAuthProvider;\n redirectURI: string;\n scope?: string[];\n loginHint?: string;\n}\n\nexport enum OAuthErrorCode {\n InvalidRequest = 'invalid_request',\n InvalidClient = 'invalid_client',\n InvalidScope = 'invalid_scope',\n InvalidGrant = 'invalid_grant',\n UnauthorizedClient = 'unauthorized_client',\n UnsupportedResponseType = 'unsupported_response_type',\n UnsupportedGrantType = 'unsupported_grant_type',\n UnsupportedTokenType = 'unsupported_token_type',\n AccessDenied = 'access_denied',\n ServerError = 'server_error',\n TemporarilyUnavailable = 'temporarily_unavailable',\n}\n"],
5
- "mappings": "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",
6
- "names": ["InAppBrowser", "Extension", "getBundleId", "sha256Fallback", "Base64", "CHARSET", "HAS_CRYPTO", "HAS_SUBTLE_CRYPTO", "bytesToVerifierString", "bytes", "value", "base64URLEncodeFromByteArray", "arg", "makeURLSafe", "base64", "utf8Binary", "sha256", "message", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "Extension", "configuration", "resolve", "reject", "provider", "query", "redirectURI", "createURI", "url", "res", "InAppBrowser", "queryString", "getResult", "err", "OAUTH_REDIRECT_METADATA_KEY", "scope", "loginHint", "verifier", "challenge", "state", "createCryptoChallenge", "bundleId", "getBundleId", "storedData", "prev", "next", "json", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
3
+ "sources": ["../../src/index.ts", "../../src/types.ts"],
4
+ "sourcesContent": ["import { InAppBrowser } from 'react-native-inappbrowser-reborn';\nimport { Extension } from '@magic-sdk/react-native-bare';\nimport {\n OAuthErrorData,\n OAuthPayloadMethods,\n OAuthRedirectConfiguration,\n OAuthRedirectError,\n OAuthRedirectResult,\n OAuthRedirectStartResult,\n} from './types';\n\nexport class OAuthExtension extends Extension.Internal<'oauth'> {\n name = 'oauth' as const;\n config = {};\n compat = {\n 'magic-sdk': false,\n '@magic-sdk/react-native-bare': '>=13.0.0',\n '@magic-sdk/react-native-expo': false,\n '@magic-sdk/react-native': false,\n };\n\n public loginWithPopup(configuration: OAuthRedirectConfiguration) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n try {\n const startPayload = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.Start, [\n {\n ...configuration,\n apiKey: this.sdk.apiKey,\n platform: 'rn',\n },\n ]);\n\n const result = await this.request<OAuthRedirectStartResult | OAuthRedirectError>(startPayload);\n const successResult = result as OAuthRedirectStartResult;\n const errorResult = result as OAuthRedirectError;\n\n if (errorResult.error) {\n reject(\n this.createError<OAuthErrorData>(errorResult.error, errorResult.error_description ?? 'An error occurred.', {\n errorURI: errorResult.error_uri,\n provider: errorResult.provider,\n }),\n );\n return;\n }\n\n if (!successResult?.oauthAuthoriationURI) {\n reject(this.createError<object>('NO_AUTH_URI', 'No authorization URI was returned', {}));\n return;\n }\n\n const url = successResult.oauthAuthoriationURI;\n const res = await InAppBrowser.openAuth(url, configuration.redirectURI, {});\n\n if (res.type === 'success') {\n const queryString = new URL(res.url).search;\n resolve(getResult.call(this, queryString.toString()));\n } else {\n reject(this.createError<object>(res.type, 'User has cancelled the authentication', {}));\n }\n } catch (err: any) {\n reject(\n this.createError<object>(err.message, 'An error has occurred', {\n err,\n }),\n );\n }\n });\n }\n}\n\nexport function getResult(this: OAuthExtension, queryString: string) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n const parseRedirectResult = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.Verify, [\n {\n authorizationResponseParams: queryString,\n magicApiKey: this.sdk.apiKey,\n platform: 'rn',\n },\n ]);\n\n // Parse the result, which may contain an OAuth-formatted error.\n const resultOrError = await this.request<OAuthRedirectResult | OAuthRedirectError>(parseRedirectResult);\n const maybeResult = resultOrError as OAuthRedirectResult;\n const maybeError = resultOrError as OAuthRedirectError;\n\n if (maybeError.error) {\n reject(\n this.createError<OAuthErrorData>(maybeError.error, maybeError.error_description ?? 'An error occurred.', {\n errorURI: maybeError.error_uri,\n provider: maybeError.provider,\n }),\n );\n }\n\n resolve(maybeResult);\n });\n}\n\nexport * from './types';\n", "import { MagicUserMetadata } from '@magic-sdk/types';\n\nexport enum OAuthPayloadMethods {\n Start = 'magic_oauth_login_with_redirect_start',\n Verify = 'magic_oauth_login_with_redirect_verify',\n Popup = 'magic_oauth_login_with_popup',\n}\n\nexport type OAuthProvider =\n | 'google'\n | 'facebook'\n | 'apple'\n | 'github'\n | 'bitbucket'\n | 'gitlab'\n | 'linkedin'\n | 'twitter'\n | 'discord'\n | 'twitch'\n | 'microsoft';\n\nexport interface OAuthErrorData {\n provider: OAuthProvider;\n errorURI?: string;\n}\n\nexport interface OpenIDConnectProfile {\n name?: string;\n familyName?: string;\n givenName?: string;\n middleName?: string;\n nickname?: string;\n preferredUsername?: string;\n profile?: string;\n picture?: string;\n website?: string;\n gender?: string;\n birthdate?: string;\n zoneinfo?: string;\n locale?: string;\n updatedAt?: number;\n}\n\nexport interface OpenIDConnectEmail {\n email?: string;\n emailVerified?: boolean;\n}\n\nexport interface OpenIDConnectPhone {\n phoneNumber?: string;\n phoneNumberVerified?: boolean;\n}\n\nexport interface OpenIDConnectAddress {\n address?: {\n formatted?: string;\n streetAddress?: string;\n locality?: string;\n region?: string;\n postalCode?: string;\n country?: string;\n };\n}\n\nexport type OpenIDConnectUserInfo = OpenIDConnectProfile &\n OpenIDConnectEmail &\n OpenIDConnectPhone &\n OpenIDConnectAddress & { sub?: string; sources?: Record<string, any> } & Record<string, any>;\n\nexport interface OAuthRedirectResult {\n oauth: {\n provider: OAuthProvider;\n scope: string[];\n accessToken: string;\n userHandle: string;\n userInfo: OpenIDConnectUserInfo;\n };\n\n magic: {\n idToken: string;\n userMetadata: MagicUserMetadata;\n };\n}\n\nexport interface OAuthRedirectError {\n provider: OAuthProvider;\n error: string;\n error_description?: string;\n error_uri?: string;\n}\n\nexport interface OAuthRedirectConfiguration {\n provider: OAuthProvider;\n redirectURI: string;\n scope?: string[];\n loginHint?: string;\n}\n\nexport enum OAuthErrorCode {\n InvalidRequest = 'invalid_request',\n InvalidClient = 'invalid_client',\n InvalidScope = 'invalid_scope',\n InvalidGrant = 'invalid_grant',\n UnauthorizedClient = 'unauthorized_client',\n UnsupportedResponseType = 'unsupported_response_type',\n UnsupportedGrantType = 'unsupported_grant_type',\n UnsupportedTokenType = 'unsupported_token_type',\n AccessDenied = 'access_denied',\n ServerError = 'server_error',\n TemporarilyUnavailable = 'temporarily_unavailable',\n}\n\nexport interface OAuthRedirectStartResult {\n oauthAuthoriationURI?: string;\n useMagicServerCallback?: boolean;\n shouldReturnURI?: boolean;\n}\n"],
5
+ "mappings": "AAAA,OAAS,gBAAAA,MAAoB,mCAC7B,OAAS,aAAAC,MAAiB,+BCCnB,IAAKC,OACVA,EAAA,MAAQ,wCACRA,EAAA,OAAS,yCACTA,EAAA,MAAQ,+BAHEA,OAAA,IAgGAC,OACVA,EAAA,eAAiB,kBACjBA,EAAA,cAAgB,iBAChBA,EAAA,aAAe,gBACfA,EAAA,aAAe,gBACfA,EAAA,mBAAqB,sBACrBA,EAAA,wBAA0B,4BAC1BA,EAAA,qBAAuB,yBACvBA,EAAA,qBAAuB,yBACvBA,EAAA,aAAe,gBACfA,EAAA,YAAc,eACdA,EAAA,uBAAyB,0BAXfA,OAAA,IDvFL,IAAMC,EAAN,cAA6BC,EAAU,QAAkB,CAC9D,KAAO,QACP,OAAS,CAAC,EACV,OAAS,CACP,YAAa,GACb,+BAAgC,WAChC,+BAAgC,GAChC,0BAA2B,EAC7B,EAEO,eAAeC,EAA2C,CAC/D,OAAO,KAAK,MAAM,iBAAsC,MAAOC,EAASC,IAAW,CACjF,GAAI,CACF,IAAMC,EAAe,KAAK,MAAM,oEAAuD,CACrF,CACE,GAAGH,EACH,OAAQ,KAAK,IAAI,OACjB,SAAU,IACZ,CACF,CAAC,EAEKI,EAAS,MAAM,KAAK,QAAuDD,CAAY,EACvFE,EAAgBD,EAChBE,EAAcF,EAEpB,GAAIE,EAAY,MAAO,CACrBJ,EACE,KAAK,YAA4BI,EAAY,MAAOA,EAAY,mBAAqB,qBAAsB,CACzG,SAAUA,EAAY,UACtB,SAAUA,EAAY,QACxB,CAAC,CACH,EACA,MACF,CAEA,GAAI,CAACD,GAAe,qBAAsB,CACxCH,EAAO,KAAK,YAAoB,cAAe,oCAAqC,CAAC,CAAC,CAAC,EACvF,MACF,CAEA,IAAMK,EAAMF,EAAc,qBACpBG,EAAM,MAAMC,EAAa,SAASF,EAAKP,EAAc,YAAa,CAAC,CAAC,EAE1E,GAAIQ,EAAI,OAAS,UAAW,CAC1B,IAAME,EAAc,IAAI,IAAIF,EAAI,GAAG,EAAE,OACrCP,EAAQU,EAAU,KAAK,KAAMD,EAAY,SAAS,CAAC,CAAC,CACtD,MACER,EAAO,KAAK,YAAoBM,EAAI,KAAM,wCAAyC,CAAC,CAAC,CAAC,CAE1F,OAASI,EAAU,CACjBV,EACE,KAAK,YAAoBU,EAAI,QAAS,wBAAyB,CAC7D,IAAAA,CACF,CAAC,CACH,CACF,CACF,CAAC,CACH,CACF,EAEO,SAASD,EAAgCD,EAAqB,CACnE,OAAO,KAAK,MAAM,iBAAsC,MAAOT,EAASC,IAAW,CACjF,IAAMW,EAAsB,KAAK,MAAM,qEAAwD,CAC7F,CACE,4BAA6BH,EAC7B,YAAa,KAAK,IAAI,OACtB,SAAU,IACZ,CACF,CAAC,EAGKI,EAAgB,MAAM,KAAK,QAAkDD,CAAmB,EAChGE,EAAcD,EACdE,EAAaF,EAEfE,EAAW,OACbd,EACE,KAAK,YAA4Bc,EAAW,MAAOA,EAAW,mBAAqB,qBAAsB,CACvG,SAAUA,EAAW,UACrB,SAAUA,EAAW,QACvB,CAAC,CACH,EAGFf,EAAQc,CAAW,CACrB,CAAC,CACH",
6
+ "names": ["InAppBrowser", "Extension", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "Extension", "configuration", "resolve", "reject", "startPayload", "result", "successResult", "errorResult", "url", "res", "InAppBrowser", "queryString", "getResult", "err", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
7
7
  }
package/dist/es/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{InAppBrowser as C}from"react-native-inappbrowser-reborn";import{Extension as w}from"@magic-sdk/react-native-bare";import{getBundleId as x}from"react-native-device-info";import A from"crypto-js/sha256";import b from"crypto-js/enc-base64";var g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",h=typeof window<"u"&&!!window.crypto,v=h&&!!window.crypto.subtle;function _(t){return Array.from(t).map(e=>g[e%g.length]).join("")}function m(t){let e=r=>r.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"");if(t instanceof ArrayBuffer){let r=new Uint8Array(t),o=Array.from(r).map(c=>String.fromCharCode(c)).join(""),i=btoa(o);return e(i)}return e(b.stringify(t))}async function U(t){if(v){let e=new TextEncoder().encode(t);return crypto.subtle.digest("SHA-256",e).then(m)}return m(A(t))}function f(t){let e=new Uint8Array(t);if(h)window.crypto.getRandomValues(e);else for(let r=0;r<t;r+=1)e[r]=Math.floor(Math.random()*Math.floor(255));return _(e)}async function y(){let t=f(128),e=f(128),r=await U(e);return{verifier:e,challenge:r,state:t}}var R=(e=>(e.ParseRedirectResult="magic_oauth_parse_redirect_result",e))(R||{}),O=(n=>(n.InvalidRequest="invalid_request",n.InvalidClient="invalid_client",n.InvalidScope="invalid_scope",n.InvalidGrant="invalid_grant",n.UnauthorizedClient="unauthorized_client",n.UnsupportedResponseType="unsupported_response_type",n.UnsupportedGrantType="unsupported_grant_type",n.UnsupportedTokenType="unsupported_token_type",n.AccessDenied="access_denied",n.ServerError="server_error",n.TemporarilyUnavailable="temporarily_unavailable",n))(O||{});var I=class extends w.Internal{name="oauth";config={};compat={"magic-sdk":!1,"@magic-sdk/react-native-bare":">=13.0.0","@magic-sdk/react-native-expo":!1,"@magic-sdk/react-native":!1};loginWithPopup(e){return this.utils.createPromiEvent(async(r,o)=>{try{let{provider:i,query:c,redirectURI:u}=await k.call(this,e),p=`https://auth.magic.link/v1/oauth2/${i}/start?${c}`,a=await C.openAuth(p,u,{});if(a.type==="success"){let s=new URL(a.url).search;r(D.call(this,s.toString()))}else o(this.createError(a.type,"User has cancelled the authentication",{}))}catch(i){o(this.createError(i.message,"An error has occurred",{err:i}))}})}},d="oauth_redirect_metadata";async function k(t){await this.utils.storage.removeItem(d);let{provider:e,redirectURI:r,scope:o,loginHint:i}=t,{verifier:c,challenge:u,state:p}=await y(),a=x(),s=JSON.stringify({verifier:c,state:p});return await this.utils.storage.setItem(d,s),{query:[`magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,`magic_challenge=${encodeURIComponent(u)}`,`state=${encodeURIComponent(p)}`,`platform=${encodeURIComponent("rn")}`,o&&`scope=${encodeURIComponent(o.join(" "))}`,r&&`redirect_uri=${encodeURIComponent(r)}`,i&&`login_hint=${encodeURIComponent(i)}`,a&&`bundleId=${encodeURIComponent(a)}`].reduce((n,l)=>l?`${n}&${l}`:n),provider:e,redirectURI:r}}function D(t){return this.utils.createPromiEvent(async(e,r)=>{let o=await this.utils.storage.getItem(d),{verifier:i,state:c}=JSON.parse(o);this.utils.storage.removeItem(d);let u=this.utils.createJsonRpcRequestPayload("magic_oauth_parse_redirect_result",[t,i,c]),p=await this.request(u),a=p,s=p;s.error&&r(this.createError(s.error,s.error_description??"An error occurred.",{errorURI:s.error_uri,provider:s.provider})),e(a)})}export{O as OAuthErrorCode,I as OAuthExtension,R as OAuthPayloadMethods,k as createURI,D as getResult};
1
+ import{InAppBrowser as R}from"react-native-inappbrowser-reborn";import{Extension as m}from"@magic-sdk/react-native-bare";var p=(r=>(r.Start="magic_oauth_login_with_redirect_start",r.Verify="magic_oauth_login_with_redirect_verify",r.Popup="magic_oauth_login_with_popup",r))(p||{}),h=(e=>(e.InvalidRequest="invalid_request",e.InvalidClient="invalid_client",e.InvalidScope="invalid_scope",e.InvalidGrant="invalid_grant",e.UnauthorizedClient="unauthorized_client",e.UnsupportedResponseType="unsupported_response_type",e.UnsupportedGrantType="unsupported_grant_type",e.UnsupportedTokenType="unsupported_token_type",e.AccessDenied="access_denied",e.ServerError="server_error",e.TemporarilyUnavailable="temporarily_unavailable",e))(h||{});var d=class extends m.Internal{name="oauth";config={};compat={"magic-sdk":!1,"@magic-sdk/react-native-bare":">=13.0.0","@magic-sdk/react-native-expo":!1,"@magic-sdk/react-native":!1};loginWithPopup(o){return this.utils.createPromiEvent(async(a,r)=>{try{let i=this.utils.createJsonRpcRequestPayload("magic_oauth_login_with_redirect_start",[{...o,apiKey:this.sdk.apiKey,platform:"rn"}]),s=await this.request(i),t=s,n=s;if(n.error){r(this.createError(n.error,n.error_description??"An error occurred.",{errorURI:n.error_uri,provider:n.provider}));return}if(!t?.oauthAuthoriationURI){r(this.createError("NO_AUTH_URI","No authorization URI was returned",{}));return}let l=t.oauthAuthoriationURI,c=await R.openAuth(l,o.redirectURI,{});if(c.type==="success"){let g=new URL(c.url).search;a(f.call(this,g.toString()))}else r(this.createError(c.type,"User has cancelled the authentication",{}))}catch(i){r(this.createError(i.message,"An error has occurred",{err:i}))}})}};function f(u){return this.utils.createPromiEvent(async(o,a)=>{let r=this.utils.createJsonRpcRequestPayload("magic_oauth_login_with_redirect_verify",[{authorizationResponseParams:u,magicApiKey:this.sdk.apiKey,platform:"rn"}]),i=await this.request(r),s=i,t=i;t.error&&a(this.createError(t.error,t.error_description??"An error occurred.",{errorURI:t.error_uri,provider:t.provider})),o(s)})}export{h as OAuthErrorCode,d as OAuthExtension,p as OAuthPayloadMethods,f as getResult};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/index.ts", "../../src/crypto.ts", "../../src/types.ts"],
4
- "sourcesContent": ["import { InAppBrowser } from 'react-native-inappbrowser-reborn';\nimport { Extension } from '@magic-sdk/react-native-bare';\nimport { getBundleId } from 'react-native-device-info';\nimport { createCryptoChallenge } from './crypto';\nimport {\n OAuthErrorData,\n OAuthPayloadMethods,\n OAuthRedirectConfiguration,\n OAuthRedirectError,\n OAuthRedirectResult,\n} from './types';\n\nexport class OAuthExtension extends Extension.Internal<'oauth'> {\n name = 'oauth' as const;\n config = {};\n compat = {\n 'magic-sdk': false,\n '@magic-sdk/react-native-bare': '>=13.0.0',\n '@magic-sdk/react-native-expo': false,\n '@magic-sdk/react-native': false,\n };\n\n public loginWithPopup(configuration: OAuthRedirectConfiguration) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n try {\n const { provider, query, redirectURI } = await createURI.call(this, configuration);\n const url = `https://auth.magic.link/v1/oauth2/${provider}/start?${query}`;\n\n /**\n * Response Type Inspired by:\n * https://docs.expo.io/versions/latest/sdk/webbrowser/#returns\n */\n const res = await InAppBrowser.openAuth(url, redirectURI, {});\n\n if (res.type === 'success') {\n const queryString = new URL(res.url).search;\n\n resolve(getResult.call(this, queryString.toString()));\n } else {\n reject(this.createError<object>(res.type, 'User has cancelled the authentication', {}));\n }\n } catch (err: any) {\n reject(\n this.createError<object>(err.message, 'An error has occurred', {\n err,\n }),\n );\n }\n });\n }\n}\n\nconst OAUTH_REDIRECT_METADATA_KEY = 'oauth_redirect_metadata';\n\nexport async function createURI(this: OAuthExtension, configuration: OAuthRedirectConfiguration) {\n // Bust any old, in-progress OAuth flows.\n await this.utils.storage.removeItem(OAUTH_REDIRECT_METADATA_KEY);\n\n // Unpack configuration, generate crypto values, and persist to storage.\n const { provider, redirectURI, scope, loginHint } = configuration;\n const { verifier, challenge, state } = await createCryptoChallenge();\n const bundleId = getBundleId();\n\n /* Stringify for RN Async storage */\n const storedData = JSON.stringify({\n verifier,\n state,\n });\n\n await this.utils.storage.setItem(OAUTH_REDIRECT_METADATA_KEY, storedData);\n\n // Formulate the initial redirect query to Magic's OAuth hub.\n // Required fields:\n // - `magic_api_key`\n // - `magic_challenge`\n // - `state`\n // - `redirect_uri`\n // - `platform`\n // Optional fields:\n // - `bundleId`\n\n const query = [\n `magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,\n `magic_challenge=${encodeURIComponent(challenge)}`,\n `state=${encodeURIComponent(state)}`,\n `platform=${encodeURIComponent('rn')}`,\n scope && `scope=${encodeURIComponent(scope.join(' '))}`,\n redirectURI && `redirect_uri=${encodeURIComponent(redirectURI)}`,\n loginHint && `login_hint=${encodeURIComponent(loginHint)}`,\n bundleId && `bundleId=${encodeURIComponent(bundleId)}`,\n ].reduce((prev, next) => (next ? `${prev}&${next}` : prev));\n\n return {\n query,\n provider,\n redirectURI,\n };\n}\n\nexport function getResult(this: OAuthExtension, queryString: string) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n const json: string = (await this.utils.storage.getItem(OAUTH_REDIRECT_METADATA_KEY)) as string;\n\n const { verifier, state } = JSON.parse(json);\n\n // Remove the save OAuth state from storage, it stays in memory now...\n this.utils.storage.removeItem(OAUTH_REDIRECT_METADATA_KEY);\n\n const parseRedirectResult = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.ParseRedirectResult, [\n queryString,\n verifier,\n state,\n ]);\n\n // Parse the result, which may contain an OAuth-formatted error.\n const resultOrError = await this.request<OAuthRedirectResult | OAuthRedirectError>(parseRedirectResult);\n const maybeResult = resultOrError as OAuthRedirectResult;\n const maybeError = resultOrError as OAuthRedirectError;\n\n if (maybeError.error) {\n reject(\n this.createError<OAuthErrorData>(maybeError.error, maybeError.error_description ?? 'An error occurred.', {\n errorURI: maybeError.error_uri,\n provider: maybeError.provider,\n }),\n );\n }\n\n resolve(maybeResult);\n });\n}\n\nexport * from './types';\n", "import Crypto from 'crypto-js';\nimport sha256Fallback from 'crypto-js/sha256';\nimport Base64 from 'crypto-js/enc-base64';\n\nconst CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';\nconst HAS_CRYPTO = typeof window !== 'undefined' && !!(window.crypto as any);\nconst HAS_SUBTLE_CRYPTO = HAS_CRYPTO && !!(window.crypto.subtle as any);\n\n/**\n * Stringifies `bytes` using the OAuth 2.0 `code_verifier` character set.\n */\nfunction bytesToVerifierString(bytes: Uint8Array) {\n return Array.from(bytes)\n .map((value: number) => CHARSET[value % CHARSET.length])\n .join('');\n}\n\n/**\n * Stringifies argument (as CryptoJS `WordArray` or EcmaScript `ArrayBuffer`)\n * and encodes to URL-safe Base64.\n */\nfunction base64URLEncodeFromByteArray(arg: Crypto.lib.WordArray | ArrayBuffer): string {\n const makeURLSafe = (base64: string) => {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n };\n\n if (arg instanceof ArrayBuffer) {\n const bytes = new Uint8Array(arg);\n const utf8Binary = Array.from(bytes)\n .map(value => String.fromCharCode(value))\n .join('');\n\n const base64 = btoa(utf8Binary);\n return makeURLSafe(base64);\n }\n\n return makeURLSafe(Base64.stringify(arg));\n}\n\n/**\n * Produces a SHA-256 hash of the given `message`. This function first attempts\n * to use the browser's built-in `SubtleCrypto` API, falling back to\n * CryptoJS if required.\n */\nasync function sha256(message: string) {\n if (HAS_SUBTLE_CRYPTO) {\n const bytes = new TextEncoder().encode(message);\n return crypto.subtle.digest('SHA-256', bytes).then(base64URLEncodeFromByteArray);\n }\n\n return base64URLEncodeFromByteArray(sha256Fallback(message));\n}\n\n/**\n * Creates a cryptographically random string using the browser's built-in\n * `Crypto` API, falling back to `Math.random` if required.\n */\nfunction createRandomString(size: number) {\n const bytes = new Uint8Array(size);\n\n if (HAS_CRYPTO) {\n window.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < size; i += 1) bytes[i] = Math.floor(Math.random() * Math.floor(255));\n }\n\n return bytesToVerifierString(bytes);\n}\n\n/**\n * Creates OAuth 2.0-compatible `code_verifier`, `code_challenge`, and `state`\n * parameters.\n */\nexport async function createCryptoChallenge() {\n const state = createRandomString(128);\n const verifier = createRandomString(128);\n const challenge = await sha256(verifier);\n return { verifier, challenge, state };\n}\n", "import { MagicUserMetadata } from '@magic-sdk/types';\n\nexport enum OAuthPayloadMethods {\n ParseRedirectResult = 'magic_oauth_parse_redirect_result',\n}\n\nexport type OAuthProvider =\n | 'google'\n | 'facebook'\n | 'apple'\n | 'github'\n | 'bitbucket'\n | 'gitlab'\n | 'linkedin'\n | 'twitter'\n | 'discord'\n | 'twitch'\n | 'microsoft';\n\nexport interface OAuthErrorData {\n provider: OAuthProvider;\n errorURI?: string;\n}\n\nexport interface OpenIDConnectProfile {\n name?: string;\n familyName?: string;\n givenName?: string;\n middleName?: string;\n nickname?: string;\n preferredUsername?: string;\n profile?: string;\n picture?: string;\n website?: string;\n gender?: string;\n birthdate?: string;\n zoneinfo?: string;\n locale?: string;\n updatedAt?: number;\n}\n\nexport interface OpenIDConnectEmail {\n email?: string;\n emailVerified?: boolean;\n}\n\nexport interface OpenIDConnectPhone {\n phoneNumber?: string;\n phoneNumberVerified?: boolean;\n}\n\nexport interface OpenIDConnectAddress {\n address?: {\n formatted?: string;\n streetAddress?: string;\n locality?: string;\n region?: string;\n postalCode?: string;\n country?: string;\n };\n}\n\nexport type OpenIDConnectUserInfo = OpenIDConnectProfile &\n OpenIDConnectEmail &\n OpenIDConnectPhone &\n OpenIDConnectAddress & { sub?: string; sources?: Record<string, any> } & Record<string, any>;\n\nexport interface OAuthRedirectResult {\n oauth: {\n provider: OAuthProvider;\n scope: string[];\n accessToken: string;\n userHandle: string;\n userInfo: OpenIDConnectUserInfo;\n };\n\n magic: {\n idToken: string;\n userMetadata: MagicUserMetadata;\n };\n}\n\nexport interface OAuthRedirectError {\n provider: OAuthProvider;\n error: string;\n error_description?: string;\n error_uri?: string;\n}\n\nexport interface OAuthRedirectConfiguration {\n provider: OAuthProvider;\n redirectURI: string;\n scope?: string[];\n loginHint?: string;\n}\n\nexport enum OAuthErrorCode {\n InvalidRequest = 'invalid_request',\n InvalidClient = 'invalid_client',\n InvalidScope = 'invalid_scope',\n InvalidGrant = 'invalid_grant',\n UnauthorizedClient = 'unauthorized_client',\n UnsupportedResponseType = 'unsupported_response_type',\n UnsupportedGrantType = 'unsupported_grant_type',\n UnsupportedTokenType = 'unsupported_token_type',\n AccessDenied = 'access_denied',\n ServerError = 'server_error',\n TemporarilyUnavailable = 'temporarily_unavailable',\n}\n"],
5
- "mappings": "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",
6
- "names": ["InAppBrowser", "Extension", "getBundleId", "sha256Fallback", "Base64", "CHARSET", "HAS_CRYPTO", "HAS_SUBTLE_CRYPTO", "bytesToVerifierString", "bytes", "value", "base64URLEncodeFromByteArray", "arg", "makeURLSafe", "base64", "utf8Binary", "sha256", "message", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "Extension", "configuration", "resolve", "reject", "provider", "query", "redirectURI", "createURI", "url", "res", "InAppBrowser", "queryString", "getResult", "err", "OAUTH_REDIRECT_METADATA_KEY", "scope", "loginHint", "verifier", "challenge", "state", "createCryptoChallenge", "bundleId", "getBundleId", "storedData", "prev", "next", "json", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
3
+ "sources": ["../../src/index.ts", "../../src/types.ts"],
4
+ "sourcesContent": ["import { InAppBrowser } from 'react-native-inappbrowser-reborn';\nimport { Extension } from '@magic-sdk/react-native-bare';\nimport {\n OAuthErrorData,\n OAuthPayloadMethods,\n OAuthRedirectConfiguration,\n OAuthRedirectError,\n OAuthRedirectResult,\n OAuthRedirectStartResult,\n} from './types';\n\nexport class OAuthExtension extends Extension.Internal<'oauth'> {\n name = 'oauth' as const;\n config = {};\n compat = {\n 'magic-sdk': false,\n '@magic-sdk/react-native-bare': '>=13.0.0',\n '@magic-sdk/react-native-expo': false,\n '@magic-sdk/react-native': false,\n };\n\n public loginWithPopup(configuration: OAuthRedirectConfiguration) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n try {\n const startPayload = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.Start, [\n {\n ...configuration,\n apiKey: this.sdk.apiKey,\n platform: 'rn',\n },\n ]);\n\n const result = await this.request<OAuthRedirectStartResult | OAuthRedirectError>(startPayload);\n const successResult = result as OAuthRedirectStartResult;\n const errorResult = result as OAuthRedirectError;\n\n if (errorResult.error) {\n reject(\n this.createError<OAuthErrorData>(errorResult.error, errorResult.error_description ?? 'An error occurred.', {\n errorURI: errorResult.error_uri,\n provider: errorResult.provider,\n }),\n );\n return;\n }\n\n if (!successResult?.oauthAuthoriationURI) {\n reject(this.createError<object>('NO_AUTH_URI', 'No authorization URI was returned', {}));\n return;\n }\n\n const url = successResult.oauthAuthoriationURI;\n const res = await InAppBrowser.openAuth(url, configuration.redirectURI, {});\n\n if (res.type === 'success') {\n const queryString = new URL(res.url).search;\n resolve(getResult.call(this, queryString.toString()));\n } else {\n reject(this.createError<object>(res.type, 'User has cancelled the authentication', {}));\n }\n } catch (err: any) {\n reject(\n this.createError<object>(err.message, 'An error has occurred', {\n err,\n }),\n );\n }\n });\n }\n}\n\nexport function getResult(this: OAuthExtension, queryString: string) {\n return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n const parseRedirectResult = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.Verify, [\n {\n authorizationResponseParams: queryString,\n magicApiKey: this.sdk.apiKey,\n platform: 'rn',\n },\n ]);\n\n // Parse the result, which may contain an OAuth-formatted error.\n const resultOrError = await this.request<OAuthRedirectResult | OAuthRedirectError>(parseRedirectResult);\n const maybeResult = resultOrError as OAuthRedirectResult;\n const maybeError = resultOrError as OAuthRedirectError;\n\n if (maybeError.error) {\n reject(\n this.createError<OAuthErrorData>(maybeError.error, maybeError.error_description ?? 'An error occurred.', {\n errorURI: maybeError.error_uri,\n provider: maybeError.provider,\n }),\n );\n }\n\n resolve(maybeResult);\n });\n}\n\nexport * from './types';\n", "import { MagicUserMetadata } from '@magic-sdk/types';\n\nexport enum OAuthPayloadMethods {\n Start = 'magic_oauth_login_with_redirect_start',\n Verify = 'magic_oauth_login_with_redirect_verify',\n Popup = 'magic_oauth_login_with_popup',\n}\n\nexport type OAuthProvider =\n | 'google'\n | 'facebook'\n | 'apple'\n | 'github'\n | 'bitbucket'\n | 'gitlab'\n | 'linkedin'\n | 'twitter'\n | 'discord'\n | 'twitch'\n | 'microsoft';\n\nexport interface OAuthErrorData {\n provider: OAuthProvider;\n errorURI?: string;\n}\n\nexport interface OpenIDConnectProfile {\n name?: string;\n familyName?: string;\n givenName?: string;\n middleName?: string;\n nickname?: string;\n preferredUsername?: string;\n profile?: string;\n picture?: string;\n website?: string;\n gender?: string;\n birthdate?: string;\n zoneinfo?: string;\n locale?: string;\n updatedAt?: number;\n}\n\nexport interface OpenIDConnectEmail {\n email?: string;\n emailVerified?: boolean;\n}\n\nexport interface OpenIDConnectPhone {\n phoneNumber?: string;\n phoneNumberVerified?: boolean;\n}\n\nexport interface OpenIDConnectAddress {\n address?: {\n formatted?: string;\n streetAddress?: string;\n locality?: string;\n region?: string;\n postalCode?: string;\n country?: string;\n };\n}\n\nexport type OpenIDConnectUserInfo = OpenIDConnectProfile &\n OpenIDConnectEmail &\n OpenIDConnectPhone &\n OpenIDConnectAddress & { sub?: string; sources?: Record<string, any> } & Record<string, any>;\n\nexport interface OAuthRedirectResult {\n oauth: {\n provider: OAuthProvider;\n scope: string[];\n accessToken: string;\n userHandle: string;\n userInfo: OpenIDConnectUserInfo;\n };\n\n magic: {\n idToken: string;\n userMetadata: MagicUserMetadata;\n };\n}\n\nexport interface OAuthRedirectError {\n provider: OAuthProvider;\n error: string;\n error_description?: string;\n error_uri?: string;\n}\n\nexport interface OAuthRedirectConfiguration {\n provider: OAuthProvider;\n redirectURI: string;\n scope?: string[];\n loginHint?: string;\n}\n\nexport enum OAuthErrorCode {\n InvalidRequest = 'invalid_request',\n InvalidClient = 'invalid_client',\n InvalidScope = 'invalid_scope',\n InvalidGrant = 'invalid_grant',\n UnauthorizedClient = 'unauthorized_client',\n UnsupportedResponseType = 'unsupported_response_type',\n UnsupportedGrantType = 'unsupported_grant_type',\n UnsupportedTokenType = 'unsupported_token_type',\n AccessDenied = 'access_denied',\n ServerError = 'server_error',\n TemporarilyUnavailable = 'temporarily_unavailable',\n}\n\nexport interface OAuthRedirectStartResult {\n oauthAuthoriationURI?: string;\n useMagicServerCallback?: boolean;\n shouldReturnURI?: boolean;\n}\n"],
5
+ "mappings": "AAAA,OAAS,gBAAAA,MAAoB,mCAC7B,OAAS,aAAAC,MAAiB,+BCCnB,IAAKC,OACVA,EAAA,MAAQ,wCACRA,EAAA,OAAS,yCACTA,EAAA,MAAQ,+BAHEA,OAAA,IAgGAC,OACVA,EAAA,eAAiB,kBACjBA,EAAA,cAAgB,iBAChBA,EAAA,aAAe,gBACfA,EAAA,aAAe,gBACfA,EAAA,mBAAqB,sBACrBA,EAAA,wBAA0B,4BAC1BA,EAAA,qBAAuB,yBACvBA,EAAA,qBAAuB,yBACvBA,EAAA,aAAe,gBACfA,EAAA,YAAc,eACdA,EAAA,uBAAyB,0BAXfA,OAAA,IDvFL,IAAMC,EAAN,cAA6BC,EAAU,QAAkB,CAC9D,KAAO,QACP,OAAS,CAAC,EACV,OAAS,CACP,YAAa,GACb,+BAAgC,WAChC,+BAAgC,GAChC,0BAA2B,EAC7B,EAEO,eAAeC,EAA2C,CAC/D,OAAO,KAAK,MAAM,iBAAsC,MAAOC,EAASC,IAAW,CACjF,GAAI,CACF,IAAMC,EAAe,KAAK,MAAM,oEAAuD,CACrF,CACE,GAAGH,EACH,OAAQ,KAAK,IAAI,OACjB,SAAU,IACZ,CACF,CAAC,EAEKI,EAAS,MAAM,KAAK,QAAuDD,CAAY,EACvFE,EAAgBD,EAChBE,EAAcF,EAEpB,GAAIE,EAAY,MAAO,CACrBJ,EACE,KAAK,YAA4BI,EAAY,MAAOA,EAAY,mBAAqB,qBAAsB,CACzG,SAAUA,EAAY,UACtB,SAAUA,EAAY,QACxB,CAAC,CACH,EACA,MACF,CAEA,GAAI,CAACD,GAAe,qBAAsB,CACxCH,EAAO,KAAK,YAAoB,cAAe,oCAAqC,CAAC,CAAC,CAAC,EACvF,MACF,CAEA,IAAMK,EAAMF,EAAc,qBACpBG,EAAM,MAAMC,EAAa,SAASF,EAAKP,EAAc,YAAa,CAAC,CAAC,EAE1E,GAAIQ,EAAI,OAAS,UAAW,CAC1B,IAAME,EAAc,IAAI,IAAIF,EAAI,GAAG,EAAE,OACrCP,EAAQU,EAAU,KAAK,KAAMD,EAAY,SAAS,CAAC,CAAC,CACtD,MACER,EAAO,KAAK,YAAoBM,EAAI,KAAM,wCAAyC,CAAC,CAAC,CAAC,CAE1F,OAASI,EAAU,CACjBV,EACE,KAAK,YAAoBU,EAAI,QAAS,wBAAyB,CAC7D,IAAAA,CACF,CAAC,CACH,CACF,CACF,CAAC,CACH,CACF,EAEO,SAASD,EAAgCD,EAAqB,CACnE,OAAO,KAAK,MAAM,iBAAsC,MAAOT,EAASC,IAAW,CACjF,IAAMW,EAAsB,KAAK,MAAM,qEAAwD,CAC7F,CACE,4BAA6BH,EAC7B,YAAa,KAAK,IAAI,OACtB,SAAU,IACZ,CACF,CAAC,EAGKI,EAAgB,MAAM,KAAK,QAAkDD,CAAmB,EAChGE,EAAcD,EACdE,EAAaF,EAEfE,EAAW,OACbd,EACE,KAAK,YAA4Bc,EAAW,MAAOA,EAAW,mBAAqB,qBAAsB,CACvG,SAAUA,EAAW,UACrB,SAAUA,EAAW,QACvB,CAAC,CACH,EAGFf,EAAQc,CAAW,CACrB,CAAC,CACH",
6
+ "names": ["InAppBrowser", "Extension", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "Extension", "configuration", "resolve", "reject", "startPayload", "result", "successResult", "errorResult", "url", "res", "InAppBrowser", "queryString", "getResult", "err", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
7
7
  }
@@ -16,11 +16,6 @@ export declare class OAuthExtension extends Extension.Internal<'oauth'> {
16
16
  "closed-by-user": () => void;
17
17
  }>;
18
18
  }
19
- export declare function createURI(this: OAuthExtension, configuration: OAuthRedirectConfiguration): Promise<{
20
- query: string | undefined;
21
- provider: import("./types").OAuthProvider;
22
- redirectURI: string;
23
- }>;
24
19
  export declare function getResult(this: OAuthExtension, queryString: string): import("@magic-sdk/react-native-bare").PromiEvent<OAuthRedirectResult, {
25
20
  done: (result: OAuthRedirectResult) => void;
26
21
  error: (reason: any) => void;
@@ -1,6 +1,8 @@
1
1
  import { MagicUserMetadata } from '@magic-sdk/types';
2
2
  export declare enum OAuthPayloadMethods {
3
- ParseRedirectResult = "magic_oauth_parse_redirect_result"
3
+ Start = "magic_oauth_login_with_redirect_start",
4
+ Verify = "magic_oauth_login_with_redirect_verify",
5
+ Popup = "magic_oauth_login_with_popup"
4
6
  }
5
7
  export type OAuthProvider = 'google' | 'facebook' | 'apple' | 'github' | 'bitbucket' | 'gitlab' | 'linkedin' | 'twitter' | 'discord' | 'twitch' | 'microsoft';
6
8
  export interface OAuthErrorData {
@@ -83,3 +85,8 @@ export declare enum OAuthErrorCode {
83
85
  ServerError = "server_error",
84
86
  TemporarilyUnavailable = "temporarily_unavailable"
85
87
  }
88
+ export interface OAuthRedirectStartResult {
89
+ oauthAuthoriationURI?: string;
90
+ useMagicServerCallback?: boolean;
91
+ shouldReturnURI?: boolean;
92
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magic-ext/react-native-bare-oauth",
3
- "version": "27.0.0-canary.915.17279247601.0",
3
+ "version": "27.0.0",
4
4
  "description": "Magic SDK OAuth Extension for Bare React Native environments.",
5
5
  "author": "Magic <team@magic.link> (https://magic.link/)",
6
6
  "license": "MIT",
@@ -26,18 +26,15 @@
26
26
  ]
27
27
  },
28
28
  "dependencies": {
29
- "crypto-js": "^4.2.0",
30
- "react-native-device-info": "^10.3.0"
29
+ "react-native-inappbrowser-reborn": "^3.7.0"
31
30
  },
32
31
  "devDependencies": {
33
- "@magic-sdk/react-native-bare": "^30.4.2",
34
- "@magic-sdk/types": "25.0.0-canary.915.17279247601.0",
35
- "@types/crypto-js": "~4.2.0",
36
- "react-native-inappbrowser-reborn": "^3.7.0"
32
+ "@magic-sdk/react-native-bare": "^31.0.0",
33
+ "@magic-sdk/types": "^25.0.0"
37
34
  },
38
35
  "peerDependencies": {
39
36
  "@magic-sdk/react-native-bare": ">=13.0.0",
40
37
  "react-native-inappbrowser-reborn": ">=3.7.0"
41
38
  },
42
- "gitHead": "30cbcd86d0112dbaaf6f6b3af6460ee0aba98b1d"
39
+ "gitHead": "be1e437bcade3e4c5f5186509b7faab7c33d03a0"
43
40
  }
@@ -1,9 +0,0 @@
1
- /**
2
- * Creates OAuth 2.0-compatible `code_verifier`, `code_challenge`, and `state`
3
- * parameters.
4
- */
5
- export declare function createCryptoChallenge(): Promise<{
6
- verifier: string;
7
- challenge: string;
8
- state: string;
9
- }>;