@magic-ext/react-native-bare-oauth 25.2.1 → 25.3.0-canary.64c67a3.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 +1 -1
- package/dist/cjs/index.js.map +3 -3
- package/dist/es/index.js +1 -1
- package/dist/es/index.js.map +3 -3
- package/dist/es/index.mjs +1 -1
- package/dist/es/index.mjs.map +3 -3
- package/dist/types/types.d.ts +0 -1
- package/package.json +4 -4
package/dist/cjs/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var T=Object.create;var g=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var q=(e,r)=>{for(var t in r)g(e,t,{get:r[t],enumerable:!0})},R=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of B(r))!M.call(e,n)&&n!==t&&g(e,n,{get:()=>r[n],enumerable:!(s=S(r,n))||s.enumerable});return e};var A=(e,r,t)=>(t=e!=null?T($(e)):{},R(r||!e||!e.__esModule?g(t,"default",{value:e,enumerable:!0}):t,e)),H=e=>R(g({},"__esModule",{value:!0}),e);var p=(e,r,t)=>new Promise((s,n)=>{var c=o=>{try{u(t.next(o))}catch(i){n(i)}},d=o=>{try{u(t.throw(o))}catch(i){n(i)}},u=o=>o.done?s(o.value):Promise.resolve(o.value).then(c,d);u((t=t.apply(e,r)).next())});var F={};q(F,{OAuthErrorCode:()=>C,OAuthExtension:()=>y,OAuthPayloadMethods:()=>f,createURI:()=>D,getResult:()=>P});module.exports=H(F);var x=require("react-native-inappbrowser-reborn"),E=require("@magic-sdk/react-native-bare"),k=require("react-native-device-info");var _=A(require("crypto-js/sha256")),U=A(require("crypto-js/enc-base64"));var I="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",O=typeof window!="undefined"&&!!window.crypto,N=O&&!!window.crypto.subtle;function L(e){return Array.from(e).map(r=>I[r%I.length]).join("")}function b(e){let r=t=>t.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"");if(e instanceof ArrayBuffer){let t=new Uint8Array(e),s=Array.from(t).map(c=>String.fromCharCode(c)).join(""),n=btoa(s);return r(n)}return r(U.default.stringify(e))}function j(e){return p(this,null,function*(){if(N){let r=new TextEncoder().encode(e);return crypto.subtle.digest("SHA-256",r).then(b)}return b((0,_.default)(e))})}function v(e){let r=new Uint8Array(e);if(O)window.crypto.getRandomValues(r);else for(let t=0;t<e;t+=1)r[t]=Math.floor(Math.random()*Math.floor(255));return L(r)}function w(){return p(this,null,function*(){let e=v(128),r=v(128),t=yield j(r);return{verifier:r,challenge:t,state:e}})}var f=(r=>(r.ParseRedirectResult="magic_oauth_parse_redirect_result",r))(f||{}),C=(a=>(a.InvalidRequest="invalid_request",a.InvalidClient="invalid_client",a.InvalidScope="invalid_scope",a.InvalidGrant="invalid_grant",a.UnauthorizedClient="unauthorized_client",a.UnsupportedResponseType="unsupported_response_type",a.UnsupportedGrantType="unsupported_grant_type",a.UnsupportedTokenType="unsupported_token_type",a.AccessDenied="access_denied",a.ServerError="server_error",a.TemporarilyUnavailable="temporarily_unavailable",a))(C||{});var y=class extends E.Extension.Internal{constructor(){super(...arguments);this.name="oauth";this.config={};this.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((s,n)=>p(this,null,function*(){try{let{provider:c,query:d,redirectURI:u}=yield D.call(this,t),o=`https://auth.magic.link/v1/oauth2/${c}/start?${d}`,i=yield x.InAppBrowser.openAuth(o,u,{});if(i.type==="success"){let l=new URL(i.url).search;s(P.call(this,l.toString()))}else n(this.createError(i.type,"User has cancelled the authentication",{}))}catch(c){n(this.createError(c.message,"An error has occurred",{err:c}))}}))}},m="oauth_redirect_metadata";function D(e){return p(this,null,function*(){yield this.utils.storage.removeItem(m);let{provider:r,redirectURI:t,scope:s,loginHint:n}=e,{verifier:c,challenge:d,state:u}=yield w(),o=(0,k.getBundleId)(),i=JSON.stringify({verifier:c,state:u});return yield this.utils.storage.setItem(m,i),{query:[`magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,`magic_challenge=${encodeURIComponent(d)}`,`state=${encodeURIComponent(u)}`,`platform=${encodeURIComponent("rn")}`,s&&`scope=${encodeURIComponent(s.join(" "))}`,t&&`redirect_uri=${encodeURIComponent(t)}`,n&&`login_hint=${encodeURIComponent(n)}`,o&&`bundleId=${encodeURIComponent(o)}`].reduce((a,h)=>h?`${a}&${h}`:a),provider:r,redirectURI:t}})}function P(e){return this.utils.createPromiEvent((r,t)=>p(this,null,function*(){var l;let s=yield this.utils.storage.getItem(m),{verifier:n,state:c}=JSON.parse(s);this.utils.storage.removeItem(m);let d=this.utils.createJsonRpcRequestPayload("magic_oauth_parse_redirect_result",[e,n,c]),u=yield this.request(d),o=u,i=u;i.error&&t(this.createError(i.error,(l=i.error_description)!=null?l:"An error occurred.",{errorURI:i.error_uri,provider:i.provider})),r(o)}))}0&&(module.exports={OAuthErrorCode,OAuthExtension,OAuthPayloadMethods,createURI,getResult});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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
|
|
5
|
-
"mappings": "uwBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oBAAAE,EAAA,mBAAAC,EAAA,wBAAAC,EAAA,cAAAC,EAAA,cAAAC,IAAA,eAAAC,EAAAP,GAAA,IAAAQ,EAA6B,4CAC7BC,EAA0B,wCAC1BC,EAA4B,oCCD5B,IAAAC,EAA2B,+BAC3BC,EAAmB,mCAEnB,IAAMC,EAAU,qEACVC,EAAa,OAAO,QAAW,aAAe,CAAC,CAAE,OAAO,OACxDC,EAAoBD,GAAc,CAAC,CAAE,OAAO,OAAO,OAKzD,SAASE,EAAsBC,EAAmB,CAChD,OAAO,MAAM,KAAKA,CAAK,EACpB,IAAKC,GAAkBL,EAAQK,EAAQL,EAAQ,OAAO,EACtD,KAAK,EAAE,CACZ,CAQA,SAASM,EAA6BC,EAAsC,CAC1E,IAAMC,EAAeC,GACZA,EAAO,QAAQ,MAAO,GAAG,EAAE,QAAQ,MAAO,GAAG,EAAE,QAAQ,KAAM,EAAE,EAGxE,GAAIF,aAAe,YAAa,CAC9B,IAAMH,EAAQ,IAAI,WAAWG,CAAG,EAC1BG,EAAa,MAAM,KAAKN,CAAK,EAChC,IAAKC,GAAU,OAAO,aAAaA,CAAK,CAAC,EACzC,KAAK,EAAE,EAEJI,EAAS,KAAKC,CAAU,EAC9B,OAAOF,EAAYC,CAAM,CAC3B,CAEA,OAAOD,EAAY,EAAAG,QAAO,UAAUJ,CAAG,CAAC,CAC1C,CAOA,SAAeK,EAAOC,EAAiB,QAAAC,EAAA,sBACrC,GAAIZ,EAAmB,CACrB,IAAME,EAAQ,IAAI,YAAY,EAAE,OAAOS,CAAO,EAC9C,OAAO,OAAO,OAAO,OAAO,UAAWT,CAAK,EAAE,KAAKE,CAA4B,CACjF,CAEA,OAAOA,KAA6B,EAAAS,SAAeF,CAAO,CAAC,CAC7D,GAMA,SAASG,EAAmBC,EAAc,CACxC,IAAMb,EAAQ,IAAI,WAAWa,CAAI,EAEjC,GAAIhB,EACF,OAAO,OAAO,gBAAgBG,CAAK,MAEnC,SAASc,EAAI,EAAGA,EAAID,EAAMC,GAAK,EAAGd,EAAMc,GAAK,KAAK,MAAM,KAAK,OAAO,EAAI,KAAK,MAAM,GAAG,CAAC,EAGzF,OAAOf,EAAsBC,CAAK,CACpC,CAMA,SAAsBe,GAAwB,QAAAL,EAAA,sBAC5C,IAAMM,EAAQJ,EAAmB,GAAG,EAC9BK,EAAWL,EAAmB,GAAG,EACjCM,EAAY,MAAMV,EAAOS,CAAQ,EACvC,MAAO,CAAE,SAAAA,EAAU,UAAAC,EAAW,MAAAF,CAAM,CACtC,GC9EO,IAAKG,OACVA,EAAA,oBAAsB,oCADZA,OAAA,
|
|
6
|
-
"names": ["src_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", "__async", "sha256Fallback", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "configuration", "resolve", "reject", "__async", "provider", "query", "redirectURI", "createURI", "url", "res", "queryString", "getResult", "err", "OAUTH_REDIRECT_METADATA_KEY", "scope", "loginHint", "
|
|
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 { WordArray } 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(wordArray: WordArray): string;\nfunction base64URLEncodeFromByteArray(arrayBuffer: ArrayBuffer): string;\nfunction base64URLEncodeFromByteArray(arg: 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": ["src_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", "__async", "sha256Fallback", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "configuration", "resolve", "reject", "__async", "provider", "query", "redirectURI", "createURI", "url", "res", "queryString", "getResult", "err", "OAUTH_REDIRECT_METADATA_KEY", "scope", "loginHint", "verifier", "challenge", "state", "createCryptoChallenge", "bundleId", "storedData", "prev", "next", "_a", "json", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
|
|
7
7
|
}
|
package/dist/es/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var p=(t,e,r)=>new Promise((u,a)=>{var s=i=>{try{c(r.next(i))}catch(n){a(n)}},d=i=>{try{c(r.throw(i))}catch(n){a(n)}},c=i=>i.done?u(i.value):Promise.resolve(i.value).then(s,d);c((r=r.apply(t,e)).next())});import{InAppBrowser as x}from"react-native-inappbrowser-reborn";import{Extension as E}from"@magic-sdk/react-native-bare";import{getBundleId as k}from"react-native-device-info";import v from"crypto-js/sha256";import _ from"crypto-js/enc-base64";var f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",R=typeof window!="undefined"&&!!window.crypto,U=R&&!!window.crypto.subtle;function O(t){return Array.from(t).map(e=>f[e%f.length]).join("")}function y(t){let e=r=>r.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"");if(t instanceof ArrayBuffer){let r=new Uint8Array(t),u=Array.from(r).map(s=>String.fromCharCode(s)).join(""),a=btoa(u);return e(a)}return e(_.stringify(t))}function w(t){return p(this,null,function*(){if(U){let e=new TextEncoder().encode(t);return crypto.subtle.digest("SHA-256",e).then(y)}return y(v(t))})}function h(t){let e=new Uint8Array(t);if(R)window.crypto.getRandomValues(e);else for(let r=0;r<t;r+=1)e[r]=Math.floor(Math.random()*Math.floor(255));return O(e)}function A(){return p(this,null,function*(){let t=h(128),e=h(128),r=yield w(e);return{verifier:e,challenge:r,state:t}})}var I=(e=>(e.ParseRedirectResult="magic_oauth_parse_redirect_result",e))(I||{}),C=(o=>(o.InvalidRequest="invalid_request",o.InvalidClient="invalid_client",o.InvalidScope="invalid_scope",o.InvalidGrant="invalid_grant",o.UnauthorizedClient="unauthorized_client",o.UnsupportedResponseType="unsupported_response_type",o.UnsupportedGrantType="unsupported_grant_type",o.UnsupportedTokenType="unsupported_token_type",o.AccessDenied="access_denied",o.ServerError="server_error",o.TemporarilyUnavailable="temporarily_unavailable",o))(C||{});var b=class extends E.Internal{constructor(){super(...arguments);this.name="oauth";this.config={};this.compat={"magic-sdk":!1,"@magic-sdk/react-native-bare":">=13.0.0","@magic-sdk/react-native-expo":!1,"@magic-sdk/react-native":!1}}loginWithPopup(r){return this.utils.createPromiEvent((u,a)=>p(this,null,function*(){try{let{provider:s,query:d,redirectURI:c}=yield D.call(this,r),i=`https://auth.magic.link/v1/oauth2/${s}/start?${d}`,n=yield x.openAuth(i,c,{});if(n.type==="success"){let l=new URL(n.url).search;u(P.call(this,l.toString()))}else a(this.createError(n.type,"User has cancelled the authentication",{}))}catch(s){a(this.createError(s.message,"An error has occurred",{err:s}))}}))}},g="oauth_redirect_metadata";function D(t){return p(this,null,function*(){yield this.utils.storage.removeItem(g);let{provider:e,redirectURI:r,scope:u,loginHint:a}=t,{verifier:s,challenge:d,state:c}=yield A(),i=k(),n=JSON.stringify({verifier:s,state:c});return yield this.utils.storage.setItem(g,n),{query:[`magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,`magic_challenge=${encodeURIComponent(d)}`,`state=${encodeURIComponent(c)}`,`platform=${encodeURIComponent("rn")}`,u&&`scope=${encodeURIComponent(u.join(" "))}`,r&&`redirect_uri=${encodeURIComponent(r)}`,a&&`login_hint=${encodeURIComponent(a)}`,i&&`bundleId=${encodeURIComponent(i)}`].reduce((o,m)=>m?`${o}&${m}`:o),provider:e,redirectURI:r}})}function P(t){return this.utils.createPromiEvent((e,r)=>p(this,null,function*(){var l;let u=yield this.utils.storage.getItem(g),{verifier:a,state:s}=JSON.parse(u);this.utils.storage.removeItem(g);let d=this.utils.createJsonRpcRequestPayload("magic_oauth_parse_redirect_result",[t,a,s]),c=yield this.request(d),i=c,n=c;n.error&&r(this.createError(n.error,(l=n.error_description)!=null?l:"An error occurred.",{errorURI:n.error_uri,provider:n.provider})),e(i)}))}export{C as OAuthErrorCode,b as OAuthExtension,I as OAuthPayloadMethods,D as createURI,P as getResult};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/es/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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
|
|
5
|
-
"mappings": "6MAAA,OAAS,gBAAAA,MAAoB,mCAC7B,OAAS,aAAAC,MAAiB,+BAC1B,OAAS,eAAAC,MAAmB,2BCD5B,OAAOC,MAAoB,mBAC3B,OAAOC,MAAY,uBAEnB,IAAMC,EAAU,qEACVC,EAAa,OAAO,QAAW,aAAe,CAAC,CAAE,OAAO,OACxDC,EAAoBD,GAAc,CAAC,CAAE,OAAO,OAAO,OAKzD,SAASE,EAAsBC,EAAmB,CAChD,OAAO,MAAM,KAAKA,CAAK,EACpB,IAAKC,GAAkBL,EAAQK,EAAQL,EAAQ,OAAO,EACtD,KAAK,EAAE,CACZ,CAQA,SAASM,EAA6BC,EAAsC,CAC1E,IAAMC,EAAeC,GACZA,EAAO,QAAQ,MAAO,GAAG,EAAE,QAAQ,MAAO,GAAG,EAAE,QAAQ,KAAM,EAAE,EAGxE,GAAIF,aAAe,YAAa,CAC9B,IAAMH,EAAQ,IAAI,WAAWG,CAAG,EAC1BG,EAAa,MAAM,KAAKN,CAAK,EAChC,IAAKC,GAAU,OAAO,aAAaA,CAAK,CAAC,EACzC,KAAK,EAAE,EAEJI,EAAS,KAAKC,CAAU,EAC9B,OAAOF,EAAYC,CAAM,CAC3B,CAEA,OAAOD,EAAYG,EAAO,UAAUJ,CAAG,CAAC,CAC1C,CAOA,SAAeK,EAAOC,EAAiB,QAAAC,EAAA,sBACrC,GAAIZ,EAAmB,CACrB,IAAME,EAAQ,IAAI,YAAY,EAAE,OAAOS,CAAO,EAC9C,OAAO,OAAO,OAAO,OAAO,UAAWT,CAAK,EAAE,KAAKE,CAA4B,CACjF,CAEA,OAAOA,EAA6BS,EAAeF,CAAO,CAAC,CAC7D,GAMA,SAASG,EAAmBC,EAAc,CACxC,IAAMb,EAAQ,IAAI,WAAWa,CAAI,EAEjC,GAAIhB,EACF,OAAO,OAAO,gBAAgBG,CAAK,MAEnC,SAASc,EAAI,EAAGA,EAAID,EAAMC,GAAK,EAAGd,EAAMc,GAAK,KAAK,MAAM,KAAK,OAAO,EAAI,KAAK,MAAM,GAAG,CAAC,EAGzF,OAAOf,EAAsBC,CAAK,CACpC,CAMA,SAAsBe,GAAwB,QAAAL,EAAA,sBAC5C,IAAMM,EAAQJ,EAAmB,GAAG,EAC9BK,EAAWL,EAAmB,GAAG,EACjCM,EAAY,MAAMV,EAAOS,CAAQ,EACvC,MAAO,CAAE,SAAAA,EAAU,UAAAC,EAAW,MAAAF,CAAM,CACtC,GC9EO,IAAKG,OACVA,EAAA,oBAAsB,oCADZA,OAAA,
|
|
6
|
-
"names": ["InAppBrowser", "Extension", "getBundleId", "sha256Fallback", "Base64", "CHARSET", "HAS_CRYPTO", "HAS_SUBTLE_CRYPTO", "bytesToVerifierString", "bytes", "value", "base64URLEncodeFromByteArray", "arg", "makeURLSafe", "base64", "utf8Binary", "Base64", "sha256", "message", "__async", "sha256Fallback", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "Extension", "configuration", "resolve", "reject", "__async", "provider", "query", "redirectURI", "createURI", "url", "res", "InAppBrowser", "queryString", "getResult", "err", "OAUTH_REDIRECT_METADATA_KEY", "scope", "loginHint", "
|
|
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 { WordArray } 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(wordArray: WordArray): string;\nfunction base64URLEncodeFromByteArray(arrayBuffer: ArrayBuffer): string;\nfunction base64URLEncodeFromByteArray(arg: 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", "Base64", "sha256", "message", "__async", "sha256Fallback", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "Extension", "configuration", "resolve", "reject", "__async", "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", "_a", "json", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
|
|
7
7
|
}
|
package/dist/es/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var p=(t,e,r)=>new Promise((u,a)=>{var s=i=>{try{c(r.next(i))}catch(n){a(n)}},d=i=>{try{c(r.throw(i))}catch(n){a(n)}},c=i=>i.done?u(i.value):Promise.resolve(i.value).then(s,d);c((r=r.apply(t,e)).next())});import{InAppBrowser as x}from"react-native-inappbrowser-reborn";import{Extension as E}from"@magic-sdk/react-native-bare";import{getBundleId as k}from"react-native-device-info";import v from"crypto-js/sha256";import _ from"crypto-js/enc-base64";var f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",R=typeof window!="undefined"&&!!window.crypto,U=R&&!!window.crypto.subtle;function O(t){return Array.from(t).map(e=>f[e%f.length]).join("")}function y(t){let e=r=>r.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"");if(t instanceof ArrayBuffer){let r=new Uint8Array(t),u=Array.from(r).map(s=>String.fromCharCode(s)).join(""),a=btoa(u);return e(a)}return e(_.stringify(t))}function w(t){return p(this,null,function*(){if(U){let e=new TextEncoder().encode(t);return crypto.subtle.digest("SHA-256",e).then(y)}return y(v(t))})}function h(t){let e=new Uint8Array(t);if(R)window.crypto.getRandomValues(e);else for(let r=0;r<t;r+=1)e[r]=Math.floor(Math.random()*Math.floor(255));return O(e)}function A(){return p(this,null,function*(){let t=h(128),e=h(128),r=yield w(e);return{verifier:e,challenge:r,state:t}})}var I=(e=>(e.ParseRedirectResult="magic_oauth_parse_redirect_result",e))(I||{}),C=(o=>(o.InvalidRequest="invalid_request",o.InvalidClient="invalid_client",o.InvalidScope="invalid_scope",o.InvalidGrant="invalid_grant",o.UnauthorizedClient="unauthorized_client",o.UnsupportedResponseType="unsupported_response_type",o.UnsupportedGrantType="unsupported_grant_type",o.UnsupportedTokenType="unsupported_token_type",o.AccessDenied="access_denied",o.ServerError="server_error",o.TemporarilyUnavailable="temporarily_unavailable",o))(C||{});var b=class extends E.Internal{constructor(){super(...arguments);this.name="oauth";this.config={};this.compat={"magic-sdk":!1,"@magic-sdk/react-native-bare":">=13.0.0","@magic-sdk/react-native-expo":!1,"@magic-sdk/react-native":!1}}loginWithPopup(r){return this.utils.createPromiEvent((u,a)=>p(this,null,function*(){try{let{provider:s,query:d,redirectURI:c}=yield D.call(this,r),i=`https://auth.magic.link/v1/oauth2/${s}/start?${d}`,n=yield x.openAuth(i,c,{});if(n.type==="success"){let l=new URL(n.url).search;u(P.call(this,l.toString()))}else a(this.createError(n.type,"User has cancelled the authentication",{}))}catch(s){a(this.createError(s.message,"An error has occurred",{err:s}))}}))}},g="oauth_redirect_metadata";function D(t){return p(this,null,function*(){yield this.utils.storage.removeItem(g);let{provider:e,redirectURI:r,scope:u,loginHint:a}=t,{verifier:s,challenge:d,state:c}=yield A(),i=k(),n=JSON.stringify({verifier:s,state:c});return yield this.utils.storage.setItem(g,n),{query:[`magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,`magic_challenge=${encodeURIComponent(d)}`,`state=${encodeURIComponent(c)}`,`platform=${encodeURIComponent("rn")}`,u&&`scope=${encodeURIComponent(u.join(" "))}`,r&&`redirect_uri=${encodeURIComponent(r)}`,a&&`login_hint=${encodeURIComponent(a)}`,i&&`bundleId=${encodeURIComponent(i)}`].reduce((o,m)=>m?`${o}&${m}`:o),provider:e,redirectURI:r}})}function P(t){return this.utils.createPromiEvent((e,r)=>p(this,null,function*(){var l;let u=yield this.utils.storage.getItem(g),{verifier:a,state:s}=JSON.parse(u);this.utils.storage.removeItem(g);let d=this.utils.createJsonRpcRequestPayload("magic_oauth_parse_redirect_result",[t,a,s]),c=yield this.request(d),i=c,n=c;n.error&&r(this.createError(n.error,(l=n.error_description)!=null?l:"An error occurred.",{errorURI:n.error_uri,provider:n.provider})),e(i)}))}export{C as OAuthErrorCode,b as OAuthExtension,I as OAuthPayloadMethods,D as createURI,P as getResult};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/es/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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
|
|
5
|
-
"mappings": "6MAAA,OAAS,gBAAAA,MAAoB,mCAC7B,OAAS,aAAAC,MAAiB,+BAC1B,OAAS,eAAAC,MAAmB,2BCD5B,OAAOC,MAAoB,mBAC3B,OAAOC,MAAY,uBAEnB,IAAMC,EAAU,qEACVC,EAAa,OAAO,QAAW,aAAe,CAAC,CAAE,OAAO,OACxDC,EAAoBD,GAAc,CAAC,CAAE,OAAO,OAAO,OAKzD,SAASE,EAAsBC,EAAmB,CAChD,OAAO,MAAM,KAAKA,CAAK,EACpB,IAAKC,GAAkBL,EAAQK,EAAQL,EAAQ,OAAO,EACtD,KAAK,EAAE,CACZ,CAQA,SAASM,EAA6BC,EAAsC,CAC1E,IAAMC,EAAeC,GACZA,EAAO,QAAQ,MAAO,GAAG,EAAE,QAAQ,MAAO,GAAG,EAAE,QAAQ,KAAM,EAAE,EAGxE,GAAIF,aAAe,YAAa,CAC9B,IAAMH,EAAQ,IAAI,WAAWG,CAAG,EAC1BG,EAAa,MAAM,KAAKN,CAAK,EAChC,IAAKC,GAAU,OAAO,aAAaA,CAAK,CAAC,EACzC,KAAK,EAAE,EAEJI,EAAS,KAAKC,CAAU,EAC9B,OAAOF,EAAYC,CAAM,CAC3B,CAEA,OAAOD,EAAYG,EAAO,UAAUJ,CAAG,CAAC,CAC1C,CAOA,SAAeK,EAAOC,EAAiB,QAAAC,EAAA,sBACrC,GAAIZ,EAAmB,CACrB,IAAME,EAAQ,IAAI,YAAY,EAAE,OAAOS,CAAO,EAC9C,OAAO,OAAO,OAAO,OAAO,UAAWT,CAAK,EAAE,KAAKE,CAA4B,CACjF,CAEA,OAAOA,EAA6BS,EAAeF,CAAO,CAAC,CAC7D,GAMA,SAASG,EAAmBC,EAAc,CACxC,IAAMb,EAAQ,IAAI,WAAWa,CAAI,EAEjC,GAAIhB,EACF,OAAO,OAAO,gBAAgBG,CAAK,MAEnC,SAASc,EAAI,EAAGA,EAAID,EAAMC,GAAK,EAAGd,EAAMc,GAAK,KAAK,MAAM,KAAK,OAAO,EAAI,KAAK,MAAM,GAAG,CAAC,EAGzF,OAAOf,EAAsBC,CAAK,CACpC,CAMA,SAAsBe,GAAwB,QAAAL,EAAA,sBAC5C,IAAMM,EAAQJ,EAAmB,GAAG,EAC9BK,EAAWL,EAAmB,GAAG,EACjCM,EAAY,MAAMV,EAAOS,CAAQ,EACvC,MAAO,CAAE,SAAAA,EAAU,UAAAC,EAAW,MAAAF,CAAM,CACtC,GC9EO,IAAKG,OACVA,EAAA,oBAAsB,oCADZA,OAAA,
|
|
6
|
-
"names": ["InAppBrowser", "Extension", "getBundleId", "sha256Fallback", "Base64", "CHARSET", "HAS_CRYPTO", "HAS_SUBTLE_CRYPTO", "bytesToVerifierString", "bytes", "value", "base64URLEncodeFromByteArray", "arg", "makeURLSafe", "base64", "utf8Binary", "Base64", "sha256", "message", "__async", "sha256Fallback", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "Extension", "configuration", "resolve", "reject", "__async", "provider", "query", "redirectURI", "createURI", "url", "res", "InAppBrowser", "queryString", "getResult", "err", "OAUTH_REDIRECT_METADATA_KEY", "scope", "loginHint", "
|
|
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 { WordArray } 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(wordArray: WordArray): string;\nfunction base64URLEncodeFromByteArray(arrayBuffer: ArrayBuffer): string;\nfunction base64URLEncodeFromByteArray(arg: 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", "Base64", "sha256", "message", "__async", "sha256Fallback", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthPayloadMethods", "OAuthErrorCode", "OAuthExtension", "Extension", "configuration", "resolve", "reject", "__async", "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", "_a", "json", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
|
|
7
7
|
}
|
package/dist/types/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magic-ext/react-native-bare-oauth",
|
|
3
|
-
"version": "25.
|
|
3
|
+
"version": "25.3.0-canary.64c67a3.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",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"react-native-device-info": "^10.3.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@magic-sdk/react-native-bare": "
|
|
34
|
-
"@magic-sdk/types": "
|
|
33
|
+
"@magic-sdk/react-native-bare": "29.3.0-canary.64c67a3.0",
|
|
34
|
+
"@magic-sdk/types": "24.1.0-canary.64c67a3.0",
|
|
35
35
|
"@types/crypto-js": "~3.1.47",
|
|
36
36
|
"react-native-inappbrowser-reborn": "^3.7.0"
|
|
37
37
|
},
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"@magic-sdk/react-native-bare": ">=13.0.0",
|
|
40
40
|
"react-native-inappbrowser-reborn": ">=3.7.0"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "64c67a37dd32bd897a5eb8dc23c1b53a54c3dd27"
|
|
43
43
|
}
|