fix: catch authentication failures in async route handlers

This commit is contained in:
tdurieux
2026-09-06 09:17:37 +02:00
parent 11eb160d2b
commit 7210db2b61
5 changed files with 30 additions and 20 deletions
+1 -1
View File
@@ -64,8 +64,8 @@ router.use(
res: express.Response,
next: express.NextFunction
) => {
const user = await getUser(req);
try {
const user = await getUser(req);
// only admins are allowed here
isOwnerOrAdmin([], user);
next();
+2 -3
View File
@@ -102,8 +102,8 @@ router.delete(
router.get(
"/source/:gistId",
async (req: express.Request, res: express.Response) => {
const user = await getUser(req);
try {
const user = await getUser(req);
const gist = new Gist(
new AnonymizedGistModel({
owner: user.id,
@@ -232,10 +232,9 @@ router.post(
// add gist
router.post("/", async (req: express.Request, res: express.Response) => {
const user = await getUser(req);
const gistUpdate = req.body;
try {
const user = await getUser(req);
validateNewGist(gistUpdate);
const gist = new Gist(
+2 -3
View File
@@ -103,8 +103,8 @@ router.delete(
router.get(
"/:owner/:repository/:pullRequestId",
async (req: express.Request, res: express.Response) => {
const user = await getUser(req);
try {
const user = await getUser(req);
const pullRequest = new PullRequest(
new AnonymizedPullRequestModel({
owner: user.id,
@@ -249,10 +249,9 @@ router.post(
// add pullRequest
router.post("/", async (req: express.Request, res: express.Response) => {
const user = await getUser(req);
const pullRequestUpdate = req.body;
try {
const user = await getUser(req);
validateNewPullRequest(pullRequestUpdate);
const pullRequest = new PullRequest(
+12 -13
View File
@@ -66,8 +66,8 @@ async function getTokenForAdmin(user: User, req: express.Request) {
// claim a repository
router.post("/claim", async (req: express.Request, res: express.Response) => {
const user = await getUser(req);
try {
const user = await getUser(req);
if (!req.body.repoId) {
throw new AnonymousError("repoId_not_defined", {
object: req.body,
@@ -254,12 +254,12 @@ router.delete(
router.get(
"/:owner/:repo/",
async (req: express.Request, res: express.Response) => {
const user = await getUser(req);
let token = user.accessToken;
if (user.isAdmin) {
token = (await getTokenForAdmin(user, req)) || token;
}
try {
const user = await getUser(req);
let token = user.accessToken;
if (user.isAdmin) {
token = (await getTokenForAdmin(user, req)) || token;
}
const repo = await getRepositoryFromGitHub({
owner: req.params.owner,
repo: req.params.repo,
@@ -277,12 +277,12 @@ router.get(
router.get(
"/:owner/:repo/branches",
async (req: express.Request, res: express.Response) => {
const user = await getUser(req);
let token = user.accessToken;
if (user.isAdmin) {
token = (await getTokenForAdmin(user, req)) || token;
}
try {
const user = await getUser(req);
let token = user.accessToken;
if (user.isAdmin) {
token = (await getTokenForAdmin(user, req)) || token;
}
const repository = await getRepositoryFromGitHub({
accessToken: token,
owner: req.params.owner,
@@ -621,10 +621,9 @@ router.post(
// add repository
router.post("/", async (req: express.Request, res: express.Response) => {
const user = await getUser(req);
const repoUpdate = req.body;
try {
const user = await getUser(req);
try {
await db.getRepository(repoUpdate.repoId);
throw new AnonymousError("repoId_already_used", {
+13
View File
@@ -96,6 +96,19 @@ describe("production regressions", function () {
const error = await new Promise(resolve => passport._strategy("github")._verify("token", "", { id: "new-id", username: "recycled" }, resolve));
expect(error.message).to.equal("not_connected");
});
for (const name of ["repository-private", "gist-private", "pullRequest-private"]) {
it(`handles rejected authentication in ${name} create routes`, async function () {
const utils = require("../src/server/routes/route-utils");
const router = require(`../src/server/routes/${name}`).default;
const failure = new Error("banned"); let handled;
stub(utils, "getUser", async () => { throw failure; });
stub(utils, "handleError", error => { handled = error; });
const route = router.stack.find(x => x.route?.path === "/" && x.route.methods.post).route;
await route.stack[0].handle({ body: {} }, {});
expect(handled).to.equal(failure);
});
}
it("checks GitHub authorization before returning shared cached metadata", async function () {
const CachedRepoModel = require("../src/core/model/repositories/repositories.model").default;
stub(db, "isConnected", true);