feat(auth): share Endorser verification across register and refresh

Extract requireEndorserAuth middleware and apply it to /notifications/refresh so both endpoints use the same check while keeping the local test bypass.
This commit is contained in:
Jose Olarte III
2026-07-10 18:58:52 +08:00
parent 764c89c071
commit f2f0732ef5
2 changed files with 35 additions and 19 deletions

View File

@@ -1,4 +1,5 @@
import type { NextFunction, Request, Response } from "express";
import { checkAuth } from "../services/endorserClient.js";
import { decodeAndVerifyJwt } from "../vc/index.js";
export type AuthContext = {
@@ -115,3 +116,31 @@ export async function requireAuthOrNotificationLocalTest(
}
return requireAuth(req, res, next);
}
/**
* When req.jwt is set (normal auth), require Endorser acceptance.
* Local test bypass leaves req.jwt unset and is allowed through unchanged.
*/
export async function requireEndorserAuth(
req: Request,
res: Response,
next: NextFunction
): Promise<void> {
const jwt = req.jwt;
if (jwt === undefined) {
next();
return;
}
const endorsed = await checkAuth(jwt);
if (!endorsed) {
console.log("[Auth] Endorser verification failed");
res.status(401).json({
success: false,
message: "Unauthorized",
});
return;
}
next();
}

View File

@@ -1,7 +1,9 @@
import express, { Router } from "express";
import { db } from "../db/fcmTokens.js";
import { requireAuthOrNotificationLocalTest } from "../middleware/auth.js";
import { checkAuth } from "../services/endorserClient.js";
import {
requireAuthOrNotificationLocalTest,
requireEndorserAuth,
} from "../middleware/auth.js";
import { errorMessage, formatElapsedMs } from "../util/formatElapsed.js";
import { maskToken } from "../util/maskToken.js";
@@ -14,6 +16,7 @@ notificationsRouter.get("/", (_req, res) => {
notificationsRouter.post(
"/refresh",
requireAuthOrNotificationLocalTest,
requireEndorserAuth,
async (req, res) => {
const started = Date.now();
const userId = req.did;
@@ -88,6 +91,7 @@ notificationsRouter.post(
notificationsRouter.post(
"/register",
requireAuthOrNotificationLocalTest,
requireEndorserAuth,
async (req, res) => {
const started = Date.now();
const userId = req.did;
@@ -96,23 +100,6 @@ notificationsRouter.post(
return;
}
// Local test bypass leaves req.jwt unset; only Endorser-check authenticated requests.
const jwt = req.jwt;
if (jwt !== undefined) {
const endorsed = await checkAuth(jwt);
if (!endorsed) {
console.log(
"[Register] Endorser verification failed in",
formatElapsedMs(Date.now() - started)
);
res.status(401).json({
success: false,
message: "Unauthorized",
});
return;
}
}
if (
req.body !== null &&
typeof req.body === "object" &&