mirror of
https://github.com/PCSX2/web-api.git
synced 2026-01-31 01:15:16 +01:00
78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import { v4 as uuidv4 } from "uuid";
|
|
import { ReleaseCache } from "../models/ReleaseCache";
|
|
import { LogFactory } from "../utils/LogFactory";
|
|
import { Request, Response } from "express";
|
|
import crypto from "crypto";
|
|
|
|
export class GithubController {
|
|
private releaseCache: ReleaseCache;
|
|
private log = new LogFactory("gh-listener").getLogger();
|
|
private readonly webhookSecret;
|
|
|
|
constructor(releaseCache: ReleaseCache) {
|
|
this.releaseCache = releaseCache;
|
|
const secret = process.env.GH_WEBHOOK_SECRET;
|
|
if (secret == undefined) {
|
|
this.log.error("GH_WEBHOOK_SECRET isn't set. Aborting");
|
|
throw new Error("GH_WEBHOOK_SECRET isn't set. Aborting");
|
|
} else {
|
|
this.webhookSecret = secret;
|
|
}
|
|
}
|
|
|
|
// in the future, might change it from instead of listing all releases it just uses the content of the webhook to evict the cache
|
|
// for the foreseeable future though, this is fine
|
|
webhookHandler(req: Request, resp: Response) {
|
|
const cid = uuidv4();
|
|
this.log.info("Received request", req.headers);
|
|
const ghDigestRaw = req.header("x-hub-signature-256");
|
|
if (ghDigestRaw == undefined) {
|
|
resp.send(403);
|
|
return;
|
|
}
|
|
const ghDigest = Buffer.from(ghDigestRaw, "utf8");
|
|
const digest = Buffer.from(
|
|
`sha256=${crypto
|
|
.createHmac("sha256", this.webhookSecret)
|
|
.update(JSON.stringify(req.body))
|
|
.digest("hex")}`,
|
|
"utf8"
|
|
);
|
|
if (crypto.timingSafeEqual(digest, ghDigest)) {
|
|
// Valid webhook from github, proceed
|
|
const body = req.body;
|
|
if (
|
|
"action" in body &&
|
|
body.action == "published" &&
|
|
"release" in body &&
|
|
body.release.draft == true
|
|
) {
|
|
// Release event
|
|
if (
|
|
"repository" in body &&
|
|
body.repository.full_name == "PCSX2/pcsx2"
|
|
) {
|
|
this.releaseCache.refreshReleaseCache(cid);
|
|
} else if (
|
|
"repository" in body &&
|
|
body.repository.full_name == "PCSX2/archive"
|
|
) {
|
|
this.releaseCache.refreshLegacyReleaseCache(cid);
|
|
}
|
|
} else if (
|
|
"action" in body &&
|
|
body.action == "completed" &&
|
|
"check_suite" in body &&
|
|
body.check_suite.status == "completed" &&
|
|
body.check_suite.conclusion == "success"
|
|
) {
|
|
this.releaseCache.refreshPullRequestBuildCache(cid);
|
|
}
|
|
} else {
|
|
resp.send(403);
|
|
return;
|
|
}
|
|
resp.send(204);
|
|
}
|
|
}
|