mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-26 19:31:25 +01:00
89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
import { URL } from "node:url";
|
|
import type { PluginDefinition } from "@yaakapp/api";
|
|
import type { CallHttpAuthenticationResponse } from "@yaakapp-internal/plugins";
|
|
import type { Request } from "aws4";
|
|
import aws4 from "aws4";
|
|
|
|
export const plugin: PluginDefinition = {
|
|
authentication: {
|
|
name: "awsv4",
|
|
label: "AWS Signature",
|
|
shortLabel: "AWS v4",
|
|
args: [
|
|
{ name: "accessKeyId", label: "Access Key ID", type: "text", password: true },
|
|
{
|
|
name: "secretAccessKey",
|
|
label: "Secret Access Key",
|
|
type: "text",
|
|
password: true,
|
|
},
|
|
{
|
|
name: "service",
|
|
label: "Service Name",
|
|
type: "text",
|
|
defaultValue: "sts",
|
|
placeholder: "sts",
|
|
description: "The service that is receiving the request (sts, s3, sqs, ...)",
|
|
},
|
|
{
|
|
name: "region",
|
|
label: "Region",
|
|
type: "text",
|
|
placeholder: "us-east-1",
|
|
description: "The region that is receiving the request (defaults to us-east-1)",
|
|
optional: true,
|
|
},
|
|
{
|
|
name: "sessionToken",
|
|
label: "Session Token",
|
|
type: "text",
|
|
password: true,
|
|
optional: true,
|
|
description: "Only required if you are using temporary credentials",
|
|
},
|
|
],
|
|
onApply(_ctx, { values, ...args }): CallHttpAuthenticationResponse {
|
|
const accessKeyId = String(values.accessKeyId || "");
|
|
const secretAccessKey = String(values.secretAccessKey || "");
|
|
const sessionToken = String(values.sessionToken || "") || undefined;
|
|
|
|
const url = new URL(args.url);
|
|
|
|
const headers: NonNullable<Request["headers"]> = {};
|
|
for (const headerName of ["content-type", "host", "x-amz-date", "x-amz-security-token"]) {
|
|
const v = args.headers.find((h) => h.name.toLowerCase() === headerName);
|
|
if (v != null) {
|
|
headers[headerName] = v.value;
|
|
}
|
|
}
|
|
|
|
const signature = aws4.sign(
|
|
{
|
|
host: url.host,
|
|
method: args.method,
|
|
path: url.pathname + (url.search || ""),
|
|
service: String(values.service || "sts"),
|
|
region: values.region ? String(values.region) : undefined,
|
|
headers,
|
|
doNotEncodePath: true,
|
|
},
|
|
{
|
|
accessKeyId,
|
|
secretAccessKey,
|
|
sessionToken,
|
|
},
|
|
);
|
|
|
|
if (signature.headers == null) {
|
|
return {};
|
|
}
|
|
|
|
return {
|
|
setHeaders: Object.entries(signature.headers)
|
|
.filter(([name]) => name !== "content-type") // Don't add this because we already have it
|
|
.map(([name, value]) => ({ name, value: String(value || "") })),
|
|
};
|
|
},
|
|
},
|
|
};
|