mirror of
https://github.com/graphql-hive/console
synced 2026-05-24 09:38:26 +00:00
57 lines
1.3 KiB
TypeScript
57 lines
1.3 KiB
TypeScript
import crypto from 'node:crypto';
|
|
|
|
export type ErrorCode = 'ERR_EMPTY_BODY' | 'ERR_INVALID_SIGNATURE';
|
|
|
|
export const signatureHeaderName = 'x-hive-signature-256';
|
|
const sigHashAlg = 'sha256';
|
|
|
|
function hash(secret: string, algo: string, data: string) {
|
|
return crypto.createHmac(algo, secret).update(data, 'utf-8').digest('hex');
|
|
}
|
|
|
|
export function verifyRequest(input: {
|
|
body: string;
|
|
signature: string;
|
|
secret: string;
|
|
}): ErrorCode | undefined {
|
|
const { body, signature, secret } = input;
|
|
|
|
if (!body) {
|
|
return 'ERR_EMPTY_BODY';
|
|
}
|
|
|
|
const sig = Buffer.from(signature ?? '', 'utf8');
|
|
const digest = Buffer.from(hash(secret, sigHashAlg, body), 'utf8');
|
|
|
|
if (sig.length !== digest.length || !crypto.timingSafeEqual(digest, sig)) {
|
|
return 'ERR_INVALID_SIGNATURE';
|
|
}
|
|
}
|
|
|
|
export interface CompositionSuccess {
|
|
type: 'success';
|
|
result: {
|
|
supergraph: string;
|
|
sdl: string;
|
|
};
|
|
}
|
|
|
|
export interface CompositionFailure {
|
|
type: 'failure';
|
|
result: {
|
|
errors: Array<{
|
|
message: string;
|
|
source: 'graphql' | 'composition';
|
|
}>;
|
|
};
|
|
}
|
|
|
|
type Input = Array<{
|
|
sdl: string;
|
|
name: string;
|
|
url?: string;
|
|
}>;
|
|
|
|
export function compose(composition: (input: Input) => CompositionSuccess | CompositionFailure) {
|
|
return (input: Input) => composition(input);
|
|
}
|