UNPKG

@scalar/api-client

Version:

the open source API testing client

98 lines (97 loc) 4.95 kB
import { shouldUseProxy as w } from "@scalar/oas-utils/helpers"; const S = () => { const e = new Uint8Array(32); return crypto.getRandomValues(e), btoa(String.fromCharCode(...e)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); }, x = async (e, l) => { if (l === "plain") return e; const a = new TextEncoder().encode(e), c = await crypto.subtle.digest("SHA-256", a); return btoa(String.fromCharCode(...new Uint8Array(c))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); }, k = async (e, l, d) => { try { if (!e) return [new Error("Flow not found"), null]; const a = e.selectedScopes.join(" "); if (e.type === "clientCredentials" || e.type === "password") return P(e, a, { proxyUrl: d }); const c = (Math.random() + 1).toString(36).substring(2, 10), t = new URL(e.authorizationUrl); let u = null; if (e.type === "implicit") t.searchParams.set("response_type", "token"); else if (e.type === "authorizationCode" && (t.searchParams.set("response_type", "code"), e["x-usePkce"] !== "no")) { const r = S(), n = await x(r, e["x-usePkce"]); u = { codeVerifier: r, codeChallenge: n, codeChallengeMethod: e["x-usePkce"] === "SHA-256" ? "S256" : "plain" }, t.searchParams.set("code_challenge", n), t.searchParams.set("code_challenge_method", u.codeChallengeMethod); } if (e["x-scalar-redirect-uri"].startsWith("/")) { const r = l.url || window.location.origin + window.location.pathname, n = new URL(e["x-scalar-redirect-uri"], r).toString(); t.searchParams.set("redirect_uri", n); } else t.searchParams.set("redirect_uri", e["x-scalar-redirect-uri"]); e["x-scalar-security-query"] && Object.keys(e["x-scalar-security-query"]).forEach((r) => { var i; const n = (i = e["x-scalar-security-query"]) == null ? void 0 : i[r]; n && t.searchParams.set(r, n); }), t.searchParams.set("client_id", e["x-scalar-client-id"]), t.searchParams.set("state", c), a && t.searchParams.set("scope", a); const s = window.open(t, "openAuth2Window", "left=100,top=100,width=800,height=600"); return s ? new Promise((r) => { const n = setInterval(() => { var _; let i = null, h = null, p = null, g = null; try { const o = new URL(s.location.href).searchParams; i = o.get("access_token"), h = o.get("code"), p = o.get("error"), g = o.get("error_description"); const m = new URLSearchParams(s.location.href.split("#")[1]); i || (i = m.get("access_token")), h || (h = m.get("code")), p || (p = m.get("error")), g || (g = m.get("error_description")); } catch { } if (s.closed || i || h || p) if (clearInterval(n), s.close(), p) r([new Error(`OAuth error: ${p}${g ? ` (${g})` : ""}`), null]); else if (i) { const o = (_ = s.location.href.match(/state=([^&]*)/)) == null ? void 0 : _[1]; r(o === c ? [null, i] : [new Error("State mismatch"), null]); } else h ? new URL(s.location.href).searchParams.get("state") === c ? P(e, a, { code: h, pkce: u, proxyUrl: d }).then(r) : r([new Error("State mismatch"), null]) : (clearInterval(n), r([new Error("Window was closed without granting authorization"), null])); }, 200); }) : [new Error("Failed to open auth window"), null]; } catch { return [new Error("Failed to authorize oauth2 flow"), null]; } }, P = async (e, l, { code: d, pkce: a, proxyUrl: c } = {}) => { if (!e) return [new Error("OAuth2 flow was not defined"), null]; const t = new URLSearchParams(); t.set("client_id", e["x-scalar-client-id"]), l && (e.type === "clientCredentials" || e.type === "password") && t.set("scope", l), e.clientSecret && t.set("client_secret", e.clientSecret), "x-scalar-redirect-uri" in e && e["x-scalar-redirect-uri"] && t.set("redirect_uri", e["x-scalar-redirect-uri"]), d ? (t.set("code", d), t.set("grant_type", "authorization_code"), a && t.set("code_verifier", a.codeVerifier)) : e.type === "password" ? (t.set("grant_type", "password"), t.set("username", e.username), t.set("password", e.password)) : t.set("grant_type", "client_credentials"); try { const u = { "Content-Type": "application/x-www-form-urlencoded" }; e.clientSecret && (u.Authorization = `Basic ${btoa(`${e["x-scalar-client-id"]}:${e.clientSecret}`)}`); const y = w(c, e.tokenUrl) ? `${c}?${new URLSearchParams([["scalar_url", e.tokenUrl]]).toString()}` : e.tokenUrl, s = await fetch(y, { method: "POST", headers: u, body: t }), { access_token: r } = await s.json(); return [null, r]; } catch { return [new Error("Failed to get an access token. Please check your credentials."), null]; } }; export { k as authorizeOauth2, P as authorizeServers, x as generateCodeChallenge };