mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-26 11:21:16 +01:00
702 lines
23 KiB
JavaScript
Generated
702 lines
23 KiB
JavaScript
Generated
"use strict";
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
|
|
// src/index.ts
|
|
var src_exports = {};
|
|
__export(src_exports, {
|
|
plugin: () => plugin
|
|
});
|
|
module.exports = __toCommonJS(src_exports);
|
|
|
|
// src/grants/authorizationCode.ts
|
|
var import_node_crypto = require("node:crypto");
|
|
|
|
// src/getAccessToken.ts
|
|
var import_node_fs = require("node:fs");
|
|
async function getAccessToken(ctx, {
|
|
accessTokenUrl,
|
|
scope,
|
|
params,
|
|
grantType,
|
|
credentialsInBody,
|
|
clientId,
|
|
clientSecret
|
|
}) {
|
|
console.log("Getting access token", accessTokenUrl);
|
|
const httpRequest = {
|
|
method: "POST",
|
|
url: accessTokenUrl,
|
|
bodyType: "application/x-www-form-urlencoded",
|
|
body: {
|
|
form: [
|
|
{ name: "grant_type", value: grantType },
|
|
...params
|
|
]
|
|
},
|
|
headers: [
|
|
{ name: "User-Agent", value: "yaak" },
|
|
{ name: "Accept", value: "application/x-www-form-urlencoded, application/json" },
|
|
{ name: "Content-Type", value: "application/x-www-form-urlencoded" }
|
|
]
|
|
};
|
|
if (scope) httpRequest.body.form.push({ name: "scope", value: scope });
|
|
if (credentialsInBody) {
|
|
httpRequest.body.form.push({ name: "client_id", value: clientId });
|
|
httpRequest.body.form.push({ name: "client_secret", value: clientSecret });
|
|
} else {
|
|
const value = "Basic " + Buffer.from(`${clientId}:${clientSecret}`).toString("base64");
|
|
httpRequest.headers.push({ name: "Authorization", value });
|
|
}
|
|
const resp = await ctx.httpRequest.send({ httpRequest });
|
|
if (resp.status < 200 || resp.status >= 300) {
|
|
throw new Error("Failed to fetch access token with status=" + resp.status);
|
|
}
|
|
const body = (0, import_node_fs.readFileSync)(resp.bodyPath ?? "", "utf8");
|
|
let response;
|
|
try {
|
|
response = JSON.parse(body);
|
|
} catch {
|
|
response = Object.fromEntries(new URLSearchParams(body));
|
|
}
|
|
if (response.error) {
|
|
throw new Error("Failed to fetch access token with " + response.error);
|
|
}
|
|
return response;
|
|
}
|
|
|
|
// src/getOrRefreshAccessToken.ts
|
|
var import_node_fs2 = require("node:fs");
|
|
|
|
// src/store.ts
|
|
async function storeToken(ctx, contextId, response) {
|
|
if (!response.access_token) {
|
|
throw new Error(`Token not found in response`);
|
|
}
|
|
const expiresAt = response.expires_in ? Date.now() + response.expires_in * 1e3 : null;
|
|
const token = {
|
|
response,
|
|
expiresAt
|
|
};
|
|
await ctx.store.set(tokenStoreKey(contextId), token);
|
|
return token;
|
|
}
|
|
async function getToken(ctx, contextId) {
|
|
return ctx.store.get(tokenStoreKey(contextId));
|
|
}
|
|
async function deleteToken(ctx, contextId) {
|
|
return ctx.store.delete(tokenStoreKey(contextId));
|
|
}
|
|
async function resetDataDirKey(ctx, contextId) {
|
|
const key = (/* @__PURE__ */ new Date()).toISOString();
|
|
return ctx.store.set(dataDirStoreKey(contextId), key);
|
|
}
|
|
async function getDataDirKey(ctx, contextId) {
|
|
const key = await ctx.store.get(dataDirStoreKey(contextId)) ?? "default";
|
|
return `${contextId}::${key}`;
|
|
}
|
|
function tokenStoreKey(context_id) {
|
|
return ["token", context_id].join("::");
|
|
}
|
|
function dataDirStoreKey(context_id) {
|
|
return ["data_dir", context_id].join("::");
|
|
}
|
|
|
|
// src/getOrRefreshAccessToken.ts
|
|
async function getOrRefreshAccessToken(ctx, contextId, {
|
|
scope,
|
|
accessTokenUrl,
|
|
credentialsInBody,
|
|
clientId,
|
|
clientSecret,
|
|
forceRefresh
|
|
}) {
|
|
const token = await getToken(ctx, contextId);
|
|
if (token == null) {
|
|
return null;
|
|
}
|
|
const now = Date.now();
|
|
const isExpired = token.expiresAt && now > token.expiresAt;
|
|
if (!isExpired && !forceRefresh) {
|
|
return token;
|
|
}
|
|
if (!token.response.refresh_token) {
|
|
return null;
|
|
}
|
|
const httpRequest = {
|
|
method: "POST",
|
|
url: accessTokenUrl,
|
|
bodyType: "application/x-www-form-urlencoded",
|
|
body: {
|
|
form: [
|
|
{ name: "grant_type", value: "refresh_token" },
|
|
{ name: "refresh_token", value: token.response.refresh_token }
|
|
]
|
|
},
|
|
headers: [
|
|
{ name: "User-Agent", value: "yaak" },
|
|
{ name: "Accept", value: "application/x-www-form-urlencoded, application/json" },
|
|
{ name: "Content-Type", value: "application/x-www-form-urlencoded" }
|
|
]
|
|
};
|
|
if (scope) httpRequest.body.form.push({ name: "scope", value: scope });
|
|
if (credentialsInBody) {
|
|
httpRequest.body.form.push({ name: "client_id", value: clientId });
|
|
httpRequest.body.form.push({ name: "client_secret", value: clientSecret });
|
|
} else {
|
|
const value = "Basic " + Buffer.from(`${clientId}:${clientSecret}`).toString("base64");
|
|
httpRequest.headers.push({ name: "Authorization", value });
|
|
}
|
|
const resp = await ctx.httpRequest.send({ httpRequest });
|
|
if (resp.status === 401) {
|
|
console.log("Unauthorized refresh_token request");
|
|
await deleteToken(ctx, contextId);
|
|
return null;
|
|
}
|
|
if (resp.status < 200 || resp.status >= 300) {
|
|
throw new Error("Failed to fetch access token with status=" + resp.status);
|
|
}
|
|
const body = (0, import_node_fs2.readFileSync)(resp.bodyPath ?? "", "utf8");
|
|
let response;
|
|
try {
|
|
response = JSON.parse(body);
|
|
} catch {
|
|
response = Object.fromEntries(new URLSearchParams(body));
|
|
}
|
|
if (response.error) {
|
|
throw new Error(`Failed to fetch access token with ${response.error} -> ${response.error_description}`);
|
|
}
|
|
const newResponse = {
|
|
...response,
|
|
// Assign a new one or keep the old one,
|
|
refresh_token: response.refresh_token ?? token.response.refresh_token
|
|
};
|
|
return storeToken(ctx, contextId, newResponse);
|
|
}
|
|
|
|
// src/grants/authorizationCode.ts
|
|
var PKCE_SHA256 = "S256";
|
|
var PKCE_PLAIN = "plain";
|
|
var DEFAULT_PKCE_METHOD = PKCE_SHA256;
|
|
async function getAuthorizationCode(ctx, contextId, {
|
|
authorizationUrl: authorizationUrlRaw,
|
|
accessTokenUrl,
|
|
clientId,
|
|
clientSecret,
|
|
redirectUri,
|
|
scope,
|
|
state,
|
|
credentialsInBody,
|
|
pkce
|
|
}) {
|
|
const token = await getOrRefreshAccessToken(ctx, contextId, {
|
|
accessTokenUrl,
|
|
scope,
|
|
clientId,
|
|
clientSecret,
|
|
credentialsInBody
|
|
});
|
|
if (token != null) {
|
|
return token;
|
|
}
|
|
const authorizationUrl = new URL(`${authorizationUrlRaw ?? ""}`);
|
|
authorizationUrl.searchParams.set("response_type", "code");
|
|
authorizationUrl.searchParams.set("client_id", clientId);
|
|
if (redirectUri) authorizationUrl.searchParams.set("redirect_uri", redirectUri);
|
|
if (scope) authorizationUrl.searchParams.set("scope", scope);
|
|
if (state) authorizationUrl.searchParams.set("state", state);
|
|
if (pkce) {
|
|
const verifier = pkce.codeVerifier || createPkceCodeVerifier();
|
|
const challengeMethod = pkce.challengeMethod || DEFAULT_PKCE_METHOD;
|
|
authorizationUrl.searchParams.set("code_challenge", createPkceCodeChallenge(verifier, challengeMethod));
|
|
authorizationUrl.searchParams.set("code_challenge_method", challengeMethod);
|
|
}
|
|
return new Promise(async (resolve, reject) => {
|
|
const authorizationUrlStr = authorizationUrl.toString();
|
|
console.log("Authorizing", authorizationUrlStr);
|
|
let foundCode = false;
|
|
let { close } = await ctx.window.openUrl({
|
|
url: authorizationUrlStr,
|
|
label: "oauth-authorization-url",
|
|
dataDirKey: await getDataDirKey(ctx, contextId),
|
|
async onClose() {
|
|
if (!foundCode) {
|
|
reject(new Error("Authorization window closed"));
|
|
}
|
|
},
|
|
async onNavigate({ url: urlStr }) {
|
|
const url = new URL(urlStr);
|
|
if (url.searchParams.has("error")) {
|
|
return reject(new Error(`Failed to authorize: ${url.searchParams.get("error")}`));
|
|
}
|
|
const code = url.searchParams.get("code");
|
|
if (!code) {
|
|
return;
|
|
}
|
|
foundCode = true;
|
|
close();
|
|
const response = await getAccessToken(ctx, {
|
|
grantType: "authorization_code",
|
|
accessTokenUrl,
|
|
clientId,
|
|
clientSecret,
|
|
scope,
|
|
credentialsInBody,
|
|
params: [
|
|
{ name: "code", value: code },
|
|
...redirectUri ? [{ name: "redirect_uri", value: redirectUri }] : []
|
|
]
|
|
});
|
|
try {
|
|
resolve(await storeToken(ctx, contextId, response));
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function createPkceCodeVerifier() {
|
|
return encodeForPkce((0, import_node_crypto.randomBytes)(32));
|
|
}
|
|
function createPkceCodeChallenge(verifier, method) {
|
|
if (method === "plain") {
|
|
return verifier;
|
|
}
|
|
const hash = encodeForPkce((0, import_node_crypto.createHash)("sha256").update(verifier).digest());
|
|
return hash.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
}
|
|
function encodeForPkce(bytes) {
|
|
return bytes.toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
}
|
|
|
|
// src/grants/clientCredentials.ts
|
|
async function getClientCredentials(ctx, contextId, {
|
|
accessTokenUrl,
|
|
clientId,
|
|
clientSecret,
|
|
scope,
|
|
credentialsInBody
|
|
}) {
|
|
const token = await getToken(ctx, contextId);
|
|
if (token) {
|
|
}
|
|
const response = await getAccessToken(ctx, {
|
|
grantType: "client_credentials",
|
|
accessTokenUrl,
|
|
clientId,
|
|
clientSecret,
|
|
scope,
|
|
credentialsInBody,
|
|
params: []
|
|
});
|
|
return storeToken(ctx, contextId, response);
|
|
}
|
|
|
|
// src/grants/implicit.ts
|
|
function getImplicit(ctx, contextId, {
|
|
authorizationUrl: authorizationUrlRaw,
|
|
responseType,
|
|
clientId,
|
|
redirectUri,
|
|
scope,
|
|
state
|
|
}) {
|
|
return new Promise(async (resolve, reject) => {
|
|
const token = await getToken(ctx, contextId);
|
|
if (token) {
|
|
}
|
|
const authorizationUrl = new URL(`${authorizationUrlRaw ?? ""}`);
|
|
authorizationUrl.searchParams.set("response_type", "code");
|
|
authorizationUrl.searchParams.set("client_id", clientId);
|
|
if (redirectUri) authorizationUrl.searchParams.set("redirect_uri", redirectUri);
|
|
if (scope) authorizationUrl.searchParams.set("scope", scope);
|
|
if (state) authorizationUrl.searchParams.set("state", state);
|
|
if (responseType.includes("id_token")) {
|
|
authorizationUrl.searchParams.set("nonce", String(Math.floor(Math.random() * 9999999999999) + 1));
|
|
}
|
|
const authorizationUrlStr = authorizationUrl.toString();
|
|
let { close } = await ctx.window.openUrl({
|
|
url: authorizationUrlStr,
|
|
label: "oauth-authorization-url",
|
|
async onNavigate({ url: urlStr }) {
|
|
const url = new URL(urlStr);
|
|
if (url.searchParams.has("error")) {
|
|
return reject(Error(`Failed to authorize: ${url.searchParams.get("error")}`));
|
|
}
|
|
close();
|
|
const hash = url.hash.slice(1);
|
|
const params = new URLSearchParams(hash);
|
|
const idToken = params.get("id_token");
|
|
if (idToken) {
|
|
params.set("access_token", idToken);
|
|
params.delete("id_token");
|
|
}
|
|
const response = Object.fromEntries(params);
|
|
try {
|
|
resolve(await storeToken(ctx, contextId, response));
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// src/grants/password.ts
|
|
async function getPassword(ctx, contextId, {
|
|
accessTokenUrl,
|
|
clientId,
|
|
clientSecret,
|
|
username,
|
|
password,
|
|
credentialsInBody,
|
|
scope
|
|
}) {
|
|
const token = await getOrRefreshAccessToken(ctx, contextId, {
|
|
accessTokenUrl,
|
|
scope,
|
|
clientId,
|
|
clientSecret,
|
|
credentialsInBody
|
|
});
|
|
if (token != null) {
|
|
return token;
|
|
}
|
|
const response = await getAccessToken(ctx, {
|
|
accessTokenUrl,
|
|
clientId,
|
|
clientSecret,
|
|
scope,
|
|
grantType: "password",
|
|
credentialsInBody,
|
|
params: [
|
|
{ name: "username", value: username },
|
|
{ name: "password", value: password }
|
|
]
|
|
});
|
|
return storeToken(ctx, contextId, response);
|
|
}
|
|
|
|
// src/index.ts
|
|
var grantTypes = [
|
|
{ label: "Authorization Code", value: "authorization_code" },
|
|
{ label: "Implicit", value: "implicit" },
|
|
{ label: "Resource Owner Password Credential", value: "password" },
|
|
{ label: "Client Credentials", value: "client_credentials" }
|
|
];
|
|
var defaultGrantType = grantTypes[0].value;
|
|
function hiddenIfNot(grantTypes2, ...other) {
|
|
return (_ctx, { values }) => {
|
|
const hasGrantType = grantTypes2.find((t) => t === String(values.grantType ?? defaultGrantType));
|
|
const hasOtherBools = other.every((t) => t(values));
|
|
const show = hasGrantType && hasOtherBools;
|
|
return { hidden: !show };
|
|
};
|
|
}
|
|
var authorizationUrls = [
|
|
"https://github.com/login/oauth/authorize",
|
|
"https://account.box.com/api/oauth2/authorize",
|
|
"https://accounts.google.com/o/oauth2/v2/auth",
|
|
"https://api.imgur.com/oauth2/authorize",
|
|
"https://bitly.com/oauth/authorize",
|
|
"https://gitlab.example.com/oauth/authorize",
|
|
"https://medium.com/m/oauth/authorize",
|
|
"https://public-api.wordpress.com/oauth2/authorize",
|
|
"https://slack.com/oauth/authorize",
|
|
"https://todoist.com/oauth/authorize",
|
|
"https://www.dropbox.com/oauth2/authorize",
|
|
"https://www.linkedin.com/oauth/v2/authorization",
|
|
"https://MY_SHOP.myshopify.com/admin/oauth/access_token"
|
|
];
|
|
var accessTokenUrls = [
|
|
"https://github.com/login/oauth/access_token",
|
|
"https://api-ssl.bitly.com/oauth/access_token",
|
|
"https://api.box.com/oauth2/token",
|
|
"https://api.dropboxapi.com/oauth2/token",
|
|
"https://api.imgur.com/oauth2/token",
|
|
"https://api.medium.com/v1/tokens",
|
|
"https://gitlab.example.com/oauth/token",
|
|
"https://public-api.wordpress.com/oauth2/token",
|
|
"https://slack.com/api/oauth.access",
|
|
"https://todoist.com/oauth/access_token",
|
|
"https://www.googleapis.com/oauth2/v4/token",
|
|
"https://www.linkedin.com/oauth/v2/accessToken",
|
|
"https://MY_SHOP.myshopify.com/admin/oauth/authorize"
|
|
];
|
|
var plugin = {
|
|
authentication: {
|
|
name: "oauth2",
|
|
label: "OAuth 2.0",
|
|
shortLabel: "OAuth 2",
|
|
actions: [
|
|
{
|
|
label: "Copy Current Token",
|
|
async onSelect(ctx, { contextId }) {
|
|
const token = await getToken(ctx, contextId);
|
|
if (token == null) {
|
|
await ctx.toast.show({ message: "No token to copy", color: "warning" });
|
|
} else {
|
|
await ctx.clipboard.copyText(token.response.access_token);
|
|
await ctx.toast.show({ message: "Token copied to clipboard", icon: "copy", color: "success" });
|
|
}
|
|
}
|
|
},
|
|
{
|
|
label: "Delete Token",
|
|
async onSelect(ctx, { contextId }) {
|
|
if (await deleteToken(ctx, contextId)) {
|
|
await ctx.toast.show({ message: "Token deleted", color: "success" });
|
|
} else {
|
|
await ctx.toast.show({ message: "No token to delete", color: "warning" });
|
|
}
|
|
}
|
|
},
|
|
{
|
|
label: "Clear Window Session",
|
|
async onSelect(ctx, { contextId }) {
|
|
await resetDataDirKey(ctx, contextId);
|
|
}
|
|
}
|
|
],
|
|
args: [
|
|
{
|
|
type: "select",
|
|
name: "grantType",
|
|
label: "Grant Type",
|
|
hideLabel: true,
|
|
defaultValue: defaultGrantType,
|
|
options: grantTypes
|
|
},
|
|
// Always-present fields
|
|
{
|
|
type: "text",
|
|
name: "clientId",
|
|
label: "Client ID",
|
|
optional: true
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "clientSecret",
|
|
label: "Client Secret",
|
|
optional: true,
|
|
password: true,
|
|
dynamic: hiddenIfNot(["authorization_code", "password", "client_credentials"])
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "authorizationUrl",
|
|
optional: true,
|
|
label: "Authorization URL",
|
|
dynamic: hiddenIfNot(["authorization_code", "implicit"]),
|
|
placeholder: authorizationUrls[0],
|
|
completionOptions: authorizationUrls.map((url) => ({ label: url, value: url }))
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "accessTokenUrl",
|
|
optional: true,
|
|
label: "Access Token URL",
|
|
placeholder: accessTokenUrls[0],
|
|
dynamic: hiddenIfNot(["authorization_code", "password", "client_credentials"]),
|
|
completionOptions: accessTokenUrls.map((url) => ({ label: url, value: url }))
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "redirectUri",
|
|
label: "Redirect URI",
|
|
optional: true,
|
|
dynamic: hiddenIfNot(["authorization_code", "implicit"])
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "state",
|
|
label: "State",
|
|
optional: true,
|
|
dynamic: hiddenIfNot(["authorization_code", "implicit"])
|
|
},
|
|
{
|
|
type: "checkbox",
|
|
name: "usePkce",
|
|
label: "Use PKCE",
|
|
dynamic: hiddenIfNot(["authorization_code"])
|
|
},
|
|
{
|
|
type: "select",
|
|
name: "pkceChallengeMethod",
|
|
label: "Code Challenge Method",
|
|
options: [{ label: "SHA-256", value: PKCE_SHA256 }, { label: "Plain", value: PKCE_PLAIN }],
|
|
defaultValue: DEFAULT_PKCE_METHOD,
|
|
dynamic: hiddenIfNot(["authorization_code"], ({ usePkce }) => !!usePkce)
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "pkceCodeVerifier",
|
|
label: "Code Verifier",
|
|
placeholder: "Automatically generated if not provided",
|
|
optional: true,
|
|
dynamic: hiddenIfNot(["authorization_code"], ({ usePkce }) => !!usePkce)
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "username",
|
|
label: "Username",
|
|
optional: true,
|
|
dynamic: hiddenIfNot(["password"])
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "password",
|
|
label: "Password",
|
|
password: true,
|
|
optional: true,
|
|
dynamic: hiddenIfNot(["password"])
|
|
},
|
|
{
|
|
type: "select",
|
|
name: "responseType",
|
|
label: "Response Type",
|
|
defaultValue: "token",
|
|
options: [
|
|
{ label: "Access Token", value: "token" },
|
|
{ label: "ID Token", value: "id_token" },
|
|
{ label: "ID and Access Token", value: "id_token token" }
|
|
],
|
|
dynamic: hiddenIfNot(["implicit"])
|
|
},
|
|
{
|
|
type: "accordion",
|
|
label: "Advanced",
|
|
inputs: [
|
|
{ type: "text", name: "scope", label: "Scope", optional: true },
|
|
{ type: "text", name: "headerPrefix", label: "Header Prefix", optional: true, defaultValue: "Bearer" },
|
|
{
|
|
type: "select",
|
|
name: "credentials",
|
|
label: "Send Credentials",
|
|
defaultValue: "body",
|
|
options: [
|
|
{ label: "In Request Body", value: "body" },
|
|
{ label: "As Basic Authentication", value: "basic" }
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
type: "accordion",
|
|
label: "Access Token Response",
|
|
async dynamic(ctx, { contextId }) {
|
|
const token = await getToken(ctx, contextId);
|
|
if (token == null) {
|
|
return { hidden: true };
|
|
}
|
|
return {
|
|
label: "Access Token Response",
|
|
inputs: [
|
|
{
|
|
type: "editor",
|
|
defaultValue: JSON.stringify(token.response, null, 2),
|
|
hideLabel: true,
|
|
readOnly: true,
|
|
language: "json"
|
|
}
|
|
]
|
|
};
|
|
}
|
|
}
|
|
],
|
|
async onApply(ctx, { values, contextId }) {
|
|
const headerPrefix = stringArg(values, "headerPrefix");
|
|
const grantType = stringArg(values, "grantType");
|
|
const credentialsInBody = values.credentials === "body";
|
|
let token;
|
|
if (grantType === "authorization_code") {
|
|
const authorizationUrl = stringArg(values, "authorizationUrl");
|
|
const accessTokenUrl = stringArg(values, "accessTokenUrl");
|
|
token = await getAuthorizationCode(ctx, contextId, {
|
|
accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`,
|
|
authorizationUrl: authorizationUrl.match(/^https?:\/\//) ? authorizationUrl : `https://${authorizationUrl}`,
|
|
clientId: stringArg(values, "clientId"),
|
|
clientSecret: stringArg(values, "clientSecret"),
|
|
redirectUri: stringArgOrNull(values, "redirectUri"),
|
|
scope: stringArgOrNull(values, "scope"),
|
|
state: stringArgOrNull(values, "state"),
|
|
credentialsInBody,
|
|
pkce: values.usePkce ? {
|
|
challengeMethod: stringArg(values, "pkceChallengeMethod"),
|
|
codeVerifier: stringArgOrNull(values, "pkceCodeVerifier")
|
|
} : null
|
|
});
|
|
} else if (grantType === "implicit") {
|
|
const authorizationUrl = stringArg(values, "authorizationUrl");
|
|
token = await getImplicit(ctx, contextId, {
|
|
authorizationUrl: authorizationUrl.match(/^https?:\/\//) ? authorizationUrl : `https://${authorizationUrl}`,
|
|
clientId: stringArg(values, "clientId"),
|
|
redirectUri: stringArgOrNull(values, "redirectUri"),
|
|
responseType: stringArg(values, "responseType"),
|
|
scope: stringArgOrNull(values, "scope"),
|
|
state: stringArgOrNull(values, "state")
|
|
});
|
|
} else if (grantType === "client_credentials") {
|
|
const accessTokenUrl = stringArg(values, "accessTokenUrl");
|
|
token = await getClientCredentials(ctx, contextId, {
|
|
accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`,
|
|
clientId: stringArg(values, "clientId"),
|
|
clientSecret: stringArg(values, "clientSecret"),
|
|
scope: stringArgOrNull(values, "scope"),
|
|
credentialsInBody
|
|
});
|
|
} else if (grantType === "password") {
|
|
const accessTokenUrl = stringArg(values, "accessTokenUrl");
|
|
token = await getPassword(ctx, contextId, {
|
|
accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`,
|
|
clientId: stringArg(values, "clientId"),
|
|
clientSecret: stringArg(values, "clientSecret"),
|
|
username: stringArg(values, "username"),
|
|
password: stringArg(values, "password"),
|
|
scope: stringArgOrNull(values, "scope"),
|
|
credentialsInBody
|
|
});
|
|
} else {
|
|
throw new Error("Invalid grant type " + grantType);
|
|
}
|
|
const headerValue = `${headerPrefix} ${token.response.access_token}`.trim();
|
|
return {
|
|
setHeaders: [{
|
|
name: "Authorization",
|
|
value: headerValue
|
|
}]
|
|
};
|
|
}
|
|
}
|
|
};
|
|
function stringArgOrNull(values, name) {
|
|
const arg = values[name];
|
|
if (arg == null || arg == "") return null;
|
|
return `${arg}`;
|
|
}
|
|
function stringArg(values, name) {
|
|
const arg = stringArgOrNull(values, name);
|
|
if (!arg) return "";
|
|
return arg;
|
|
}
|
|
// Annotate the CommonJS export names for ESM import in node:
|
|
0 && (module.exports = {
|
|
plugin
|
|
});
|