expo-auth-session 5.2.1 → 5.3.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/CHANGELOG.md +10 -0
- package/build/AuthRequest.d.ts.map +1 -1
- package/build/AuthRequest.js +1 -2
- package/build/AuthRequest.js.map +1 -1
- package/build/Fetch.d.ts.map +1 -1
- package/build/Fetch.js +1 -2
- package/build/Fetch.js.map +1 -1
- package/build/QueryParams.d.ts +1 -2
- package/build/QueryParams.d.ts.map +1 -1
- package/build/QueryParams.js +12 -23
- package/build/QueryParams.js.map +1 -1
- package/build/SessionUrlProvider.d.ts.map +1 -1
- package/build/SessionUrlProvider.js +4 -3
- package/build/SessionUrlProvider.js.map +1 -1
- package/package.json +7 -9
- package/src/AuthRequest.ts +1 -2
- package/src/Fetch.ts +1 -2
- package/src/QueryParams.ts +13 -30
- package/src/SessionUrlProvider.ts +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 5.3.0 — 2023-11-14
|
|
14
|
+
|
|
15
|
+
### 💡 Others
|
|
16
|
+
|
|
17
|
+
- Migrate to new standard `URL` support on native. ([#24941](https://github.com/expo/expo/pull/24941) by [@EvanBacon](https://github.com/EvanBacon))
|
|
18
|
+
|
|
19
|
+
## 5.2.2 — 2023-10-17
|
|
20
|
+
|
|
21
|
+
_This version does not introduce any user-facing changes._
|
|
22
|
+
|
|
13
23
|
## 5.2.1 — 2023-09-16
|
|
14
24
|
|
|
15
25
|
_This version does not introduce any user-facing changes._
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthRequest.d.ts","sourceRoot":"","sources":["../src/AuthRequest.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,EACZ,MAAM,EACP,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQhD,KAAK,qBAAqB,GAAG,IAAI,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;AAG9E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,WAAY,YAAW,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAClE;;OAEG;IACI,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,iBAAiB;IA2CtC;;OAEG;IACG,yBAAyB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAoB7D;;;;;OAKG;IACG,WAAW,CACf,SAAS,EAAE,qBAAqB,EAChC,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAE,wBAA6B,GACjD,OAAO,CAAC,iBAAiB,CAAC;IAuD7B,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB;IAgC9C;;;;OAIG;IACG,gBAAgB,CAAC,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthRequest.d.ts","sourceRoot":"","sources":["../src/AuthRequest.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,EACZ,MAAM,EACP,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQhD,KAAK,qBAAqB,GAAG,IAAI,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;AAG9E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,WAAY,YAAW,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAClE;;OAEG;IACI,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,iBAAiB;IA2CtC;;OAEG;IACG,yBAAyB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAoB7D;;;;;OAKG;IACG,WAAW,CACf,SAAS,EAAE,qBAAqB,EAChC,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAE,wBAA6B,GACjD,OAAO,CAAC,iBAAiB,CAAC;IAuD7B,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB;IAgC9C;;;;OAIG;IACG,gBAAgB,CAAC,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;YA6C3D,sBAAsB;CAWrC"}
|
package/build/AuthRequest.js
CHANGED
|
@@ -214,9 +214,8 @@ export class AuthRequest {
|
|
|
214
214
|
if (request.scopes?.length) {
|
|
215
215
|
params.scope = request.scopes.join(' ');
|
|
216
216
|
}
|
|
217
|
-
const query = QueryParams.buildQueryString(params);
|
|
218
217
|
// Store the URL for later
|
|
219
|
-
this.url = `${discovery.authorizationEndpoint}?${
|
|
218
|
+
this.url = `${discovery.authorizationEndpoint}?${new URLSearchParams(params)}`;
|
|
220
219
|
return this.url;
|
|
221
220
|
}
|
|
222
221
|
async ensureCodeIsSetupAsync() {
|
package/build/AuthRequest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthRequest.js","sourceRoot":"","sources":["../src/AuthRequest.ts"],"names":[],"mappings":"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","sourcesContent":["import * as WebBrowser from 'expo-web-browser';\nimport invariant from 'invariant';\nimport { Platform } from 'react-native';\n\nimport {\n AuthRequestConfig,\n AuthRequestPromptOptions,\n CodeChallengeMethod,\n ResponseType,\n Prompt,\n} from './AuthRequest.types';\nimport { AuthSessionResult } from './AuthSession.types';\nimport { DiscoveryDocument } from './Discovery';\nimport { AuthError } from './Errors';\nimport * as PKCE from './PKCE';\nimport * as QueryParams from './QueryParams';\nimport { TokenResponse } from './TokenRequest';\n\nlet _authLock: boolean = false;\n\ntype AuthDiscoveryDocument = Pick<DiscoveryDocument, 'authorizationEndpoint'>;\n\n// @needsAudit @docsMissing\n/**\n * Used to manage an authorization request according to the OAuth spec: [Section 4.1.1](https://tools.ietf.org/html/rfc6749#section-4.1.1).\n * You can use this class directly for more info around the authorization.\n *\n * **Common use-cases:**\n *\n * - Parse a URL returned from the authorization server with `parseReturnUrlAsync()`.\n * - Get the built authorization URL with `makeAuthUrlAsync()`.\n * - Get a loaded JSON representation of the auth request with crypto state loaded with `getAuthRequestConfigAsync()`.\n *\n * @example\n * ```ts\n * // Create a request.\n * const request = new AuthRequest({ ... });\n *\n * // Prompt for an auth code\n * const result = await request.promptAsync(discovery);\n *\n * // Get the URL to invoke\n * const url = await request.makeAuthUrlAsync(discovery);\n *\n * // Get the URL to invoke\n * const parsed = await request.parseReturnUrlAsync(\"<URL From Server>\");\n * ```\n */\nexport class AuthRequest implements Omit<AuthRequestConfig, 'state'> {\n /**\n * Used for protection against [Cross-Site Request Forgery](https://tools.ietf.org/html/rfc6749#section-10.12).\n */\n public state: string;\n public url: string | null = null;\n public codeVerifier?: string;\n public codeChallenge?: string;\n\n readonly responseType: ResponseType | string;\n readonly clientId: string;\n readonly extraParams: Record<string, string>;\n readonly usePKCE?: boolean;\n readonly codeChallengeMethod: CodeChallengeMethod;\n readonly redirectUri: string;\n readonly scopes?: string[];\n readonly clientSecret?: string;\n readonly prompt?: Prompt;\n\n constructor(request: AuthRequestConfig) {\n this.responseType = request.responseType ?? ResponseType.Code;\n this.clientId = request.clientId;\n this.redirectUri = request.redirectUri;\n this.scopes = request.scopes;\n this.clientSecret = request.clientSecret;\n this.prompt = request.prompt;\n this.state = request.state ?? PKCE.generateRandom(10);\n this.extraParams = request.extraParams ?? {};\n this.codeChallengeMethod = request.codeChallengeMethod ?? CodeChallengeMethod.S256;\n // PKCE defaults to true\n this.usePKCE = request.usePKCE ?? true;\n\n // Some warnings in development about potential confusing application code\n if (__DEV__) {\n if (this.prompt && this.extraParams.prompt) {\n console.warn(`\\`AuthRequest\\` \\`extraParams.prompt\\` will be overwritten by \\`prompt\\`.`);\n }\n if (this.clientSecret && this.extraParams.client_secret) {\n console.warn(\n `\\`AuthRequest\\` \\`extraParams.client_secret\\` will be overwritten by \\`clientSecret\\`.`\n );\n }\n if (this.codeChallengeMethod && this.extraParams.code_challenge_method) {\n console.warn(\n `\\`AuthRequest\\` \\`extraParams.code_challenge_method\\` will be overwritten by \\`codeChallengeMethod\\`.`\n );\n }\n }\n\n invariant(\n this.codeChallengeMethod !== CodeChallengeMethod.Plain,\n `\\`AuthRequest\\` does not support \\`CodeChallengeMethod.Plain\\` as it's not secure.`\n );\n invariant(\n this.redirectUri,\n `\\`AuthRequest\\` requires a valid \\`redirectUri\\`. Ex: ${Platform.select({\n web: 'https://yourwebsite.com/',\n default: 'com.your.app:/oauthredirect',\n })}`\n );\n }\n\n /**\n * Load and return a valid auth request based on the input config.\n */\n async getAuthRequestConfigAsync(): Promise<AuthRequestConfig> {\n if (this.usePKCE) {\n await this.ensureCodeIsSetupAsync();\n }\n\n return {\n responseType: this.responseType,\n clientId: this.clientId,\n redirectUri: this.redirectUri,\n scopes: this.scopes,\n clientSecret: this.clientSecret,\n codeChallenge: this.codeChallenge,\n codeChallengeMethod: this.codeChallengeMethod,\n prompt: this.prompt,\n state: this.state,\n extraParams: this.extraParams,\n usePKCE: this.usePKCE,\n };\n }\n\n /**\n * Prompt a user to authorize for a code.\n *\n * @param discovery\n * @param promptOptions\n */\n async promptAsync(\n discovery: AuthDiscoveryDocument,\n { url, ...options }: AuthRequestPromptOptions = {}\n ): Promise<AuthSessionResult> {\n if (!url) {\n if (!this.url) {\n // Generate a new url\n return this.promptAsync(discovery, {\n ...options,\n url: await this.makeAuthUrlAsync(discovery),\n });\n }\n // Reuse the preloaded url\n url = this.url;\n }\n\n // Prevent accidentally starting to an empty url\n invariant(\n url,\n 'No authUrl provided to AuthSession.startAsync. An authUrl is required -- it points to the page where the user will be able to sign in.'\n );\n\n const startUrl: string = url!;\n const returnUrl: string = this.redirectUri;\n\n // Prevent multiple sessions from running at the same time, WebBrowser doesn't\n // support it this makes the behavior predictable.\n if (_authLock) {\n if (__DEV__) {\n console.warn(\n 'Attempted to call AuthSession.startAsync multiple times while already active. Only one AuthSession can be active at any given time.'\n );\n }\n\n return { type: 'locked' };\n }\n\n // About to start session, set lock\n _authLock = true;\n\n let result: WebBrowser.WebBrowserAuthSessionResult;\n try {\n result = await WebBrowser.openAuthSessionAsync(startUrl, returnUrl, options);\n } finally {\n _authLock = false;\n }\n\n if (result.type === 'opened') {\n // This should never happen\n throw new Error('An unexpected error occurred');\n }\n if (result.type !== 'success') {\n return { type: result.type };\n }\n\n return this.parseReturnUrl(result.url);\n }\n\n parseReturnUrl(url: string): AuthSessionResult {\n const { params, errorCode } = QueryParams.getQueryParams(url);\n const { state, error = errorCode } = params;\n\n let parsedError: AuthError | null = null;\n let authentication: TokenResponse | null = null;\n if (state !== this.state) {\n // This is a non-standard error\n parsedError = new AuthError({\n error: 'state_mismatch',\n error_description:\n 'Cross-Site request verification failed. Cached state and returned state do not match.',\n });\n } else if (error) {\n parsedError = new AuthError({ error, ...params });\n }\n if (params.access_token) {\n authentication = TokenResponse.fromQueryParams(params);\n }\n\n return {\n type: parsedError ? 'error' : 'success',\n error: parsedError,\n url,\n params,\n authentication,\n\n // Return errorCode for legacy\n errorCode,\n };\n }\n\n /**\n * Create the URL for authorization.\n *\n * @param discovery\n */\n async makeAuthUrlAsync(discovery: AuthDiscoveryDocument): Promise<string> {\n const request = await this.getAuthRequestConfigAsync();\n if (!request.state) throw new Error('Cannot make request URL without a valid `state` loaded');\n\n // Create a query string\n const params: Record<string, string> = {};\n\n if (request.codeChallenge) {\n params.code_challenge = request.codeChallenge;\n }\n\n // copy over extra params\n for (const extra in request.extraParams) {\n if (extra in request.extraParams) {\n params[extra] = request.extraParams[extra];\n }\n }\n\n if (request.usePKCE && request.codeChallengeMethod) {\n params.code_challenge_method = request.codeChallengeMethod;\n }\n\n if (request.clientSecret) {\n params.client_secret = request.clientSecret;\n }\n\n if (request.prompt) {\n params.prompt = request.prompt;\n }\n\n // These overwrite any extra params\n params.redirect_uri = request.redirectUri;\n params.client_id = request.clientId;\n params.response_type = request.responseType!;\n params.state = request.state;\n\n if (request.scopes?.length) {\n params.scope = request.scopes.join(' ');\n }\n\n const query = QueryParams.buildQueryString(params);\n // Store the URL for later\n this.url = `${discovery.authorizationEndpoint}?${query}`;\n return this.url;\n }\n\n private async ensureCodeIsSetupAsync(): Promise<void> {\n if (this.codeVerifier) {\n return;\n }\n\n // This method needs to be resolved like all other native methods.\n const { codeVerifier, codeChallenge } = await PKCE.buildCodeAsync();\n\n this.codeVerifier = codeVerifier;\n this.codeChallenge = codeChallenge;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AuthRequest.js","sourceRoot":"","sources":["../src/AuthRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAGL,mBAAmB,EACnB,YAAY,GAEb,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,WAAW,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,IAAI,SAAS,GAAY,KAAK,CAAC;AAI/B,2BAA2B;AAC3B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAO,WAAW;IACtB;;OAEG;IACI,KAAK,CAAS;IACd,GAAG,GAAkB,IAAI,CAAC;IAC1B,YAAY,CAAU;IACtB,aAAa,CAAU;IAErB,YAAY,CAAwB;IACpC,QAAQ,CAAS;IACjB,WAAW,CAAyB;IACpC,OAAO,CAAW;IAClB,mBAAmB,CAAsB;IACzC,WAAW,CAAS;IACpB,MAAM,CAAY;IAClB,YAAY,CAAU;IACtB,MAAM,CAAU;IAEzB,YAAY,OAA0B;QACpC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,CAAC;QAC9D,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,IAAI,mBAAmB,CAAC,IAAI,CAAC;QACnF,wBAAwB;QACxB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;QAEvC,0EAA0E;QAC1E,IAAI,OAAO,EAAE;YACX,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;gBAC1C,OAAO,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;aAC3F;YACD,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE;gBACvD,OAAO,CAAC,IAAI,CACV,wFAAwF,CACzF,CAAC;aACH;YACD,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,WAAW,CAAC,qBAAqB,EAAE;gBACtE,OAAO,CAAC,IAAI,CACV,uGAAuG,CACxG,CAAC;aACH;SACF;QAED,SAAS,CACP,IAAI,CAAC,mBAAmB,KAAK,mBAAmB,CAAC,KAAK,EACtD,oFAAoF,CACrF,CAAC;QACF,SAAS,CACP,IAAI,CAAC,WAAW,EAChB,yDAAyD,QAAQ,CAAC,MAAM,CAAC;YACvE,GAAG,EAAE,0BAA0B;YAC/B,OAAO,EAAE,6BAA6B;SACvC,CAAC,EAAE,CACL,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,yBAAyB;QAC7B,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;SACrC;QAED,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CACf,SAAgC,EAChC,EAAE,GAAG,EAAE,GAAG,OAAO,KAA+B,EAAE;QAElD,IAAI,CAAC,GAAG,EAAE;YACR,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;gBACb,qBAAqB;gBACrB,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;oBACjC,GAAG,OAAO;oBACV,GAAG,EAAE,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC;iBAC5C,CAAC,CAAC;aACJ;YACD,0BAA0B;YAC1B,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;SAChB;QAED,gDAAgD;QAChD,SAAS,CACP,GAAG,EACH,wIAAwI,CACzI,CAAC;QAEF,MAAM,QAAQ,GAAW,GAAI,CAAC;QAC9B,MAAM,SAAS,GAAW,IAAI,CAAC,WAAW,CAAC;QAE3C,8EAA8E;QAC9E,kDAAkD;QAClD,IAAI,SAAS,EAAE;YACb,IAAI,OAAO,EAAE;gBACX,OAAO,CAAC,IAAI,CACV,qIAAqI,CACtI,CAAC;aACH;YAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;SAC3B;QAED,mCAAmC;QACnC,SAAS,GAAG,IAAI,CAAC;QAEjB,IAAI,MAA8C,CAAC;QACnD,IAAI;YACF,MAAM,GAAG,MAAM,UAAU,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;SAC9E;gBAAS;YACR,SAAS,GAAG,KAAK,CAAC;SACnB;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;YAC5B,2BAA2B;YAC3B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;SACjD;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;YAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;SAC9B;QAED,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,cAAc,CAAC,GAAW;QACxB,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC9D,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,GAAG,MAAM,CAAC;QAE5C,IAAI,WAAW,GAAqB,IAAI,CAAC;QACzC,IAAI,cAAc,GAAyB,IAAI,CAAC;QAChD,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE;YACxB,+BAA+B;YAC/B,WAAW,GAAG,IAAI,SAAS,CAAC;gBAC1B,KAAK,EAAE,gBAAgB;gBACvB,iBAAiB,EACf,uFAAuF;aAC1F,CAAC,CAAC;SACJ;aAAM,IAAI,KAAK,EAAE;YAChB,WAAW,GAAG,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;SACnD;QACD,IAAI,MAAM,CAAC,YAAY,EAAE;YACvB,cAAc,GAAG,aAAa,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;SACxD;QAED,OAAO;YACL,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YACvC,KAAK,EAAE,WAAW;YAClB,GAAG;YACH,MAAM;YACN,cAAc;YAEd,8BAA8B;YAC9B,SAAS;SACV,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CAAC,SAAgC;QACrD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACvD,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAE9F,wBAAwB;QACxB,MAAM,MAAM,GAA2B,EAAE,CAAC;QAE1C,IAAI,OAAO,CAAC,aAAa,EAAE;YACzB,MAAM,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;SAC/C;QAED,yBAAyB;QACzB,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,WAAW,EAAE;YACvC,IAAI,KAAK,IAAI,OAAO,CAAC,WAAW,EAAE;gBAChC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;aAC5C;SACF;QAED,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,mBAAmB,EAAE;YAClD,MAAM,CAAC,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC;SAC5D;QAED,IAAI,OAAO,CAAC,YAAY,EAAE;YACxB,MAAM,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;SAC7C;QAED,IAAI,OAAO,CAAC,MAAM,EAAE;YAClB,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;SAChC;QAED,mCAAmC;QACnC,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;QAC1C,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;QACpC,MAAM,CAAC,aAAa,GAAG,OAAO,CAAC,YAAa,CAAC;QAC7C,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAE7B,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;YAC1B,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SACzC;QAED,0BAA0B;QAC1B,IAAI,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,qBAAqB,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,sBAAsB;QAClC,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,OAAO;SACR;QAED,kEAAkE;QAClE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAEpE,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;CACF","sourcesContent":["import * as WebBrowser from 'expo-web-browser';\nimport invariant from 'invariant';\nimport { Platform } from 'react-native';\n\nimport {\n AuthRequestConfig,\n AuthRequestPromptOptions,\n CodeChallengeMethod,\n ResponseType,\n Prompt,\n} from './AuthRequest.types';\nimport { AuthSessionResult } from './AuthSession.types';\nimport { DiscoveryDocument } from './Discovery';\nimport { AuthError } from './Errors';\nimport * as PKCE from './PKCE';\nimport * as QueryParams from './QueryParams';\nimport { TokenResponse } from './TokenRequest';\n\nlet _authLock: boolean = false;\n\ntype AuthDiscoveryDocument = Pick<DiscoveryDocument, 'authorizationEndpoint'>;\n\n// @needsAudit @docsMissing\n/**\n * Used to manage an authorization request according to the OAuth spec: [Section 4.1.1](https://tools.ietf.org/html/rfc6749#section-4.1.1).\n * You can use this class directly for more info around the authorization.\n *\n * **Common use-cases:**\n *\n * - Parse a URL returned from the authorization server with `parseReturnUrlAsync()`.\n * - Get the built authorization URL with `makeAuthUrlAsync()`.\n * - Get a loaded JSON representation of the auth request with crypto state loaded with `getAuthRequestConfigAsync()`.\n *\n * @example\n * ```ts\n * // Create a request.\n * const request = new AuthRequest({ ... });\n *\n * // Prompt for an auth code\n * const result = await request.promptAsync(discovery);\n *\n * // Get the URL to invoke\n * const url = await request.makeAuthUrlAsync(discovery);\n *\n * // Get the URL to invoke\n * const parsed = await request.parseReturnUrlAsync(\"<URL From Server>\");\n * ```\n */\nexport class AuthRequest implements Omit<AuthRequestConfig, 'state'> {\n /**\n * Used for protection against [Cross-Site Request Forgery](https://tools.ietf.org/html/rfc6749#section-10.12).\n */\n public state: string;\n public url: string | null = null;\n public codeVerifier?: string;\n public codeChallenge?: string;\n\n readonly responseType: ResponseType | string;\n readonly clientId: string;\n readonly extraParams: Record<string, string>;\n readonly usePKCE?: boolean;\n readonly codeChallengeMethod: CodeChallengeMethod;\n readonly redirectUri: string;\n readonly scopes?: string[];\n readonly clientSecret?: string;\n readonly prompt?: Prompt;\n\n constructor(request: AuthRequestConfig) {\n this.responseType = request.responseType ?? ResponseType.Code;\n this.clientId = request.clientId;\n this.redirectUri = request.redirectUri;\n this.scopes = request.scopes;\n this.clientSecret = request.clientSecret;\n this.prompt = request.prompt;\n this.state = request.state ?? PKCE.generateRandom(10);\n this.extraParams = request.extraParams ?? {};\n this.codeChallengeMethod = request.codeChallengeMethod ?? CodeChallengeMethod.S256;\n // PKCE defaults to true\n this.usePKCE = request.usePKCE ?? true;\n\n // Some warnings in development about potential confusing application code\n if (__DEV__) {\n if (this.prompt && this.extraParams.prompt) {\n console.warn(`\\`AuthRequest\\` \\`extraParams.prompt\\` will be overwritten by \\`prompt\\`.`);\n }\n if (this.clientSecret && this.extraParams.client_secret) {\n console.warn(\n `\\`AuthRequest\\` \\`extraParams.client_secret\\` will be overwritten by \\`clientSecret\\`.`\n );\n }\n if (this.codeChallengeMethod && this.extraParams.code_challenge_method) {\n console.warn(\n `\\`AuthRequest\\` \\`extraParams.code_challenge_method\\` will be overwritten by \\`codeChallengeMethod\\`.`\n );\n }\n }\n\n invariant(\n this.codeChallengeMethod !== CodeChallengeMethod.Plain,\n `\\`AuthRequest\\` does not support \\`CodeChallengeMethod.Plain\\` as it's not secure.`\n );\n invariant(\n this.redirectUri,\n `\\`AuthRequest\\` requires a valid \\`redirectUri\\`. Ex: ${Platform.select({\n web: 'https://yourwebsite.com/',\n default: 'com.your.app:/oauthredirect',\n })}`\n );\n }\n\n /**\n * Load and return a valid auth request based on the input config.\n */\n async getAuthRequestConfigAsync(): Promise<AuthRequestConfig> {\n if (this.usePKCE) {\n await this.ensureCodeIsSetupAsync();\n }\n\n return {\n responseType: this.responseType,\n clientId: this.clientId,\n redirectUri: this.redirectUri,\n scopes: this.scopes,\n clientSecret: this.clientSecret,\n codeChallenge: this.codeChallenge,\n codeChallengeMethod: this.codeChallengeMethod,\n prompt: this.prompt,\n state: this.state,\n extraParams: this.extraParams,\n usePKCE: this.usePKCE,\n };\n }\n\n /**\n * Prompt a user to authorize for a code.\n *\n * @param discovery\n * @param promptOptions\n */\n async promptAsync(\n discovery: AuthDiscoveryDocument,\n { url, ...options }: AuthRequestPromptOptions = {}\n ): Promise<AuthSessionResult> {\n if (!url) {\n if (!this.url) {\n // Generate a new url\n return this.promptAsync(discovery, {\n ...options,\n url: await this.makeAuthUrlAsync(discovery),\n });\n }\n // Reuse the preloaded url\n url = this.url;\n }\n\n // Prevent accidentally starting to an empty url\n invariant(\n url,\n 'No authUrl provided to AuthSession.startAsync. An authUrl is required -- it points to the page where the user will be able to sign in.'\n );\n\n const startUrl: string = url!;\n const returnUrl: string = this.redirectUri;\n\n // Prevent multiple sessions from running at the same time, WebBrowser doesn't\n // support it this makes the behavior predictable.\n if (_authLock) {\n if (__DEV__) {\n console.warn(\n 'Attempted to call AuthSession.startAsync multiple times while already active. Only one AuthSession can be active at any given time.'\n );\n }\n\n return { type: 'locked' };\n }\n\n // About to start session, set lock\n _authLock = true;\n\n let result: WebBrowser.WebBrowserAuthSessionResult;\n try {\n result = await WebBrowser.openAuthSessionAsync(startUrl, returnUrl, options);\n } finally {\n _authLock = false;\n }\n\n if (result.type === 'opened') {\n // This should never happen\n throw new Error('An unexpected error occurred');\n }\n if (result.type !== 'success') {\n return { type: result.type };\n }\n\n return this.parseReturnUrl(result.url);\n }\n\n parseReturnUrl(url: string): AuthSessionResult {\n const { params, errorCode } = QueryParams.getQueryParams(url);\n const { state, error = errorCode } = params;\n\n let parsedError: AuthError | null = null;\n let authentication: TokenResponse | null = null;\n if (state !== this.state) {\n // This is a non-standard error\n parsedError = new AuthError({\n error: 'state_mismatch',\n error_description:\n 'Cross-Site request verification failed. Cached state and returned state do not match.',\n });\n } else if (error) {\n parsedError = new AuthError({ error, ...params });\n }\n if (params.access_token) {\n authentication = TokenResponse.fromQueryParams(params);\n }\n\n return {\n type: parsedError ? 'error' : 'success',\n error: parsedError,\n url,\n params,\n authentication,\n\n // Return errorCode for legacy\n errorCode,\n };\n }\n\n /**\n * Create the URL for authorization.\n *\n * @param discovery\n */\n async makeAuthUrlAsync(discovery: AuthDiscoveryDocument): Promise<string> {\n const request = await this.getAuthRequestConfigAsync();\n if (!request.state) throw new Error('Cannot make request URL without a valid `state` loaded');\n\n // Create a query string\n const params: Record<string, string> = {};\n\n if (request.codeChallenge) {\n params.code_challenge = request.codeChallenge;\n }\n\n // copy over extra params\n for (const extra in request.extraParams) {\n if (extra in request.extraParams) {\n params[extra] = request.extraParams[extra];\n }\n }\n\n if (request.usePKCE && request.codeChallengeMethod) {\n params.code_challenge_method = request.codeChallengeMethod;\n }\n\n if (request.clientSecret) {\n params.client_secret = request.clientSecret;\n }\n\n if (request.prompt) {\n params.prompt = request.prompt;\n }\n\n // These overwrite any extra params\n params.redirect_uri = request.redirectUri;\n params.client_id = request.clientId;\n params.response_type = request.responseType!;\n params.state = request.state;\n\n if (request.scopes?.length) {\n params.scope = request.scopes.join(' ');\n }\n\n // Store the URL for later\n this.url = `${discovery.authorizationEndpoint}?${new URLSearchParams(params)}`;\n return this.url;\n }\n\n private async ensureCodeIsSetupAsync(): Promise<void> {\n if (this.codeVerifier) {\n return;\n }\n\n // This method needs to be resolved like all other native methods.\n const { codeVerifier, codeChallenge } = await PKCE.buildCodeAsync();\n\n this.codeVerifier = codeVerifier;\n this.codeChallenge = codeChallenge;\n }\n}\n"]}
|
package/build/Fetch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Fetch.d.ts","sourceRoot":"","sources":["../src/Fetch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Fetch.d.ts","sourceRoot":"","sources":["../src/Fetch.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AASF,wBAAsB,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAiDhG"}
|
package/build/Fetch.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Platform } from 'expo-modules-core';
|
|
2
|
-
import qs from 'qs';
|
|
3
2
|
// TODO(Bacon): pending react-native-adapter publish after sdk 38
|
|
4
3
|
const isDOMAvailable = Platform.OS === 'web' &&
|
|
5
4
|
typeof window !== 'undefined' &&
|
|
@@ -26,7 +25,7 @@ export async function requestAsync(requestUrl, fetchRequest) {
|
|
|
26
25
|
}
|
|
27
26
|
if (fetchRequest.body) {
|
|
28
27
|
if (fetchRequest.method?.toUpperCase() === 'POST') {
|
|
29
|
-
request.body =
|
|
28
|
+
request.body = new URLSearchParams(fetchRequest.body).toString();
|
|
30
29
|
}
|
|
31
30
|
else {
|
|
32
31
|
for (const key of Object.keys(fetchRequest.body)) {
|
package/build/Fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Fetch.js","sourceRoot":"","sources":["../src/Fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"Fetch.js","sourceRoot":"","sources":["../src/Fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAe7C,iEAAiE;AACjE,MAAM,cAAc,GAClB,QAAQ,CAAC,EAAE,KAAK,KAAK;IACrB,OAAO,MAAM,KAAK,WAAW;IAC7B,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,aAAa;IAChC,OAAO,GAAG,KAAK,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,UAAkB,EAAE,YAA0B;IAClF,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,cAAc,EAAE;QAC5C,aAAa;QACb,OAAO;KACR;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAEhC,MAAM,OAAO,GAA4D;QACvE,MAAM,EAAE,YAAY,CAAC,MAAM;QAC3B,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,EAAE;KACZ,CAAC;IAEF,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,MAAM,CAAC;IAEvE,IAAI,YAAY,CAAC,OAAO,EAAE;QACxB,KAAK,MAAM,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE;YACpC,IAAI,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE;gBAC7B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAW,CAAC;aACxD;SACF;KACF;IAED,IAAI,YAAY,CAAC,IAAI,EAAE;QACrB,IAAI,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,MAAM,EAAE;YACjD,OAAO,CAAC,IAAI,GAAG,IAAI,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;SAClE;aAAM;YACL,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE;gBAChD,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;aACtD;SACF;KACF;IAED,IAAI,cAAc,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QACpD,kFAAkF;QAClF,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,2CAA2C,CAAC;KACzE;IAED,8EAA8E;IAC9E,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAEvD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEpD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACzD,IAAI,cAAc,IAAI,WAAW,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QAC/D,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;KACxB;IACD,2DAA2D;IAC3D,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC","sourcesContent":["import { Platform } from 'expo-modules-core';\n\nexport type Headers = Record<string, string> & {\n 'Content-Type': string;\n Authorization?: string;\n Accept?: string;\n};\n\nexport type FetchRequest = {\n headers?: Headers;\n body?: Record<string, string>;\n dataType?: string;\n method?: string;\n};\n\n// TODO(Bacon): pending react-native-adapter publish after sdk 38\nconst isDOMAvailable =\n Platform.OS === 'web' &&\n typeof window !== 'undefined' &&\n !!window.document?.createElement &&\n typeof URL !== 'undefined';\n\nexport async function requestAsync<T>(requestUrl: string, fetchRequest: FetchRequest): Promise<T> {\n if (Platform.OS === 'web' && !isDOMAvailable) {\n // @ts-ignore\n return;\n }\n const url = new URL(requestUrl);\n\n const request: Omit<RequestInit, 'headers'> & { headers: HeadersInit } = {\n method: fetchRequest.method,\n mode: 'cors',\n headers: {},\n };\n\n const isJsonDataType = fetchRequest.dataType?.toLowerCase() === 'json';\n\n if (fetchRequest.headers) {\n for (const i in fetchRequest.headers) {\n if (i in fetchRequest.headers) {\n request.headers[i] = fetchRequest.headers[i] as string;\n }\n }\n }\n\n if (fetchRequest.body) {\n if (fetchRequest.method?.toUpperCase() === 'POST') {\n request.body = new URLSearchParams(fetchRequest.body).toString();\n } else {\n for (const key of Object.keys(fetchRequest.body)) {\n url.searchParams.append(key, fetchRequest.body[key]);\n }\n }\n }\n\n if (isJsonDataType && !('Accept' in request.headers)) {\n // NOTE: Github authentication will return XML if this includes the standard `*/*`\n request.headers['Accept'] = 'application/json, text/javascript; q=0.01';\n }\n\n // Fix a problem with React Native `URL` causing a trailing slash to be added.\n const correctedUrl = url.toString().replace(/\\/$/, '');\n\n const response = await fetch(correctedUrl, request);\n\n const contentType = response.headers.get('content-type');\n if (isJsonDataType || contentType?.includes('application/json')) {\n return response.json();\n }\n // @ts-ignore: Type 'string' is not assignable to type 'T'.\n return response.text();\n}\n"]}
|
package/build/QueryParams.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryParams.d.ts","sourceRoot":"","sources":["../src/QueryParams.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QueryParams.d.ts","sourceRoot":"","sources":["../src/QueryParams.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG;IAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACnC,CAuBA"}
|
package/build/QueryParams.js
CHANGED
|
@@ -1,29 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export function buildQueryString(input) {
|
|
4
|
-
return qs.stringify(input);
|
|
5
|
-
}
|
|
6
|
-
export function getQueryParams(url) {
|
|
7
|
-
const parts = url.split('#');
|
|
8
|
-
const hash = parts[1];
|
|
9
|
-
const partsWithoutHash = parts[0].split('?');
|
|
10
|
-
const queryString = partsWithoutHash[partsWithoutHash.length - 1];
|
|
11
|
-
// Get query string (?hello=world)
|
|
12
|
-
const parsedSearch = qs.parse(queryString, { parseArrays: false });
|
|
1
|
+
export function getQueryParams(input) {
|
|
2
|
+
const url = new URL(input, 'https://phony.example');
|
|
13
3
|
// Pull errorCode off of params
|
|
14
|
-
const errorCode = (
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
const errorCode = url.searchParams.get('errorCode');
|
|
5
|
+
url.searchParams.delete('errorCode');
|
|
6
|
+
// Merge search and hash
|
|
7
|
+
const params = Object.fromEntries(
|
|
8
|
+
// @ts-ignore: [Symbol.iterator] is indeed, available on every platform.
|
|
9
|
+
url.searchParams);
|
|
17
10
|
// Get hash (#abc=example)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
if (url.hash) {
|
|
12
|
+
new URLSearchParams(url.hash.replace(/^#/, '')).forEach((value, key) => {
|
|
13
|
+
params[key] = value;
|
|
14
|
+
});
|
|
21
15
|
}
|
|
22
|
-
// Merge search and hash
|
|
23
|
-
const params = {
|
|
24
|
-
...parsedSearch,
|
|
25
|
-
...parsedHash,
|
|
26
|
-
};
|
|
27
16
|
return {
|
|
28
17
|
errorCode,
|
|
29
18
|
params,
|
package/build/QueryParams.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryParams.js","sourceRoot":"","sources":["../src/QueryParams.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"QueryParams.js","sourceRoot":"","sources":["../src/QueryParams.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,KAAa;IAI1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC;IAEpD,+BAA+B;IAC/B,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACpD,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAErC,wBAAwB;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW;IAC/B,wEAAwE;IACxE,GAAG,CAAC,YAAY,CACjB,CAAC;IACF,0BAA0B;IAC1B,IAAI,GAAG,CAAC,IAAI,EAAE;QACZ,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACrE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC,CAAC,CAAC;KACJ;IAED,OAAO;QACL,SAAS;QACT,MAAM;KACP,CAAC;AACJ,CAAC","sourcesContent":["export function getQueryParams(input: string): {\n errorCode: string | null;\n params: { [key: string]: string };\n} {\n const url = new URL(input, 'https://phony.example');\n\n // Pull errorCode off of params\n const errorCode = url.searchParams.get('errorCode');\n url.searchParams.delete('errorCode');\n\n // Merge search and hash\n const params = Object.fromEntries(\n // @ts-ignore: [Symbol.iterator] is indeed, available on every platform.\n url.searchParams\n );\n // Get hash (#abc=example)\n if (url.hash) {\n new URLSearchParams(url.hash.replace(/^#/, '')).forEach((value, key) => {\n params[key] = value;\n });\n }\n\n return {\n errorCode,\n params,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionUrlProvider.d.ts","sourceRoot":"","sources":["../src/SessionUrlProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"SessionUrlProvider.d.ts","sourceRoot":"","sources":["../src/SessionUrlProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AAGxC,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAuB;IAE3D,mBAAmB,CACjB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,aAAa,CAAC,GACtD,MAAM;IAeT,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM;IAahG,cAAc,CAAC,OAAO,EAAE;QAAE,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;IA4CnF,OAAO,CAAC,MAAM,CAAC,yBAAyB;IA+BxC,OAAO,CAAC,MAAM,CAAC,eAAe;IAQ9B,OAAO,CAAC,MAAM,CAAC,YAAY;IAI3B,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAGlC;;AAED,wBAAwC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Constants, { ExecutionEnvironment } from 'expo-constants';
|
|
2
2
|
import * as Linking from 'expo-linking';
|
|
3
3
|
import { Platform } from 'expo-modules-core';
|
|
4
|
-
import qs from 'qs';
|
|
5
4
|
export class SessionUrlProvider {
|
|
6
5
|
static BASE_URL = `https://auth.expo.io`;
|
|
7
6
|
static SESSION_PATH = 'expo-auth-session';
|
|
@@ -23,7 +22,7 @@ export class SessionUrlProvider {
|
|
|
23
22
|
// Return nothing in SSR envs
|
|
24
23
|
return '';
|
|
25
24
|
}
|
|
26
|
-
const queryString =
|
|
25
|
+
const queryString = new URLSearchParams({
|
|
27
26
|
authUrl,
|
|
28
27
|
returnUrl,
|
|
29
28
|
});
|
|
@@ -85,7 +84,9 @@ export class SessionUrlProvider {
|
|
|
85
84
|
}
|
|
86
85
|
const uriParts = hostUri?.split('?');
|
|
87
86
|
try {
|
|
88
|
-
return
|
|
87
|
+
return Object.fromEntries(
|
|
88
|
+
// @ts-ignore: [Symbol.iterator] is indeed, available on every platform.
|
|
89
|
+
new URLSearchParams(uriParts?.[1]));
|
|
89
90
|
}
|
|
90
91
|
catch { }
|
|
91
92
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionUrlProvider.js","sourceRoot":"","sources":["../src/SessionUrlProvider.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,EAAE,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"SessionUrlProvider.js","sourceRoot":"","sources":["../src/SessionUrlProvider.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,EAAE,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,MAAM,OAAO,kBAAkB;IACrB,MAAM,CAAU,QAAQ,GAAG,sBAAsB,CAAC;IAClD,MAAM,CAAU,YAAY,GAAG,mBAAmB,CAAC;IAE3D,mBAAmB,CACjB,OAAgB,EAChB,OAAuD;QAEvD,MAAM,WAAW,GAAG,kBAAkB,CAAC,yBAAyB,EAAE,CAAC;QACnE,IAAI,IAAI,GAAG,kBAAkB,CAAC,YAAY,CAAC;QAC3C,IAAI,OAAO,EAAE;YACX,IAAI,GAAG,CAAC,IAAI,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SACzF;QAED,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE;YAC7B,sGAAsG;YACtG,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACpE,WAAW;YACX,eAAe,EAAE,OAAO,EAAE,eAAe;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,OAAe,EAAE,SAAiB,EAAE,mBAAuC;QACrF,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;YACrD,6BAA6B;YAC7B,OAAO,EAAE,CAAC;SACX;QACD,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC;YACtC,OAAO;YACP,SAAS;SACV,CAAC,CAAC;QAEH,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC,UAAU,WAAW,EAAE,CAAC;IAChF,CAAC;IAED,cAAc,CAAC,OAA2D;QACxE,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;YACzB,IAAI,QAAQ,CAAC,cAAc,EAAE;gBAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aAC5E;iBAAM;gBACL,6BAA6B;gBAC7B,OAAO,EAAE,CAAC;aACX;SACF;QAED,MAAM,yBAAyB,GAC7B,OAAO,CAAC,mBAAmB,IAAI,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC;QAExE,IAAI,CAAC,yBAAyB,EAAE;YAC9B,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,IAAI,OAAO,EAAE;gBACX,IAAI,SAAS,CAAC,oBAAoB,KAAK,oBAAoB,CAAC,IAAI,EAAE;oBAChE,SAAS;wBACP,uNAAuN,CAAC;iBAC3N;qBAAM,IAAI,SAAS,CAAC,oBAAoB,KAAK,oBAAoB,CAAC,WAAW,EAAE;oBAC9E,SAAS;wBACP,gFAAgF,CAAC;iBACpF;aACF;YAED,IAAI,SAAS,CAAC,SAAS,EAAE;gBACvB,SAAS;oBACP,+FAA+F;wBAC/F,6HAA6H,CAAC;aACjI;YAED,MAAM,IAAI,KAAK,CACb,gFAAgF,GAAG,SAAS,CAC7F,CAAC;SACH;QAED,MAAM,WAAW,GAAG,GAAG,kBAAkB,CAAC,QAAQ,IAAI,yBAAyB,EAAE,CAAC;QAClF,IAAI,OAAO,EAAE;YACX,kBAAkB,CAAC,eAAe,CAAC,yBAAyB,EAAE,WAAW,CAAC,CAAC;YAC3E,oEAAoE;SACrE;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAEO,MAAM,CAAC,yBAAyB;QACtC,IAAI,OAAO,GAAuB,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC;QAChE,IACE,CAAC,OAAO;YACR,CAAC,oBAAoB,CAAC,WAAW,KAAK,SAAS,CAAC,oBAAoB;gBAClE,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,EAC5B;YACA,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;gBACzB,OAAO,GAAG,EAAE,CAAC;aACd;iBAAM;gBACL,mEAAmE;gBACnE,gFAAgF;gBAChF,OAAO,GAAG,kBAAkB,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;aAC7F;SACF;QAED,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,QAAQ,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI;YACF,OAAO,MAAM,CAAC,WAAW;YACvB,wEAAwE;YACxE,IAAI,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CACnC,CAAC;SACH;QAAC,MAAM,GAAE;QAEV,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,GAAG;QACpC,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;YAChC,OAAO,CAAC,IAAI,CACV,+HAA+H,GAAG,6TAA6T,CAChc,CAAC;SACH;IACH,CAAC;IAEO,MAAM,CAAC,YAAY,CAAC,GAAW;QACrC,OAAO,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC;IAEO,MAAM,CAAC,kBAAkB,CAAC,GAAW;QAC3C,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC;;AAGH,eAAe,IAAI,kBAAkB,EAAE,CAAC","sourcesContent":["import Constants, { ExecutionEnvironment } from 'expo-constants';\nimport * as Linking from 'expo-linking';\nimport { Platform } from 'expo-modules-core';\n\nexport class SessionUrlProvider {\n private static readonly BASE_URL = `https://auth.expo.io`;\n private static readonly SESSION_PATH = 'expo-auth-session';\n\n getDefaultReturnUrl(\n urlPath?: string,\n options?: Omit<Linking.CreateURLOptions, 'queryParams'>\n ): string {\n const queryParams = SessionUrlProvider.getHostAddressQueryParams();\n let path = SessionUrlProvider.SESSION_PATH;\n if (urlPath) {\n path = [path, SessionUrlProvider.removeLeadingSlash(urlPath)].filter(Boolean).join('/');\n }\n\n return Linking.createURL(path, {\n // The redirect URL doesn't matter for the proxy as long as it's valid, so silence warnings if needed.\n scheme: options?.scheme ?? Linking.resolveScheme({ isSilent: true }),\n queryParams,\n isTripleSlashed: options?.isTripleSlashed,\n });\n }\n\n getStartUrl(authUrl: string, returnUrl: string, projectNameForProxy: string | undefined): string {\n if (Platform.OS === 'web' && !Platform.isDOMAvailable) {\n // Return nothing in SSR envs\n return '';\n }\n const queryString = new URLSearchParams({\n authUrl,\n returnUrl,\n });\n\n return `${this.getRedirectUrl({ projectNameForProxy })}/start?${queryString}`;\n }\n\n getRedirectUrl(options: { projectNameForProxy?: string; urlPath?: string }): string {\n if (Platform.OS === 'web') {\n if (Platform.isDOMAvailable) {\n return [window.location.origin, options.urlPath].filter(Boolean).join('/');\n } else {\n // Return nothing in SSR envs\n return '';\n }\n }\n\n const legacyExpoProjectFullName =\n options.projectNameForProxy || Constants.expoConfig?.originalFullName;\n\n if (!legacyExpoProjectFullName) {\n let nextSteps = '';\n if (__DEV__) {\n if (Constants.executionEnvironment === ExecutionEnvironment.Bare) {\n nextSteps =\n ' Please ensure you have the latest version of expo-constants installed and rebuild your native app. You can verify that originalFullName is defined by running `expo config --type public` and inspecting the output.';\n } else if (Constants.executionEnvironment === ExecutionEnvironment.StoreClient) {\n nextSteps =\n ' Please report this as a bug with the contents of `expo config --type public`.';\n }\n }\n\n if (Constants.manifest2) {\n nextSteps =\n ' Prefer AuthRequest in combination with an Expo Development Client build of your application.' +\n ' To continue using the AuthSession proxy, specify the project full name (@owner/slug) using the projectNameForProxy option.';\n }\n\n throw new Error(\n 'Cannot use the AuthSession proxy because the project full name is not defined.' + nextSteps\n );\n }\n\n const redirectUrl = `${SessionUrlProvider.BASE_URL}/${legacyExpoProjectFullName}`;\n if (__DEV__) {\n SessionUrlProvider.warnIfAnonymous(legacyExpoProjectFullName, redirectUrl);\n // TODO: Verify with the dev server that the manifest is up to date.\n }\n return redirectUrl;\n }\n\n private static getHostAddressQueryParams(): Record<string, string> | undefined {\n let hostUri: string | undefined = Constants.expoConfig?.hostUri;\n if (\n !hostUri &&\n (ExecutionEnvironment.StoreClient === Constants.executionEnvironment ||\n Linking.resolveScheme({}))\n ) {\n if (!Constants.linkingUri) {\n hostUri = '';\n } else {\n // we're probably not using up-to-date xdl, so just fake it for now\n // we have to remove the /--/ on the end since this will be inserted again later\n hostUri = SessionUrlProvider.removeScheme(Constants.linkingUri).replace(/\\/--(\\/.*)?$/, '');\n }\n }\n\n if (!hostUri) {\n return undefined;\n }\n\n const uriParts = hostUri?.split('?');\n try {\n return Object.fromEntries(\n // @ts-ignore: [Symbol.iterator] is indeed, available on every platform.\n new URLSearchParams(uriParts?.[1])\n );\n } catch {}\n\n return undefined;\n }\n\n private static warnIfAnonymous(id, url): void {\n if (id.startsWith('@anonymous/')) {\n console.warn(\n `You are not currently signed in to Expo on your development machine. As a result, the redirect URL for AuthSession will be \"${url}\". If you are using an OAuth provider that requires adding redirect URLs to an allow list, we recommend that you do not add this URL -- instead, you should sign in to Expo to acquire a unique redirect URL. Additionally, if you do decide to publish this app using Expo, you will need to register an account to do it.`\n );\n }\n }\n\n private static removeScheme(url: string) {\n return url.replace(/^[a-zA-Z0-9+.-]+:\\/\\//, '');\n }\n\n private static removeLeadingSlash(url: string) {\n return url.replace(/^\\//, '');\n }\n}\n\nexport default new SessionUrlProvider();\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-auth-session",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "Expo module for browser-based authentication",
|
|
5
5
|
"main": "build/AuthSession.js",
|
|
6
6
|
"types": "build/AuthSession.d.ts",
|
|
@@ -34,19 +34,17 @@
|
|
|
34
34
|
"license": "MIT",
|
|
35
35
|
"homepage": "https://docs.expo.dev/versions/latest/sdk/auth-session",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"expo-constants": "~15.
|
|
38
|
-
"expo-crypto": "~12.
|
|
39
|
-
"expo-linking": "~6.
|
|
40
|
-
"expo-web-browser": "~12.
|
|
41
|
-
"invariant": "^2.2.4"
|
|
42
|
-
"qs": "^6.11.0"
|
|
37
|
+
"expo-constants": "~15.3.0",
|
|
38
|
+
"expo-crypto": "~12.8.0",
|
|
39
|
+
"expo-linking": "~6.2.0",
|
|
40
|
+
"expo-web-browser": "~12.8.0",
|
|
41
|
+
"invariant": "^2.2.4"
|
|
43
42
|
},
|
|
44
43
|
"devDependencies": {
|
|
45
|
-
"@types/qs": "^6.9.7",
|
|
46
44
|
"expo-module-scripts": "^3.0.0"
|
|
47
45
|
},
|
|
48
46
|
"jest": {
|
|
49
47
|
"preset": "expo-module-scripts"
|
|
50
48
|
},
|
|
51
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "3142a086578deffd8704a8f1b6f0f661527d836c"
|
|
52
50
|
}
|
package/src/AuthRequest.ts
CHANGED
|
@@ -272,9 +272,8 @@ export class AuthRequest implements Omit<AuthRequestConfig, 'state'> {
|
|
|
272
272
|
params.scope = request.scopes.join(' ');
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
const query = QueryParams.buildQueryString(params);
|
|
276
275
|
// Store the URL for later
|
|
277
|
-
this.url = `${discovery.authorizationEndpoint}?${
|
|
276
|
+
this.url = `${discovery.authorizationEndpoint}?${new URLSearchParams(params)}`;
|
|
278
277
|
return this.url;
|
|
279
278
|
}
|
|
280
279
|
|
package/src/Fetch.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Platform } from 'expo-modules-core';
|
|
2
|
-
import qs from 'qs';
|
|
3
2
|
|
|
4
3
|
export type Headers = Record<string, string> & {
|
|
5
4
|
'Content-Type': string;
|
|
@@ -46,7 +45,7 @@ export async function requestAsync<T>(requestUrl: string, fetchRequest: FetchReq
|
|
|
46
45
|
|
|
47
46
|
if (fetchRequest.body) {
|
|
48
47
|
if (fetchRequest.method?.toUpperCase() === 'POST') {
|
|
49
|
-
request.body =
|
|
48
|
+
request.body = new URLSearchParams(fetchRequest.body).toString();
|
|
50
49
|
} else {
|
|
51
50
|
for (const key of Object.keys(fetchRequest.body)) {
|
|
52
51
|
url.searchParams.append(key, fetchRequest.body[key]);
|
package/src/QueryParams.ts
CHANGED
|
@@ -1,42 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
import qs from 'qs';
|
|
3
|
-
|
|
4
|
-
export function buildQueryString(input: Record<string, string>): string {
|
|
5
|
-
return qs.stringify(input);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function getQueryParams(url: string): {
|
|
1
|
+
export function getQueryParams(input: string): {
|
|
9
2
|
errorCode: string | null;
|
|
10
3
|
params: { [key: string]: string };
|
|
11
4
|
} {
|
|
12
|
-
const
|
|
13
|
-
const hash = parts[1];
|
|
14
|
-
const partsWithoutHash = parts[0].split('?');
|
|
15
|
-
const queryString = partsWithoutHash[partsWithoutHash.length - 1];
|
|
16
|
-
|
|
17
|
-
// Get query string (?hello=world)
|
|
18
|
-
const parsedSearch = qs.parse(queryString, { parseArrays: false });
|
|
5
|
+
const url = new URL(input, 'https://phony.example');
|
|
19
6
|
|
|
20
7
|
// Pull errorCode off of params
|
|
21
|
-
const errorCode = (
|
|
22
|
-
|
|
23
|
-
typeof errorCode === 'string' || errorCode === null,
|
|
24
|
-
`The "errorCode" parameter must be a string if specified`
|
|
25
|
-
);
|
|
26
|
-
delete parsedSearch.errorCode;
|
|
8
|
+
const errorCode = url.searchParams.get('errorCode');
|
|
9
|
+
url.searchParams.delete('errorCode');
|
|
27
10
|
|
|
11
|
+
// Merge search and hash
|
|
12
|
+
const params = Object.fromEntries(
|
|
13
|
+
// @ts-ignore: [Symbol.iterator] is indeed, available on every platform.
|
|
14
|
+
url.searchParams
|
|
15
|
+
);
|
|
28
16
|
// Get hash (#abc=example)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
if (url.hash) {
|
|
18
|
+
new URLSearchParams(url.hash.replace(/^#/, '')).forEach((value, key) => {
|
|
19
|
+
params[key] = value;
|
|
20
|
+
});
|
|
32
21
|
}
|
|
33
22
|
|
|
34
|
-
// Merge search and hash
|
|
35
|
-
const params = {
|
|
36
|
-
...parsedSearch,
|
|
37
|
-
...parsedHash,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
23
|
return {
|
|
41
24
|
errorCode,
|
|
42
25
|
params,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Constants, { ExecutionEnvironment } from 'expo-constants';
|
|
2
2
|
import * as Linking from 'expo-linking';
|
|
3
3
|
import { Platform } from 'expo-modules-core';
|
|
4
|
-
import qs, { ParsedQs } from 'qs';
|
|
5
4
|
|
|
6
5
|
export class SessionUrlProvider {
|
|
7
6
|
private static readonly BASE_URL = `https://auth.expo.io`;
|
|
@@ -30,7 +29,7 @@ export class SessionUrlProvider {
|
|
|
30
29
|
// Return nothing in SSR envs
|
|
31
30
|
return '';
|
|
32
31
|
}
|
|
33
|
-
const queryString =
|
|
32
|
+
const queryString = new URLSearchParams({
|
|
34
33
|
authUrl,
|
|
35
34
|
returnUrl,
|
|
36
35
|
});
|
|
@@ -82,7 +81,7 @@ export class SessionUrlProvider {
|
|
|
82
81
|
return redirectUrl;
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
private static getHostAddressQueryParams():
|
|
84
|
+
private static getHostAddressQueryParams(): Record<string, string> | undefined {
|
|
86
85
|
let hostUri: string | undefined = Constants.expoConfig?.hostUri;
|
|
87
86
|
if (
|
|
88
87
|
!hostUri &&
|
|
@@ -104,7 +103,10 @@ export class SessionUrlProvider {
|
|
|
104
103
|
|
|
105
104
|
const uriParts = hostUri?.split('?');
|
|
106
105
|
try {
|
|
107
|
-
return
|
|
106
|
+
return Object.fromEntries(
|
|
107
|
+
// @ts-ignore: [Symbol.iterator] is indeed, available on every platform.
|
|
108
|
+
new URLSearchParams(uriParts?.[1])
|
|
109
|
+
);
|
|
108
110
|
} catch {}
|
|
109
111
|
|
|
110
112
|
return undefined;
|