mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-12 12:09:37 +02:00
Add .oxfmtignore to skip generated bindings and wasm-pack output. Add npm format script, update DEVELOPMENT.md for Vite+ toolchain, and format all non-generated files with oxfmt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
149 lines
4.1 KiB
TypeScript
149 lines
4.1 KiB
TypeScript
import type { PluginDefinition } from "@yaakapp/api";
|
|
import jwt from "jsonwebtoken";
|
|
|
|
const algorithms = [
|
|
"HS256",
|
|
"HS384",
|
|
"HS512",
|
|
"RS256",
|
|
"RS384",
|
|
"RS512",
|
|
"PS256",
|
|
"PS384",
|
|
"PS512",
|
|
"ES256",
|
|
"ES384",
|
|
"ES512",
|
|
"none",
|
|
] as const;
|
|
|
|
const defaultAlgorithm = algorithms[0];
|
|
|
|
export const plugin: PluginDefinition = {
|
|
authentication: {
|
|
name: "jwt",
|
|
label: "JWT Bearer",
|
|
shortLabel: "JWT",
|
|
args: [
|
|
{
|
|
type: "select",
|
|
name: "algorithm",
|
|
label: "Algorithm",
|
|
hideLabel: true,
|
|
defaultValue: defaultAlgorithm,
|
|
options: algorithms.map((value) => ({ label: value === "none" ? "None" : value, value })),
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "secret",
|
|
label: "Secret or Private Key",
|
|
password: true,
|
|
optional: true,
|
|
multiLine: true,
|
|
},
|
|
{
|
|
type: "checkbox",
|
|
name: "secretBase64",
|
|
label: "Secret is base64 encoded",
|
|
},
|
|
{
|
|
type: "editor",
|
|
name: "payload",
|
|
label: "JWT Payload",
|
|
language: "json",
|
|
defaultValue: '{\n "foo": "bar"\n}',
|
|
placeholder: "{ }",
|
|
},
|
|
{
|
|
type: "accordion",
|
|
label: "Advanced",
|
|
inputs: [
|
|
{
|
|
type: "editor",
|
|
name: "headers",
|
|
label: "JWT Header",
|
|
description: "Merged with auto-generated header fields like alg (e.g., kid)",
|
|
language: "json",
|
|
defaultValue: "{}",
|
|
placeholder: "{ }",
|
|
optional: true,
|
|
},
|
|
{
|
|
type: "select",
|
|
name: "location",
|
|
label: "Behavior",
|
|
defaultValue: "header",
|
|
options: [
|
|
{ label: "Insert Header", value: "header" },
|
|
{ label: "Append Query Parameter", value: "query" },
|
|
],
|
|
},
|
|
{
|
|
type: "h_stack",
|
|
inputs: [
|
|
{
|
|
type: "text",
|
|
name: "name",
|
|
label: "Header Name",
|
|
defaultValue: "Authorization",
|
|
optional: true,
|
|
description: "The name of the header to add to the request",
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "headerPrefix",
|
|
label: "Header Prefix",
|
|
optional: true,
|
|
defaultValue: "Bearer",
|
|
},
|
|
],
|
|
dynamic(_ctx, args) {
|
|
if (args.values.location === "query") {
|
|
return {
|
|
hidden: true,
|
|
};
|
|
}
|
|
},
|
|
},
|
|
{
|
|
type: "text",
|
|
name: "name",
|
|
label: "Parameter Name",
|
|
description: "The name of the query parameter to add to the request",
|
|
defaultValue: "token",
|
|
optional: true,
|
|
dynamic(_ctx, args) {
|
|
if (args.values.location !== "query") {
|
|
return {
|
|
hidden: true,
|
|
};
|
|
}
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
async onApply(_ctx, { values }) {
|
|
const { algorithm, secret: _secret, secretBase64, payload, headers } = values;
|
|
const secret = secretBase64 ? Buffer.from(`${_secret}`, "base64") : `${_secret}`;
|
|
|
|
const parsedHeaders = headers ? JSON.parse(`${headers}`) : undefined;
|
|
|
|
const token = jwt.sign(`${payload}`, secret, {
|
|
algorithm: algorithm as (typeof algorithms)[number],
|
|
// Extra header fields are merged with the auto-generated header (which includes alg)
|
|
header: parsedHeaders as jwt.JwtHeader | undefined,
|
|
});
|
|
|
|
if (values.location === "query") {
|
|
const paramName = String(values.name || "token");
|
|
return { setQueryParameters: [{ name: paramName, value: token }] };
|
|
}
|
|
const headerPrefix = values.headerPrefix != null ? values.headerPrefix : "Bearer";
|
|
const headerName = String(values.name || "Authorization");
|
|
const headerValue = `${headerPrefix} ${token}`.trim();
|
|
return { setHeaders: [{ name: headerName, value: headerValue }] };
|
|
},
|
|
},
|
|
};
|