Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Use `verifyKey` to check a request signature:
```js
const signature = req.get('X-Signature-Ed25519');
const timestamp = req.get('X-Signature-Timestamp');
const isValidRequest = verifyKey(req.rawBody, signature, timestamp, 'MY_CLIENT_PUBLIC_KEY');
const isValidRequest = await verifyKey(req.rawBody, signature, timestamp, 'MY_CLIENT_PUBLIC_KEY');
if (!isValidRequest) {
return res.status(401).end('Bad request signature');
}
Expand Down
10 changes: 1 addition & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"url": "https://github.com/discord/discord-interactions-js.git"
},
"engines": {
"node": ">=18"
"node": ">=18.4.0"
},
"bugs": {
"url": "https://github.com/discord/discord-interactions-js/issues"
Expand All @@ -18,20 +18,19 @@
"files": [
"dist/**/*"
],
"prepare": "npm run build",
"types": "dist/index.d.ts",
"keywords": [
"discord"
],
"scripts": {
"prepare": "npm run build",
"build": "tsc",
"build:watch": "tsc --watch",
"fix": "biome check --apply .",
"lint": "biome check .",
"test": "jest --verbose"
},
"dependencies": {
"tweetnacl": "^1.0.3"
},
"devDependencies": {
"@biomejs/biome": "^1.7.3",
Expand Down
41 changes: 24 additions & 17 deletions src/__tests__/utils/SharedTestUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import nacl from 'tweetnacl';
import { arrayBufferToBase64, subtleCrypto } from '../../util';

// Example PING request body
export const pingRequestBody = JSON.stringify({
Expand Down Expand Up @@ -51,10 +51,17 @@ export const autocompleteRequestBody = JSON.stringify({
},
});

// Generate a "valid" keypair
export const validKeyPair = nacl.sign.keyPair();
// Generate an "invalid" keypair
export const invalidKeyPair = nacl.sign.keyPair();
export async function generateKeyPair() {
const keyPair = await subtleCrypto.generateKey(
{
name: 'ed25519',
namedCurve: 'ed25519',
},
true,
['sign', 'verify'],
);
return keyPair;
}

export type SignedRequest = {
body: string;
Expand All @@ -66,22 +73,22 @@ export type ExampleRequestResponse = {
body: string;
};

export function signRequestWithKeyPair(
export async function signRequestWithKeyPair(
body: string,
privateKey: Uint8Array,
): SignedRequest {
privateKey: CryptoKey,
) {
const encoder = new TextEncoder();
const timestamp = String(Math.round(new Date().getTime() / 1000));
const signature = Buffer.from(
nacl.sign.detached(
Uint8Array.from(
Buffer.concat([Buffer.from(timestamp), Buffer.from(body)]),
),
privateKey,
),
).toString('hex');
const signature = await subtleCrypto.sign(
{
name: 'ed25519',
},
privateKey,
encoder.encode(timestamp + body),
);
return {
body,
signature,
signature: arrayBufferToBase64(signature),
timestamp,
};
}
Expand Down
Loading