From 396447d2e41be79decdc791da7cabbacbd5aab18 Mon Sep 17 00:00:00 2001 From: "Robert St. John" Date: Fri, 22 Nov 2024 11:45:12 -0700 Subject: [PATCH] refactor(service): users/auth: fix type errors in export routes --- service/src/models/export.d.ts | 7 ++++--- service/src/models/export.js | 2 +- service/src/routes/exports.ts | 35 +++++++++++++++++++--------------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/service/src/models/export.d.ts b/service/src/models/export.d.ts index 0fbce07a5..9a5c647f2 100644 --- a/service/src/models/export.d.ts +++ b/service/src/models/export.d.ts @@ -1,5 +1,6 @@ import mongoose from 'mongoose' import { MageEventId } from '../entities/events/entities.events' +import { UserId } from '../entities/users/entities.users' import { ExportFormat } from '../export' import { ExportOptions } from '../export/exporter' import { UserDocument } from './user' @@ -19,7 +20,7 @@ export type ExportErrorAttrs = { } export type ExportAttrs = { - userId: mongoose.Types.ObjectId, + userId: UserId, relativePath?: string, filename?: string, exportType: ExportFormat, @@ -48,8 +49,8 @@ export type PopulateQueryOption = { populate: true } export function createExport(spec: Pick): Promise export function getExportById(id: mongoose.Types.ObjectId | string): Promise export function getExportById(id: mongoose.Types.ObjectId | string, options: PopulateQueryOption): Promise -export function getExportsByUserId(userId: mongoose.Types.ObjectId): Promise -export function getExportsByUserId(userId: mongoose.Types.ObjectId, options: PopulateQueryOption): Promise +export function getExportsByUserId(userId: UserId): Promise +export function getExportsByUserId(userId: UserId, options: PopulateQueryOption): Promise export function getExports(): Promise export function getExports(options: PopulateQueryOption): Promise export function count(options?: { filter: any }): Promise diff --git a/service/src/models/export.js b/service/src/models/export.js index 1778907c6..dd2ba48de 100644 --- a/service/src/models/export.js +++ b/service/src/models/export.js @@ -94,7 +94,7 @@ exports.getExportById = function (id, options = {}) { }; exports.getExportsByUserId = function (userId, options = {}) { - let query = Export.find({ userId: userId }); + let query = Export.find({ userId }); if (options.populate) { query = query.populate('userId').populate({ path: 'options.eventId', select: 'name' }); } diff --git a/service/src/routes/exports.ts b/service/src/routes/exports.ts index d4c348839..3ed876fb2 100644 --- a/service/src/routes/exports.ts +++ b/service/src/routes/exports.ts @@ -15,11 +15,11 @@ import { EventAccessType } from '../entities/events/entities.events' import Export, { ExportDocument } from '../models/export' type ExportRequest = express.Request & { - export?: ExportDocument | null - parameters?: { - exportId?: ExportDocument['_id'] - filter: any - }, + export?: ExportDocument | null + parameters?: { + exportId?: ExportDocument['_id'] + filter: any + }, } const DefineExportsRoutes: MageRouteDefinitions = function(app, security) { @@ -27,12 +27,13 @@ const DefineExportsRoutes: MageRouteDefinitions = function(app, security) { const passport = security.authentication.passport; async function authorizeEventAccess(req: express.Request, res: express.Response, next: express.NextFunction): Promise { - if (access.userHasPermission(req.user, ObservationPermission.READ_OBSERVATION_ALL)) { + const account = req.user?.admitted?.account + if (access.userHasPermission(account, ObservationPermission.READ_OBSERVATION_ALL)) { return next(); } - else if (access.userHasPermission(req.user, ObservationPermission.READ_OBSERVATION_EVENT)) { + else if (account && access.userHasPermission(account, ObservationPermission.READ_OBSERVATION_EVENT)) { // Make sure I am part of this event - const allowed = await eventPermissions.userHasEventPermission(req.event!, req.user.id, EventAccessType.Read) + const allowed = await eventPermissions.userHasEventPermission(req.event!, account.id, EventAccessType.Read) if (allowed) { return next(); } @@ -43,13 +44,15 @@ const DefineExportsRoutes: MageRouteDefinitions = function(app, security) { function authorizeExportAccess(permission: ExportPermission): express.RequestHandler { return async function authorizeExportAccess(req, res, next) { const exportReq = req as ExportRequest + const account = exportReq.user?.admitted?.account exportReq.export = await Export.getExportById(req.params.exportId) - if (access.userHasPermission(exportReq.user, permission)) { - next() + if (access.userHasPermission(account, permission)) { + return next() } - else { - exportReq.user._id.toString() === exportReq.export?.userId.toString() ? next() : res.sendStatus(403); + else if (account && account.id === exportReq.export?.userId.toString()) { + return next() } + res.sendStatus(403) } } @@ -60,8 +63,9 @@ const DefineExportsRoutes: MageRouteDefinitions = function(app, security) { authorizeEventAccess, function (req, res, next) { const exportReq = req as ExportRequest + const userId = exportReq.user!.admitted!.account.id const document = { - userId: exportReq.user._id, + userId, exportType: exportReq.body.exportType, options: { eventId: req.body.eventId, @@ -97,7 +101,8 @@ const DefineExportsRoutes: MageRouteDefinitions = function(app, security) { app.get('/api/exports/myself', passport.authenticate('bearer'), function (req, res, next) { - Export.getExportsByUserId(req.user._id, { populate: true }).then(exports => { + const userId = req.user!.admitted!.account.id + Export.getExportsByUserId(userId, { populate: true }).then(exports => { const response = exportXform.transform(exports, { path: `${req.getRoot()}/api/exports` }); res.json(response); }).catch(err => next(err)); @@ -209,7 +214,7 @@ function parseQueryParams(req: express.Request, res: express.Response, next: exp parameters.filter.favorites = String(body.favorites).toLowerCase() === 'true'; if (parameters.filter.favorites) { parameters.filter.favorites = { - userId: req.user._id + userId: req.user?.admitted?.account.id }; } parameters.filter.important = String(body.important).toLowerCase() === 'true';