Last active
November 12, 2024 17:46
-
-
Save ntotten/3264ceb91ae97ea391812e8b813ade8c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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