You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
temptress-bot/src/shim/creator.ts

73 lines
2.3 KiB

import {
SlashCreator as Creator,
RespondFunction,
Server,
SlashCreatorOptions,
TransformedRequest
} from 'slash-create';
import { FetchRequestHandler } from './util/requestHandler';
import { verify } from './util/verify';
// @ts-expect-error doesn't like _onRequest
export class SlashCreator extends Creator {
/** The request handler for the creator */
readonly requestHandler: FetchRequestHandler;
/** @param opts The options for the creator */
constructor(opts: SlashCreatorOptions) {
// eslint-disable-next-line constructor-super
super(opts);
// @ts-ignore
this.requestHandler = new FetchRequestHandler(this);
}
/**
* Attaches a server to the creator.
* @param server The server to use
*/
withServer(server: Server) {
if (this.server) throw new Error('A server was already set in this creator.');
this.server = server;
if (this.server.isWebserver) {
if (!this.options.publicKey) throw new Error('A public key is required to be set when using a webserver.');
// @ts-ignore
this.server.createEndpoint(this.options.endpointPath as string, this._onRequest.bind(this));
// @ts-ignore
} else this.server.handleInteraction((interaction) => this._onInteraction(interaction, null, false));
return this;
}
// Overwriting the verification method to use Web Crypto API and use waitUntil for the promise
private async _onRequest(treq: TransformedRequest, respond: RespondFunction, wait: (f: any) => void) {
this.emit('debug', 'Got request');
// Verify request
const signature = treq.headers['x-signature-ed25519'] as string;
const timestamp = treq.headers['x-signature-timestamp'] as string;
// Check if both signature and timestamp exists, and the timestamp isn't past due.
if (
!signature ||
!timestamp ||
parseInt(timestamp) < (Date.now() - (this.options.maxSignatureTimestamp as number)) / 1000
)
return respond({
status: 401,
body: 'Invalid signature'
});
if (!(await verify(treq))) {
this.emit('debug', 'A request failed to be verified');
this.emit('unverifiedRequest', treq);
return respond({
status: 401,
body: 'Invalid signature'
});
}
// @ts-expect-error
wait(this._onInteraction(treq.body, respond, true).catch(() => {}));
}
}