Skip to content

Instantly share code, notes, and snippets.

@ntotten
Last active November 12, 2024 17:46
Show Gist options
  • Save ntotten/3264ceb91ae97ea391812e8b813ade8c to your computer and use it in GitHub Desktop.
Save ntotten/3264ceb91ae97ea391812e8b813ade8c to your computer and use it in GitHub Desktop.
import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime";
type MyPolicyOptionsType = {
bucketName: string;
accountName: string;
};
export default async function policy(
request: ZuploRequest,
context: ZuploContext,
options: MyPolicyOptionsType,
policyName: string
) {
// Get the consumerName from the URL
const { consumerName } = request.params;
const url = new URL(`https://dev.zuplo.com/v1/accounts/${options.accountName}/key-buckets/${options.bucketName}/consumers/${consumerName}`)
url.searchParams.set("include-api-keys", "true")
url.searchParams.set("key-format", "true")
const response = await fetch(url.toString(), {
headers: {
"Authorization": `Bearer ${environment.MY_ZUPLO_API_KEY}`
}
})
if (!response.ok) {
const text = await response.text();
context.log.error("Error retreieving consumer", text);
throw new Error("Error retrieving consumer");
}
/*
Simplified API response
{
"id": "csmr_TNel8WPAbkVc5cj1UhWXMWV5",
"name": "fasdff",
"metadata": {},
"apiKeys": [
{
"id": "key_Vs64JirxXVGxWEdJI6X7sjG2",
"key": "****"
}
]
}
*/
const result = await response.json();
request.user.data
request.user = {
sub: result.name,
data: {
...result.metadata,
apiKey: result.apiKeys[0].key
}
}
return request;
}
import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
export default async function policy(
request: ZuploRequest,
context: ZuploContext
) {
// Get the API Key
const { apiKey } = request.user.data;
// Get the body as a string
const body = await request.clone().text();
// Sign the body with the key
const signature = await signRequestBody(apiKey, body);
// Add the header to the request
request.headers.set("X-Signature", signature)
return request;
}
async function signRequestBody(secret: string, body: string) {
// Encode the secret as a key
const key = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode(secret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"]
);
// Encode the body and generate the HMAC signature
const signature = await crypto.subtle.sign(
"HMAC",
key,
new TextEncoder().encode(body)
);
// Convert the signature to a hex string
return Array.from(new Uint8Array(signature))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment