Skip to content

Commit

Permalink
Merge pull request #7 from ubiquibot/check-signature
Browse files Browse the repository at this point in the history
Check signature
  • Loading branch information
whilefoo authored Jun 11, 2024
2 parents 437ed6a + 92bfa6e commit be0f10d
Show file tree
Hide file tree
Showing 6 changed files with 552 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
"version": "0.2",
"ignorePaths": ["**/*.json", "**/*.css", "node_modules", "**/*.log", "**/*.toml", "src/adapters/supabase/types/database.ts"],
"ignorePaths": ["**/*.json", "**/*.css", "node_modules", "**/*.log", "**/*.toml", "**/*.http", "src/adapters/supabase/types/database.ts"],
"useGitignore": true,
"language": "en",
"words": ["dataurl", "devpool", "outdir", "servedir", "supabase", "typebox", "typeguards", "mswjs", "ubiquibot"],
Expand Down
1 change: 1 addition & 0 deletions src/types/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "dotenv/config";
export const envSchema = T.Object({
SUPABASE_URL: T.String(),
SUPABASE_KEY: T.String(),
UBIQUIBOT_PUBLIC_KEY: T.String(),
});

export type Env = StaticDecode<typeof envSchema>;
32 changes: 30 additions & 2 deletions src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@ export default {
});
}
const webhookPayload = await request.json();
const settings = Value.Decode(assistivePricingSettingsSchema, Value.Default(assistivePricingSettingsSchema, JSON.parse(webhookPayload.settings)));
webhookPayload.eventPayload = JSON.parse(webhookPayload.eventPayload);
const signature = webhookPayload.signature;
delete webhookPayload.signature;
if (!(await verifySignature(env.UBIQUIBOT_PUBLIC_KEY, webhookPayload, signature))) {
return new Response(JSON.stringify({ error: `Error: Signature verification failed` }), {
status: 400,
headers: { "content-type": "application/json" },
});
}
const settings = Value.Decode(assistivePricingSettingsSchema, Value.Default(assistivePricingSettingsSchema, webhookPayload.settings));
webhookPayload.settings = settings;
await run(webhookPayload, env);
return new Response(JSON.stringify("OK"), { status: 200, headers: { "content-type": "application/json" } });
Expand All @@ -36,3 +43,24 @@ function handleUncaughtError(error: unknown) {
const status = 500;
return new Response(JSON.stringify({ error }), { status: status, headers: { "content-type": "application/json" } });
}

async function verifySignature(publicKeyPem: string, payload: unknown, signature: string) {
const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));

const publicKey = await crypto.subtle.importKey(
"spki",
binaryDer.buffer,
{
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
},
true,
["verify"]
);

const signatureArray = Uint8Array.from(atob(signature), (c) => c.charCodeAt(0));
const dataArray = new TextEncoder().encode(JSON.stringify(payload));

return await crypto.subtle.verify("RSASSA-PKCS1-v1_5", publicKey, signatureArray, dataArray);
}
Loading

0 comments on commit be0f10d

Please sign in to comment.