fix(avatars): every signed-in account sees other users' pictures
System Health shows every user's name and avatarAt to everyone, but the picture route GET /api/users/:id/avatar sat under the staff-only /users prefix, so a developer got 403 EADMIN and saw only initials. authGuard now lets any signed-in account make that one read (EVERYONE_READS); every other /users path stays staff-only, and the test checks both.
This commit is contained in:
@@ -128,6 +128,11 @@ const STAFF_ONLY_PREFIXES = [
|
||||
// Staff-only paths with an id in the middle, matched on `apiPath()`'s
|
||||
// lower-cased form: the host's own AI-tool config files (they may hold keys).
|
||||
const STAFF_ONLY_PATTERNS = [/^\/ai-tools\/[^/]+\/config(\/|$)/];
|
||||
// The one read under a staff-only prefix every signed-in user may make: an
|
||||
// account's PICTURE (`GET /users/:id/avatar` — the image or a redirect to its
|
||||
// link, nothing else of the account). System Health shows every user's name and
|
||||
// `avatarAt` to everyone, so a developer refused here saw only initials.
|
||||
const EVERYONE_READS = [/^\/users\/\d+\/avatar$/];
|
||||
|
||||
const isServerMode = () => process.env.AGENTHUB_MODE === "server";
|
||||
|
||||
@@ -789,6 +794,7 @@ function authGuard(req, res, next) {
|
||||
const isRead = req.method === "GET" || req.method === "HEAD";
|
||||
if (
|
||||
user.role === "developer" &&
|
||||
!(isRead && EVERYONE_READS.some((re) => re.test(lp))) &&
|
||||
(STAFF_ONLY_PREFIXES.some(under) || STAFF_ONLY_PATTERNS.some((re) => re.test(lp)))
|
||||
) {
|
||||
return deny(res, 403, "EADMIN", "only an admin or analyst may open this");
|
||||
|
||||
Reference in New Issue
Block a user