Files
yaak/plugins/auth-jwt/src/index.ts
Gregory Schier b4a1c418bb Run oxfmt across repo, add format script and docs
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>
2026-03-13 10:15:49 -07:00

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 }] };
},
},
};