From 2bedfbc4baeefea746c42639024eb3556070b422 Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 19 Jul 2024 15:43:32 -0700 Subject: [PATCH 01/13] feat: extended express request and added util getters for properties --- api/src/app.ts | 13 ++++++++ api/src/database/db.ts | 2 +- api/src/paths/administrative-activity.ts | 4 ++- .../security/authentication.ts | 3 +- api/src/utils/keycloak-utils.ts | 15 +++++---- api/src/utils/request.ts | 32 +++++++++++++++++++ 6 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 api/src/utils/request.ts diff --git a/api/src/app.ts b/api/src/app.ts index c8bae12e0b..6ed1dca058 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -12,11 +12,24 @@ import { replaceAuthorizationHeaderMiddleware } from './middleware/critterbase-proxy'; import { rootAPIDoc } from './openapi/root-api-doc'; +import { SystemUser } from './repositories/user-repository'; import { authenticateRequest, authenticateRequestOptional } from './request-handlers/security/authentication'; +import { KeycloakUserInformation } from './utils/keycloak-utils'; import { getLogger } from './utils/logger'; const defaultLog = getLogger('app'); +/** + * Extending express request type. + * + */ +declare module 'express-serve-static-core' { + interface Request { + keycloak_token?: KeycloakUserInformation; + system_user?: SystemUser; + } +} + const HOST = process.env.API_HOST; const PORT = Number(process.env.API_PORT); diff --git a/api/src/database/db.ts b/api/src/database/db.ts index 26fec348de..01334de9f5 100644 --- a/api/src/database/db.ts +++ b/api/src/database/db.ts @@ -225,7 +225,7 @@ export interface IDBConnection { * @param {object} keycloakToken * @return {*} {IDBConnection} */ -export const getDBConnection = function (keycloakToken: KeycloakUserInformation): IDBConnection { +export const getDBConnection = function (keycloakToken?: KeycloakUserInformation): IDBConnection { if (!keycloakToken) { throw Error('Keycloak token is undefined'); } diff --git a/api/src/paths/administrative-activity.ts b/api/src/paths/administrative-activity.ts index 04dec02ae5..77ea91d106 100644 --- a/api/src/paths/administrative-activity.ts +++ b/api/src/paths/administrative-activity.ts @@ -5,6 +5,7 @@ import { HTTP400, HTTP500 } from '../errors/http-error'; import { AdministrativeActivityService } from '../services/administrative-activity-service'; import { getUserGuid } from '../utils/keycloak-utils'; import { getLogger } from '../utils/logger'; +import { getKeycloakTokenFromRequest } from '../utils/request'; const defaultLog = getLogger('paths/administrative-activity-request'); @@ -173,7 +174,8 @@ export function getAdministrativeActivityStanding(): RequestHandler { const connection = getAPIUserDBConnection(); try { - const userGUID = getUserGuid(req['keycloak_token']); + const keycloakToken = getKeycloakTokenFromRequest(req); + const userGUID = getUserGuid(keycloakToken); if (!userGUID) { throw new HTTP400('Failed to identify user'); diff --git a/api/src/request-handlers/security/authentication.ts b/api/src/request-handlers/security/authentication.ts index 5e136aadc3..6ad6c74a46 100644 --- a/api/src/request-handlers/security/authentication.ts +++ b/api/src/request-handlers/security/authentication.ts @@ -2,6 +2,7 @@ import { Request } from 'express'; import { decode, verify } from 'jsonwebtoken'; import { JwksClient } from 'jwks-rsa'; import { HTTP401 } from '../../errors/http-error'; +import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getLogger } from '../../utils/logger'; const defaultLog = getLogger('request-handlers/security/authentication'); @@ -80,7 +81,7 @@ export const authenticateRequest = async function (req: Request): Promise } // Add the verified token to the request for future use, if needed - req['keycloak_token'] = verifiedToken; + req.keycloak_token = verifiedToken as KeycloakUserInformation; return true; } catch (error) { diff --git a/api/src/utils/keycloak-utils.ts b/api/src/utils/keycloak-utils.ts index fbb21e1146..7703ca67ba 100644 --- a/api/src/utils/keycloak-utils.ts +++ b/api/src/utils/keycloak-utils.ts @@ -1,3 +1,4 @@ +import { JwtPayload } from 'jsonwebtoken'; import { SOURCE_SYSTEM, SYSTEM_IDENTITY_SOURCE } from '../constants/database'; /** @@ -73,12 +74,14 @@ export type DatabaseUserInformation = { /** * User information from either an IDIR or BCeID Basic or BCeID Business Keycloak token. */ -export type KeycloakUserInformation = - | IdirUserInformation - | BceidBasicUserInformation - | BceidBusinessUserInformation - | ServiceClientUserInformation - | DatabaseUserInformation; +export type KeycloakUserInformation = JwtPayload & + ( + | IdirUserInformation + | BceidBasicUserInformation + | BceidBusinessUserInformation + | ServiceClientUserInformation + | DatabaseUserInformation + ); /** * Returns the user information guid. diff --git a/api/src/utils/request.ts b/api/src/utils/request.ts new file mode 100644 index 0000000000..019d077437 --- /dev/null +++ b/api/src/utils/request.ts @@ -0,0 +1,32 @@ +import { Request } from 'express'; +import { SystemUser } from '../repositories/user-repository'; +import { KeycloakUserInformation } from './keycloak-utils'; + +/** + * Get keycloak token from request or throw error. + * + * @param {Request} req + * @throws {Error} - Missing keycloak token + * @returns {KeycloakUserInformation} + */ +export const getKeycloakTokenFromRequest = (req: Request): KeycloakUserInformation => { + if (!req.keycloak_token) { + throw new Error('Request missing keycloak token.'); + } + return req.keycloak_token; +}; + +/** + * Get system user from request of throw error. + * + * @param {Request} req + * @throws {Error} - Missing system user + * @returns {SystemUser} + */ +export const getSystemUserFromRequest = (req: Request): SystemUser => { + if (!req.system_user) { + throw new Error('Request missing system user.'); + } + + return req.system_user; +}; From a6fbe8adafa0acdff54392ce35709e98297c7629 Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 19 Jul 2024 15:45:33 -0700 Subject: [PATCH 02/13] fix: updated req['keycloak_token'] -> req.keycloak_token --- api/src/database/db.ts | 2 +- api/src/paths/administrative-activities.ts | 2 +- api/src/paths/administrative-activity.test.ts | 4 ++-- .../system-access/{administrativeActivityId}/approve.ts | 2 +- .../system-access/{administrativeActivityId}/reject.ts | 2 +- api/src/paths/animal/index.test.ts | 4 ++-- api/src/paths/animal/index.ts | 2 +- api/src/paths/funding-sources/index.ts | 4 ++-- api/src/paths/funding-sources/{fundingSourceId}.ts | 6 +++--- api/src/paths/observation/index.test.ts | 4 ++-- api/src/paths/observation/index.ts | 2 +- api/src/paths/project/create.ts | 2 +- api/src/paths/project/index.test.ts | 4 ++-- api/src/paths/project/index.ts | 2 +- api/src/paths/project/{projectId}/attachments/list.ts | 2 +- .../paths/project/{projectId}/attachments/report/upload.ts | 2 +- api/src/paths/project/{projectId}/attachments/upload.ts | 2 +- .../{projectId}/attachments/{attachmentId}/delete.ts | 2 +- .../{projectId}/attachments/{attachmentId}/getSignedUrl.ts | 2 +- .../{projectId}/attachments/{attachmentId}/metadata/get.ts | 2 +- .../attachments/{attachmentId}/metadata/update.ts | 2 +- api/src/paths/project/{projectId}/delete.ts | 2 +- api/src/paths/project/{projectId}/participants/index.ts | 4 ++-- api/src/paths/project/{projectId}/participants/self.ts | 2 +- .../{projectId}/participants/{projectParticipationId}.ts | 4 ++-- api/src/paths/project/{projectId}/survey/create.ts | 2 +- api/src/paths/project/{projectId}/survey/index.test.ts | 4 ++-- api/src/paths/project/{projectId}/survey/index.ts | 2 +- .../survey/{surveyId}/attachments/keyx/upload.ts | 2 +- .../{projectId}/survey/{surveyId}/attachments/list.ts | 2 +- .../survey/{surveyId}/attachments/report/upload.ts | 2 +- .../{projectId}/survey/{surveyId}/attachments/upload.ts | 2 +- .../survey/{surveyId}/attachments/{attachmentId}/delete.ts | 2 +- .../{surveyId}/attachments/{attachmentId}/getSignedUrl.ts | 2 +- .../{surveyId}/attachments/{attachmentId}/metadata/get.ts | 2 +- .../attachments/{attachmentId}/metadata/update.ts | 2 +- .../{projectId}/survey/{surveyId}/critters/delete.ts | 2 +- .../{projectId}/survey/{surveyId}/critters/import.ts | 2 +- .../project/{projectId}/survey/{surveyId}/critters/index.ts | 4 ++-- .../{projectId}/survey/{surveyId}/critters/{critterId}.ts | 2 +- .../{surveyId}/critters/{critterId}/deployments/index.ts | 4 ++-- .../critters/{critterId}/deployments/{bctwDeploymentId}.ts | 2 +- .../survey/{surveyId}/critters/{critterId}/telemetry.ts | 2 +- .../paths/project/{projectId}/survey/{surveyId}/delete.ts | 2 +- .../project/{projectId}/survey/{surveyId}/deployments.ts | 2 +- .../{projectId}/survey/{surveyId}/observations/delete.ts | 2 +- .../survey/{surveyId}/observations/environments/delete.ts | 2 +- .../{projectId}/survey/{surveyId}/observations/index.ts | 4 ++-- .../survey/{surveyId}/observations/measurements/delete.ts | 2 +- .../{projectId}/survey/{surveyId}/observations/process.ts | 2 +- .../{projectId}/survey/{surveyId}/observations/spatial.ts | 2 +- .../{projectId}/survey/{surveyId}/observations/upload.ts | 2 +- .../{surveyId}/observations/{surveyObservationId}/index.ts | 2 +- .../{projectId}/survey/{surveyId}/participants/index.ts | 4 ++-- .../{surveyId}/participants/{surveyParticipationId}.ts | 4 ++-- .../{projectId}/survey/{surveyId}/sample-site/delete.ts | 2 +- .../{projectId}/survey/{surveyId}/sample-site/index.ts | 4 ++-- .../{surveyId}/sample-site/{surveySampleSiteId}/index.ts | 6 +++--- .../sample-site/{surveySampleSiteId}/sample-method/index.ts | 4 ++-- .../sample-method/{surveySampleMethodId}/index.ts | 4 ++-- .../{surveySampleMethodId}/sample-period/index.ts | 4 ++-- .../sample-period/{surveySamplePeriodId}.ts | 4 ++-- .../{projectId}/survey/{surveyId}/telemetry/upload.ts | 2 +- .../paths/project/{projectId}/survey/{surveyId}/update.ts | 2 +- .../project/{projectId}/survey/{surveyId}/update/get.ts | 2 +- api/src/paths/project/{projectId}/survey/{surveyId}/view.ts | 2 +- api/src/paths/project/{projectId}/update.ts | 4 ++-- api/src/paths/project/{projectId}/view.ts | 2 +- api/src/paths/publish/attachment/resubmit.ts | 2 +- api/src/paths/publish/survey.ts | 2 +- api/src/paths/spatial/regions.ts | 2 +- api/src/paths/standards/taxon/{tsn}/index.ts | 2 +- api/src/paths/survey/index.test.ts | 4 ++-- api/src/paths/survey/index.ts | 2 +- api/src/paths/telemetry/index.test.ts | 4 ++-- api/src/paths/telemetry/index.ts | 2 +- api/src/paths/telemetry/manual/process.ts | 2 +- api/src/paths/user/add.ts | 4 ++-- api/src/paths/user/index.ts | 2 +- api/src/paths/user/list.ts | 2 +- api/src/paths/user/self.ts | 2 +- api/src/paths/user/{userId}/delete.ts | 2 +- api/src/paths/user/{userId}/get.ts | 2 +- api/src/paths/user/{userId}/projects/get.ts | 2 +- api/src/paths/user/{userId}/system-roles/update.ts | 2 +- api/src/request-handlers/security/authorization.ts | 2 +- 86 files changed, 112 insertions(+), 112 deletions(-) diff --git a/api/src/database/db.ts b/api/src/database/db.ts index 01334de9f5..cdc3c1a8b5 100644 --- a/api/src/database/db.ts +++ b/api/src/database/db.ts @@ -209,7 +209,7 @@ export interface IDBConnection { * * const sqlStatement = SQL\`select * from table where id = ${id};\`; * - * const connection = await getDBConnection(req['keycloak_token']); + * const connection = await getDBConnection(req.keycloak_token); * * try { * await connection.open(); diff --git a/api/src/paths/administrative-activities.ts b/api/src/paths/administrative-activities.ts index 5f83783081..81d8d9b58d 100644 --- a/api/src/paths/administrative-activities.ts +++ b/api/src/paths/administrative-activities.ts @@ -140,7 +140,7 @@ GET.apiDoc = { */ export function getAdministrativeActivities(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { // Only search for specified types if provided, otherwise search all types diff --git a/api/src/paths/administrative-activity.test.ts b/api/src/paths/administrative-activity.test.ts index 2a13a35167..e03cf1917f 100644 --- a/api/src/paths/administrative-activity.test.ts +++ b/api/src/paths/administrative-activity.test.ts @@ -117,7 +117,7 @@ describe('getAdministrativeActivityStanding', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockReq['keycloak_token'] = { + mockreq.keycloak_token = { idir_user_guid: 'testguid', identity_provider: 'idir', idir_username: 'testuser', @@ -158,7 +158,7 @@ describe('getAdministrativeActivityStanding', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockReq['keycloak_token'] = { + mockreq.keycloak_token = { idir_user_guid: 'testguid', identity_provider: 'idir', idir_username: 'testuser', diff --git a/api/src/paths/administrative-activity/system-access/{administrativeActivityId}/approve.ts b/api/src/paths/administrative-activity/system-access/{administrativeActivityId}/approve.ts index 1f9906e4b4..dbff48abe5 100644 --- a/api/src/paths/administrative-activity/system-access/{administrativeActivityId}/approve.ts +++ b/api/src/paths/administrative-activity/system-access/{administrativeActivityId}/approve.ts @@ -139,7 +139,7 @@ export function approveAccessRequest(): RequestHandler { const roleIds: number[] = req.body.roleIds || []; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/administrative-activity/system-access/{administrativeActivityId}/reject.ts b/api/src/paths/administrative-activity/system-access/{administrativeActivityId}/reject.ts index 0ba3b74852..77bb24a6e2 100644 --- a/api/src/paths/administrative-activity/system-access/{administrativeActivityId}/reject.ts +++ b/api/src/paths/administrative-activity/system-access/{administrativeActivityId}/reject.ts @@ -68,7 +68,7 @@ export function rejectAccessRequest(): RequestHandler { return async (req, res) => { const administrativeActivityId = Number(req.params.administrativeActivityId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/animal/index.test.ts b/api/src/paths/animal/index.test.ts index f7cc30846d..09e061154a 100644 --- a/api/src/paths/animal/index.test.ts +++ b/api/src/paths/animal/index.test.ts @@ -59,7 +59,7 @@ describe('findAnimals', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -126,7 +126,7 @@ describe('findAnimals', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/animal/index.ts b/api/src/paths/animal/index.ts index ad2d1b229b..e2177196cc 100644 --- a/api/src/paths/animal/index.ts +++ b/api/src/paths/animal/index.ts @@ -184,7 +184,7 @@ export function findAnimals(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'findAnimals' }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/funding-sources/index.ts b/api/src/paths/funding-sources/index.ts index dd5fd6d073..b633fd9533 100644 --- a/api/src/paths/funding-sources/index.ts +++ b/api/src/paths/funding-sources/index.ts @@ -113,7 +113,7 @@ GET.apiDoc = { */ export function getFundingSources(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const filterFields: IFundingSourceSearchParams = req.query || {}; try { await connection.open(); @@ -260,7 +260,7 @@ POST.apiDoc = { */ export function postFundingSource(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const service = new FundingSourceService(connection); const data = req.body; try { diff --git a/api/src/paths/funding-sources/{fundingSourceId}.ts b/api/src/paths/funding-sources/{fundingSourceId}.ts index b630fef7d7..048e5ffa80 100644 --- a/api/src/paths/funding-sources/{fundingSourceId}.ts +++ b/api/src/paths/funding-sources/{fundingSourceId}.ts @@ -172,7 +172,7 @@ GET.apiDoc = { */ export function getFundingSource(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const fundingSourceId = Number(req.params.fundingSourceId); @@ -309,7 +309,7 @@ PUT.apiDoc = { */ export function putFundingSource(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -408,7 +408,7 @@ DELETE.apiDoc = { */ export function deleteFundingSource(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const fundingSourceId = Number(req.params.fundingSourceId); diff --git a/api/src/paths/observation/index.test.ts b/api/src/paths/observation/index.test.ts index 525d111514..5eda7fe56a 100644 --- a/api/src/paths/observation/index.test.ts +++ b/api/src/paths/observation/index.test.ts @@ -79,7 +79,7 @@ describe('findObservations', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -172,7 +172,7 @@ describe('findObservations', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/observation/index.ts b/api/src/paths/observation/index.ts index de2c23a71f..30fbbd3b45 100644 --- a/api/src/paths/observation/index.ts +++ b/api/src/paths/observation/index.ts @@ -169,7 +169,7 @@ export function findObservations(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'getObservations' }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/create.ts b/api/src/paths/project/create.ts index 90c1440836..a1e73bb325 100644 --- a/api/src/paths/project/create.ts +++ b/api/src/paths/project/create.ts @@ -87,7 +87,7 @@ POST.apiDoc = { */ export function createProject(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const sanitizedProjectPostData = new PostProjectObject(req.body); diff --git a/api/src/paths/project/index.test.ts b/api/src/paths/project/index.test.ts index 8a31df36b6..12b2a2da85 100644 --- a/api/src/paths/project/index.test.ts +++ b/api/src/paths/project/index.test.ts @@ -55,7 +55,7 @@ describe('findProjects', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -117,7 +117,7 @@ describe('findProjects', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/project/index.ts b/api/src/paths/project/index.ts index 609ef2e4d5..779a91b07c 100644 --- a/api/src/paths/project/index.ts +++ b/api/src/paths/project/index.ts @@ -183,7 +183,7 @@ export function findProjects(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'findProjects' }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/attachments/list.ts b/api/src/paths/project/{projectId}/attachments/list.ts index 944d31effe..6c9ce424df 100644 --- a/api/src/paths/project/{projectId}/attachments/list.ts +++ b/api/src/paths/project/{projectId}/attachments/list.ts @@ -131,7 +131,7 @@ export function getAttachments(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'Get attachments list', message: 'params', req_params: req.params }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const projectId = Number(req.params.projectId); try { diff --git a/api/src/paths/project/{projectId}/attachments/report/upload.ts b/api/src/paths/project/{projectId}/attachments/report/upload.ts index fa5ad30e24..592079239a 100644 --- a/api/src/paths/project/{projectId}/attachments/report/upload.ts +++ b/api/src/paths/project/{projectId}/attachments/report/upload.ts @@ -155,7 +155,7 @@ export function uploadMedia(): RequestHandler { file: { ...rawMediaFile, buffer: 'Too big to print' } }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/attachments/upload.ts b/api/src/paths/project/{projectId}/attachments/upload.ts index 515b4b0ff9..6a74324613 100644 --- a/api/src/paths/project/{projectId}/attachments/upload.ts +++ b/api/src/paths/project/{projectId}/attachments/upload.ts @@ -130,7 +130,7 @@ export function uploadMedia(): RequestHandler { file: { ...rawMediaFile, buffer: 'Too big to print' } }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/attachments/{attachmentId}/delete.ts b/api/src/paths/project/{projectId}/attachments/{attachmentId}/delete.ts index 57664dc131..16c2dbdb05 100644 --- a/api/src/paths/project/{projectId}/attachments/{attachmentId}/delete.ts +++ b/api/src/paths/project/{projectId}/attachments/{attachmentId}/delete.ts @@ -96,7 +96,7 @@ export function deleteAttachment(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'Delete attachment', message: 'params', req_params: req.params }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/attachments/{attachmentId}/getSignedUrl.ts b/api/src/paths/project/{projectId}/attachments/{attachmentId}/getSignedUrl.ts index 0e5b07b373..85ec5c50e2 100644 --- a/api/src/paths/project/{projectId}/attachments/{attachmentId}/getSignedUrl.ts +++ b/api/src/paths/project/{projectId}/attachments/{attachmentId}/getSignedUrl.ts @@ -105,7 +105,7 @@ export function getProjectAttachmentSignedURL(): RequestHandler { req_body: req.body }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/attachments/{attachmentId}/metadata/get.ts b/api/src/paths/project/{projectId}/attachments/{attachmentId}/metadata/get.ts index 82406071ef..f74d77b3c0 100644 --- a/api/src/paths/project/{projectId}/attachments/{attachmentId}/metadata/get.ts +++ b/api/src/paths/project/{projectId}/attachments/{attachmentId}/metadata/get.ts @@ -111,7 +111,7 @@ export function getProjectReportDetails(): RequestHandler { req_query: req.query }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/attachments/{attachmentId}/metadata/update.ts b/api/src/paths/project/{projectId}/attachments/{attachmentId}/metadata/update.ts index 5df56a9685..c93706c7f6 100644 --- a/api/src/paths/project/{projectId}/attachments/{attachmentId}/metadata/update.ts +++ b/api/src/paths/project/{projectId}/attachments/{attachmentId}/metadata/update.ts @@ -133,7 +133,7 @@ export function updateProjectAttachmentMetadata(): RequestHandler { req_body: req.body }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/delete.ts b/api/src/paths/project/{projectId}/delete.ts index d618a8f73f..ec801cca6d 100644 --- a/api/src/paths/project/{projectId}/delete.ts +++ b/api/src/paths/project/{projectId}/delete.ts @@ -75,7 +75,7 @@ export function deleteProject(): RequestHandler { throw new HTTP400('Missing required path param: `projectId`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const projectId = Number(req.params.projectId); try { diff --git a/api/src/paths/project/{projectId}/participants/index.ts b/api/src/paths/project/{projectId}/participants/index.ts index dc6a382c55..e07c97b0a1 100644 --- a/api/src/paths/project/{projectId}/participants/index.ts +++ b/api/src/paths/project/{projectId}/participants/index.ts @@ -93,7 +93,7 @@ export function getParticipants(): RequestHandler { throw new HTTP400('Missing required param `projectId`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const projectId = Number(req.params.projectId); @@ -235,7 +235,7 @@ export function postProjectParticipants(): RequestHandler { throw new HTTP400('Missing required body param `participants`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const participants: IParticipant[] = req.body.participants; diff --git a/api/src/paths/project/{projectId}/participants/self.ts b/api/src/paths/project/{projectId}/participants/self.ts index e3867b715b..fefb2b6aec 100644 --- a/api/src/paths/project/{projectId}/participants/self.ts +++ b/api/src/paths/project/{projectId}/participants/self.ts @@ -70,7 +70,7 @@ export function getSelf(): RequestHandler { throw new HTTP400("Missing required param 'projectId'"); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const projectId = Number(req.params.projectId); diff --git a/api/src/paths/project/{projectId}/participants/{projectParticipationId}.ts b/api/src/paths/project/{projectId}/participants/{projectParticipationId}.ts index 7609cf9f49..79255de1b2 100644 --- a/api/src/paths/project/{projectId}/participants/{projectParticipationId}.ts +++ b/api/src/paths/project/{projectId}/participants/{projectParticipationId}.ts @@ -101,7 +101,7 @@ export function putProjectParticipantRole(): RequestHandler { const projectParticipationId = Number(req.params.projectParticipationId); const roleId = Number(req.body.roleId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -234,7 +234,7 @@ export function deleteProjectParticipant(): RequestHandler { const projectId = Number(req.params.projectId); const projectParticipationId = Number(req.params.projectParticipationId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/create.ts b/api/src/paths/project/{projectId}/survey/create.ts index 4e3ba36794..9fd7b420be 100644 --- a/api/src/paths/project/{projectId}/survey/create.ts +++ b/api/src/paths/project/{projectId}/survey/create.ts @@ -176,7 +176,7 @@ export function createSurvey(): RequestHandler { const sanitizedPostSurveyData = new PostSurveyObject(req.body); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/index.test.ts b/api/src/paths/project/{projectId}/survey/index.test.ts index 8cd4d01167..682758b64f 100644 --- a/api/src/paths/project/{projectId}/survey/index.test.ts +++ b/api/src/paths/project/{projectId}/survey/index.test.ts @@ -24,7 +24,7 @@ describe('survey list', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq.params = { projectId: '1' }; @@ -72,7 +72,7 @@ describe('survey list', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); const projectId = 3; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq.params = { projectId: String(projectId) }; diff --git a/api/src/paths/project/{projectId}/survey/index.ts b/api/src/paths/project/{projectId}/survey/index.ts index 1f6ae88c4a..0a25ea3112 100644 --- a/api/src/paths/project/{projectId}/survey/index.ts +++ b/api/src/paths/project/{projectId}/survey/index.ts @@ -140,7 +140,7 @@ GET.apiDoc = { */ export function getSurveys(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts index f7a2d849c7..a289368dbc 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts @@ -146,7 +146,7 @@ export function uploadKeyxMedia(): RequestHandler { files: { ...rawMediaFile, buffer: 'Too big to print' } }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/list.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/list.ts index 8bd09bedd0..35b9dc44e6 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/list.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/list.ts @@ -258,7 +258,7 @@ export function getSurveyAttachments(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'Get attachments list', message: 'params', req_params: req.params }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const surveyId = Number(req.params.surveyId); try { diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/report/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/report/upload.ts index 0d3ad3ebf3..813e06bac5 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/report/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/report/upload.ts @@ -172,7 +172,7 @@ export function uploadMedia(): RequestHandler { files: { ...rawMediaFile, buffer: 'Too big to print' } }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/upload.ts index 939971660f..1135be46af 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/upload.ts @@ -121,7 +121,7 @@ export function uploadMedia(): RequestHandler { files: { ...rawMediaFile, buffer: 'Too big to print' } }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/delete.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/delete.ts index 9a5c0bfe29..ca50846f80 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/delete.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/delete.ts @@ -102,7 +102,7 @@ export function deleteAttachment(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'Delete attachment', message: 'params', req_params: req.params }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/getSignedUrl.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/getSignedUrl.ts index 84cfb29a7b..d28ae2ab70 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/getSignedUrl.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/getSignedUrl.ts @@ -118,7 +118,7 @@ export function getSurveyAttachmentSignedURL(): RequestHandler { req_body: req.body }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/metadata/get.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/metadata/get.ts index 4e712c424c..02496f335c 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/metadata/get.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/metadata/get.ts @@ -121,7 +121,7 @@ export function getSurveyReportDetails(): RequestHandler { req_query: req.query }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/metadata/update.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/metadata/update.ts index 981f7b8e10..01fbc1077d 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/metadata/update.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/{attachmentId}/metadata/update.ts @@ -139,7 +139,7 @@ export function updateSurveyReportMetadata(): RequestHandler { req_body: req.body }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/delete.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/delete.ts index d4b0f7d6cc..a20ba8ef23 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/delete.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/delete.ts @@ -94,7 +94,7 @@ export function removeCrittersFromSurvey(): RequestHandler { const critterIds = req.body.critterIds; const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/import.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/import.ts index ed1e690c52..feb1970c5c 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/import.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/import.ts @@ -128,7 +128,7 @@ export function importCsv(): RequestHandler { const rawFiles = req.files as Express.Multer.File[]; const rawFile = rawFiles[0]; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts index 13246cee5c..9c6729d605 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts @@ -209,7 +209,7 @@ export function getCrittersFromSurvey(): RequestHandler { }; const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -258,7 +258,7 @@ export function addCritterToSurvey(): RequestHandler { const surveyId = Number(req.params.surveyId); let critterId = req.body.critter_id; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts index ffa3837792..d08acc83d3 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts @@ -93,7 +93,7 @@ export function updateSurveyCritter(): RequestHandler { const critterId = Number(req.params.critterId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { if (!critterbaseCritterId) { throw new HTTPError(HTTPErrorType.BAD_REQUEST, 400, 'No external critter ID was found.'); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts index 6f23d36217..de4e0f3cd2 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts @@ -249,7 +249,7 @@ export function deployDevice(): RequestHandler { deploymentId: newDeploymentId }; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -281,7 +281,7 @@ export function updateDeployment(): RequestHandler { }; const critterId = Number(req.params.critterId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts index d98ee990a1..c81bd16ebd 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts @@ -112,7 +112,7 @@ export function deleteDeployment(): RequestHandler { const deploymentId = String(req.params.bctwDeploymentId); const critterId = Number(req.params.critterId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts index 7fbf63de05..7fad5b15f6 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts @@ -265,7 +265,7 @@ export function getCritterTelemetry(): RequestHandler { const critterId = Number(req.params.critterId); const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/delete.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/delete.ts index 97cf594a20..2c3e507bea 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/delete.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/delete.ts @@ -82,7 +82,7 @@ export function deleteSurvey(): RequestHandler { return async (req, res) => { const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts index 211a072412..cf31154f43 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts @@ -92,7 +92,7 @@ export function getDeploymentsInSurvey(): RequestHandler { }; const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/delete.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/delete.ts index 00bbfa02b2..f0008aa54b 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/delete.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/delete.ts @@ -130,7 +130,7 @@ export function deleteSurveyObservations(): RequestHandler { defaultLog.debug({ label: 'deleteSurveyObservations', surveyId }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/environments/delete.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/environments/delete.ts index 2642ee34ef..4ea8c3b84f 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/environments/delete.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/environments/delete.ts @@ -115,7 +115,7 @@ POST.apiDoc = { */ export function deleteObservationEnvironments(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const surveyId = Number(req.params.surveyId); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts index 49aa7688bd..a587ce3cc8 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts @@ -373,7 +373,7 @@ export function getSurveyObservations(): RequestHandler { const paginationOptions: Partial = { page, limit, order, sort }; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -416,7 +416,7 @@ export function putObservations(): RequestHandler { defaultLog.debug({ label: 'insertUpdateSurveyObservations', surveyId }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/measurements/delete.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/measurements/delete.ts index 03767daeb8..59894c1779 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/measurements/delete.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/measurements/delete.ts @@ -112,7 +112,7 @@ export function deleteObservationMeasurements(): RequestHandler { defaultLog.debug({ label: 'deleteObservationMeasurements', surveyId }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/process.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/process.ts index 8c9ad329f2..d4cc63c64a 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/process.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/process.ts @@ -103,7 +103,7 @@ export function processFile(): RequestHandler { const surveyId = Number(req.params.surveyId); const submissionId = req.body.observation_submission_id; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/spatial.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/spatial.ts index b9ac787336..1492421197 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/spatial.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/spatial.ts @@ -250,7 +250,7 @@ export function getSurveyObservationsGeometry(): RequestHandler { defaultLog.debug({ label: 'getSurveyObservationsGeometry', surveyId }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/upload.ts index e7eb310283..64a420a58e 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/upload.ts @@ -122,7 +122,7 @@ export function uploadMedia(): RequestHandler { throw new HTTP400('Too many files uploaded, expected 1'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const rawMediaFile = rawMediaArray[0]; diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/{surveyObservationId}/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/{surveyObservationId}/index.ts index 234633a6e6..f7e7fe4a16 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/{surveyObservationId}/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/{surveyObservationId}/index.ts @@ -194,7 +194,7 @@ export function getSurveyObservation(): RequestHandler { defaultLog.debug({ label: 'getSurveyObservation', surveyObservationId }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/participants/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/participants/index.ts index 54b16e4f5c..ea5af0daf4 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/participants/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/participants/index.ts @@ -124,7 +124,7 @@ export function getSurveyParticipants(): RequestHandler { throw new HTTP400('Missing required param `surveyId`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const surveyId = Number(req.params.surveyId); @@ -258,7 +258,7 @@ export function createSurveyParticipants(): RequestHandler { throw new HTTP400('Missing required body param `participants`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const participants: ISurveyParticipationPostData[] = req.body.participants; diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/participants/{surveyParticipationId}.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/participants/{surveyParticipationId}.ts index 27b2b2dde8..9e98e5c334 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/participants/{surveyParticipationId}.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/participants/{surveyParticipationId}.ts @@ -107,7 +107,7 @@ export function updateSurveyParticipantRole(): RequestHandler { const surveyParticipationId = Number(req.params.surveyParticipationId); const { surveyJobName } = req.body; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -212,7 +212,7 @@ export function deleteSurveyParticipant(): RequestHandler { const surveyId = Number(req.params.surveyId); const surveyParticipationId = Number(req.params.surveyParticipationId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/delete.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/delete.ts index 8658d99cd8..b8df9c0512 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/delete.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/delete.ts @@ -108,7 +108,7 @@ export function deleteSurveySampleSiteRecords(): RequestHandler { throw new HTTP400('Missing required body `surveySampleSiteIds`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/index.ts index d98c7416b9..398ae73b42 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/index.ts @@ -269,7 +269,7 @@ export function getSurveySampleLocationRecord(): RequestHandler { throw new HTTP400('Missing required param `surveyId`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -570,7 +570,7 @@ export function createSurveySampleSiteRecord(): RequestHandler { throw new HTTP400('Missing required path param `surveyId`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const sampleSite: PostSampleLocations = { diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/index.ts index 4cdb8d8984..ad019f5394 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/index.ts @@ -235,7 +235,7 @@ export function updateSurveySampleSite(): RequestHandler { } const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const sampleSite: UpdateSampleLocationRecord = { @@ -350,7 +350,7 @@ export function deleteSurveySampleSiteRecord(): RequestHandler { throw new HTTP400('Missing required param `surveySampleSiteId`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -620,7 +620,7 @@ export function getSurveySampleLocationRecord(): RequestHandler { throw new HTTP400('Missing required param `surveySampleSiteId`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/index.ts index 2d5bc3c71f..6acf2fe4b0 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/index.ts @@ -157,7 +157,7 @@ export function getSurveySampleMethodRecords(): RequestHandler { const surveySampleSiteId = Number(req.params.surveySampleSiteId); const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -294,7 +294,7 @@ export function createSurveySampleSiteRecord(): RequestHandler { const surveyId = Number(req.params.surveyId); const surveySampleSiteId = Number(req.params.surveySampleSiteId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const sampleSiteService = new SampleLocationService(connection); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/index.ts index 9621af8fd7..3685cd5fbb 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/index.ts @@ -129,7 +129,7 @@ export function updateSurveySampleMethod(): RequestHandler { } const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const sampleMethod: UpdateSampleMethodRecord = { @@ -243,7 +243,7 @@ export function deleteSurveySampleMethodRecord(): RequestHandler { } const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/sample-period/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/sample-period/index.ts index 28919744e1..305ea168cd 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/sample-period/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/sample-period/index.ts @@ -165,7 +165,7 @@ export function getSurveySamplePeriodRecords(): RequestHandler { const surveyId = Number(req.params.surveyId); const surveySampleMethodId = Number(req.params.surveySampleMethodId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); @@ -304,7 +304,7 @@ export function createSurveySamplePeriodRecord(): RequestHandler { throw new HTTP400('Missing required body param `samplePeriod`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const samplePeriod: InsertSamplePeriodRecord = { diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/sample-period/{surveySamplePeriodId}.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/sample-period/{surveySamplePeriodId}.ts index 7283bdbd51..2fd67f1684 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/sample-period/{surveySamplePeriodId}.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/sample-site/{surveySampleSiteId}/sample-method/{surveySampleMethodId}/sample-period/{surveySamplePeriodId}.ts @@ -147,7 +147,7 @@ export function updateSurveySamplePeriod(): RequestHandler { } const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const samplePeriod: UpdateSamplePeriodRecord = { @@ -280,7 +280,7 @@ export function deleteSurveySamplePeriodRecord(): RequestHandler { throw new HTTP400('Missing required param `surveySamplePeriodId`'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/telemetry/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/telemetry/upload.ts index d04d97b1d8..5bb1144379 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/telemetry/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/telemetry/upload.ts @@ -121,7 +121,7 @@ export function uploadMedia(): RequestHandler { throw new HTTP400('Too many files uploaded, expected 1'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const rawMediaFile = rawMediaArray[0]; diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/update.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/update.ts index 254344857e..9e3ce263c3 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/update.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/update.ts @@ -183,7 +183,7 @@ export function updateSurvey(): RequestHandler { const sanitizedPutSurveyData = new PutSurveyObject(req.body); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/update/get.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/update/get.ts index 16bbe41a3b..a1ab70d232 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/update/get.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/update/get.ts @@ -171,7 +171,7 @@ export function getSurveyForUpdate(): RequestHandler { return async (req, res) => { const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/view.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/view.ts index 6fb775be48..6c2cb398d7 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/view.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/view.ts @@ -157,7 +157,7 @@ export function getSurvey(): RequestHandler { return async (req, res) => { const surveyId = Number(req.params.surveyId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/project/{projectId}/update.ts b/api/src/paths/project/{projectId}/update.ts index 209cb0230a..8e87f68f16 100644 --- a/api/src/paths/project/{projectId}/update.ts +++ b/api/src/paths/project/{projectId}/update.ts @@ -185,7 +185,7 @@ GET.apiDoc = { */ export function getProjectForUpdate(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const projectId = Number(req.params?.projectId); @@ -301,7 +301,7 @@ export interface IUpdateProject { */ export function updateProject(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const projectId = Number(req.params?.projectId); diff --git a/api/src/paths/project/{projectId}/view.ts b/api/src/paths/project/{projectId}/view.ts index af1c845de1..73a6e22987 100644 --- a/api/src/paths/project/{projectId}/view.ts +++ b/api/src/paths/project/{projectId}/view.ts @@ -174,7 +174,7 @@ GET.apiDoc = { */ export function viewProject(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/publish/attachment/resubmit.ts b/api/src/paths/publish/attachment/resubmit.ts index ff80f20e5e..aea21f730f 100644 --- a/api/src/paths/publish/attachment/resubmit.ts +++ b/api/src/paths/publish/attachment/resubmit.ts @@ -113,7 +113,7 @@ POST.apiDoc = { // @TODO is this endpoint needed anymore? Do we submit attachments on their own? export function resubmitAttachment(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const resubmitData = req.body; diff --git a/api/src/paths/publish/survey.ts b/api/src/paths/publish/survey.ts index 99fb728161..4059c98833 100644 --- a/api/src/paths/publish/survey.ts +++ b/api/src/paths/publish/survey.ts @@ -125,7 +125,7 @@ POST.apiDoc = { */ export function publishSurvey(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); const { surveyId, data } = req.body; diff --git a/api/src/paths/spatial/regions.ts b/api/src/paths/spatial/regions.ts index 7bd4d05ed7..42e113cd20 100644 --- a/api/src/paths/spatial/regions.ts +++ b/api/src/paths/spatial/regions.ts @@ -110,7 +110,7 @@ POST.apiDoc = { */ export function getRegions(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const features = req.body.features as Feature[]; diff --git a/api/src/paths/standards/taxon/{tsn}/index.ts b/api/src/paths/standards/taxon/{tsn}/index.ts index 1c08b78ead..a46bb597a1 100644 --- a/api/src/paths/standards/taxon/{tsn}/index.ts +++ b/api/src/paths/standards/taxon/{tsn}/index.ts @@ -200,7 +200,7 @@ GET.apiDoc = { export function getSpeciesStandards(): RequestHandler { return async (req, res) => { // TODO: const connection = getAPIUserDBConnection(); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const tsn = Number(req.params.tsn); diff --git a/api/src/paths/survey/index.test.ts b/api/src/paths/survey/index.test.ts index c9a7f502b3..a6dc37560a 100644 --- a/api/src/paths/survey/index.test.ts +++ b/api/src/paths/survey/index.test.ts @@ -59,7 +59,7 @@ describe('findSurveys', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -125,7 +125,7 @@ describe('findSurveys', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/survey/index.ts b/api/src/paths/survey/index.ts index a68d30ded4..0be1fef5c8 100644 --- a/api/src/paths/survey/index.ts +++ b/api/src/paths/survey/index.ts @@ -219,7 +219,7 @@ export function findSurveys(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'findSurveys' }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/telemetry/index.test.ts b/api/src/paths/telemetry/index.test.ts index 9700ce479c..bde6472c08 100644 --- a/api/src/paths/telemetry/index.test.ts +++ b/api/src/paths/telemetry/index.test.ts @@ -57,7 +57,7 @@ describe('findTelemetry', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -103,7 +103,7 @@ describe('findTelemetry', () => { sort: undefined, order: undefined }; - mockReq['keycloak_token'] = {}; + mockreq.keycloak_token = {}; mockReq['system_user'] = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/telemetry/index.ts b/api/src/paths/telemetry/index.ts index a95c986d40..8328d4f63c 100644 --- a/api/src/paths/telemetry/index.ts +++ b/api/src/paths/telemetry/index.ts @@ -185,7 +185,7 @@ export function findTelemetry(): RequestHandler { return async (req, res) => { defaultLog.debug({ label: 'findTelemetry' }); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/telemetry/manual/process.ts b/api/src/paths/telemetry/manual/process.ts index 35a2889234..97c5423824 100644 --- a/api/src/paths/telemetry/manual/process.ts +++ b/api/src/paths/telemetry/manual/process.ts @@ -97,7 +97,7 @@ export function processFile(): RequestHandler { keycloak_guid: req['system_user']?.user_guid, username: req['system_user']?.user_identifier }; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/user/add.ts b/api/src/paths/user/add.ts index abfdb376f2..91b1716d1a 100644 --- a/api/src/paths/user/add.ts +++ b/api/src/paths/user/add.ts @@ -132,11 +132,11 @@ export function addSystemRoleUser(): RequestHandler { const family_name: string = req.body?.family_name; const role_name: string = req.body?.role_name; - const sourceSystem = getKeycloakSource(req['keycloak_token']); + const sourceSystem = getKeycloakSource(req.keycloak_token); const connection = sourceSystem ? getServiceClientDBConnection(sourceSystem) - : getDBConnection(req['keycloak_token']); + : getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/user/index.ts b/api/src/paths/user/index.ts index 8a9fae74fe..189c549413 100644 --- a/api/src/paths/user/index.ts +++ b/api/src/paths/user/index.ts @@ -78,7 +78,7 @@ GET.apiDoc = { */ export function getUsers(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/user/list.ts b/api/src/paths/user/list.ts index a4e8ab5f9f..a209757717 100644 --- a/api/src/paths/user/list.ts +++ b/api/src/paths/user/list.ts @@ -70,7 +70,7 @@ GET.apiDoc = { */ export function getUserList(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/user/self.ts b/api/src/paths/user/self.ts index 3ea154a5cf..9a1333f893 100644 --- a/api/src/paths/user/self.ts +++ b/api/src/paths/user/self.ts @@ -66,7 +66,7 @@ GET.apiDoc = { */ export function getUser(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/user/{userId}/delete.ts b/api/src/paths/user/{userId}/delete.ts index f6bccd9db6..750a7df35e 100644 --- a/api/src/paths/user/{userId}/delete.ts +++ b/api/src/paths/user/{userId}/delete.ts @@ -71,7 +71,7 @@ export function removeSystemUser(): RequestHandler { const systemUserId = req.params && Number(req.params.userId); - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/user/{userId}/get.ts b/api/src/paths/user/{userId}/get.ts index e1ad449945..e27063ac01 100644 --- a/api/src/paths/user/{userId}/get.ts +++ b/api/src/paths/user/{userId}/get.ts @@ -157,7 +157,7 @@ GET.apiDoc = { */ export function getUserById(): RequestHandler { return async (req, res) => { - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const userId = Number(req.params.userId); diff --git a/api/src/paths/user/{userId}/projects/get.ts b/api/src/paths/user/{userId}/projects/get.ts index 8eadddf72d..6908d366e2 100644 --- a/api/src/paths/user/{userId}/projects/get.ts +++ b/api/src/paths/user/{userId}/projects/get.ts @@ -133,7 +133,7 @@ export function getAllUserProjects(): RequestHandler { throw new HTTP400('Missing required param: userId'); } - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { const userId = Number(req.params.userId); diff --git a/api/src/paths/user/{userId}/system-roles/update.ts b/api/src/paths/user/{userId}/system-roles/update.ts index e7ea062c5c..eba23a85bc 100644 --- a/api/src/paths/user/{userId}/system-roles/update.ts +++ b/api/src/paths/user/{userId}/system-roles/update.ts @@ -97,7 +97,7 @@ export function updateSystemRolesHandler(): RequestHandler { const userId = Number(req.params.userId); const roles: number[] = req.body.roles; - const connection = getDBConnection(req['keycloak_token']); + const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/request-handlers/security/authorization.ts b/api/src/request-handlers/security/authorization.ts index 2f5bc5ec9c..166a824769 100644 --- a/api/src/request-handlers/security/authorization.ts +++ b/api/src/request-handlers/security/authorization.ts @@ -57,7 +57,7 @@ export const authorizeRequest = async (req: Request): Promise => { const authorizationService = new AuthorizationService(connection, { systemUser: req['system_user'], - keycloakToken: req['keycloak_token'] + keycloakToken: req.keycloak_token }); const isAuthorized = From 5509bcd3fbb5cdfb0bc151ed846463fd291e34b7 Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 19 Jul 2024 15:47:02 -0700 Subject: [PATCH 03/13] fix: updated req['auth_payload'] -> req.keycloak_token --- .../paths/project/{projectId}/attachments/report/upload.ts | 4 ++-- api/src/paths/project/{projectId}/attachments/upload.ts | 4 ++-- .../{projectId}/survey/{surveyId}/attachments/keyx/upload.ts | 4 ++-- .../survey/{surveyId}/attachments/report/upload.ts | 4 ++-- .../{projectId}/survey/{surveyId}/attachments/upload.ts | 4 ++-- .../{projectId}/survey/{surveyId}/observations/upload.ts | 4 ++-- .../project/{projectId}/survey/{surveyId}/telemetry/upload.ts | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/api/src/paths/project/{projectId}/attachments/report/upload.ts b/api/src/paths/project/{projectId}/attachments/report/upload.ts index 592079239a..8e1083b673 100644 --- a/api/src/paths/project/{projectId}/attachments/report/upload.ts +++ b/api/src/paths/project/{projectId}/attachments/report/upload.ts @@ -179,8 +179,8 @@ export function uploadMedia(): RequestHandler { // Upload file to S3 const metadata = { filename: rawMediaFile.originalname, - username: (req['auth_payload'] && req['auth_payload'].preferred_username) || '', - email: (req['auth_payload'] && req['auth_payload'].email) || '' + username: (req.keycloak_token && req.keycloak_token.preferred_username) || '', + email: (req.keycloak_token && req.keycloak_token.email) || '' }; await uploadFileToS3(rawMediaFile, upsertResult.key, metadata); diff --git a/api/src/paths/project/{projectId}/attachments/upload.ts b/api/src/paths/project/{projectId}/attachments/upload.ts index 6a74324613..4d5b90c8eb 100644 --- a/api/src/paths/project/{projectId}/attachments/upload.ts +++ b/api/src/paths/project/{projectId}/attachments/upload.ts @@ -153,8 +153,8 @@ export function uploadMedia(): RequestHandler { // Upload file to S3 const metadata = { filename: rawMediaFile.originalname, - username: (req['auth_payload'] && req['auth_payload'].preferred_username) || '', - email: (req['auth_payload'] && req['auth_payload'].email) || '' + username: (req.keycloak_token && req.keycloak_token.preferred_username) || '', + email: (req.keycloak_token && req.keycloak_token.email) || '' }; await uploadFileToS3(rawMediaFile, upsertResult.key, metadata); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts index a289368dbc..d89843dcbb 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts @@ -182,8 +182,8 @@ export function uploadKeyxMedia(): RequestHandler { const metadata = { filename: rawMediaFile.originalname, - username: req['auth_payload']?.preferred_username ?? '', - email: req['auth_payload']?.email ?? '' + username: req.keycloak_token?.preferred_username ?? '', + email: req.keycloak_token?.email ?? '' }; const result = await uploadFileToS3(rawMediaFile, upsertResult.key, metadata); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/report/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/report/upload.ts index 813e06bac5..c5849ffb56 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/report/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/report/upload.ts @@ -195,8 +195,8 @@ export function uploadMedia(): RequestHandler { const metadata = { filename: rawMediaFile.originalname, - username: (req['auth_payload'] && req['auth_payload'].preferred_username) || '', - email: (req['auth_payload'] && req['auth_payload'].email) || '' + username: (req.keycloak_token && req.keycloak_token.preferred_username) || '', + email: (req.keycloak_token && req.keycloak_token.email) || '' }; const result = await uploadFileToS3(rawMediaFile, upsertResult.key, metadata); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/upload.ts index 1135be46af..bc91c9714b 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/upload.ts @@ -144,8 +144,8 @@ export function uploadMedia(): RequestHandler { const metadata = { filename: rawMediaFile.originalname, - username: (req['auth_payload'] && req['auth_payload'].preferred_username) || '', - email: (req['auth_payload'] && req['auth_payload'].email) || '' + username: (req.keycloak_token && req.keycloak_token.preferred_username) || '', + email: (req.keycloak_token && req.keycloak_token.email) || '' }; const result = await uploadFileToS3(rawMediaFile, upsertResult.key, metadata); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/upload.ts index 64a420a58e..e154015d3e 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/upload.ts @@ -151,8 +151,8 @@ export function uploadMedia(): RequestHandler { // Upload file to S3 const metadata = { filename: rawMediaFile.originalname, - username: req['auth_payload']?.preferred_username ?? '', - email: req['auth_payload']?.email ?? '' + username: req.keycloak_token?.preferred_username ?? '', + email: req.keycloak_token?.email ?? '' }; const result = await uploadFileToS3(rawMediaFile, key, metadata); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/telemetry/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/telemetry/upload.ts index 5bb1144379..dab809bebc 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/telemetry/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/telemetry/upload.ts @@ -150,8 +150,8 @@ export function uploadMedia(): RequestHandler { // Upload file to S3 const metadata = { filename: rawMediaFile.originalname, - username: req['auth_payload']?.preferred_username ?? '', - email: req['auth_payload']?.email ?? '' + username: req.keycloak_token?.preferred_username ?? '', + email: req.keycloak_token?.email ?? '' }; const result = await uploadFileToS3(rawMediaFile, key, metadata); From fe46b70a7ee9eefcae8b7f17546e793834c5690c Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 19 Jul 2024 15:48:09 -0700 Subject: [PATCH 04/13] fix: repaced req['system_user'] -> req.system_user --- api/src/middleware/critterbase-proxy.ts | 4 ++-- api/src/paths/animal/index.test.ts | 4 ++-- api/src/paths/animal/index.ts | 2 +- api/src/paths/funding-sources/index.test.ts | 4 ++-- api/src/paths/funding-sources/index.ts | 2 +- api/src/paths/observation/index.test.ts | 4 ++-- api/src/paths/observation/index.ts | 2 +- api/src/paths/project/index.test.ts | 4 ++-- api/src/paths/project/index.ts | 2 +- .../survey/{surveyId}/attachments/keyx/upload.ts | 4 ++-- .../{projectId}/survey/{surveyId}/critters/index.ts | 8 ++++---- .../{projectId}/survey/{surveyId}/critters/{critterId}.ts | 4 ++-- .../{surveyId}/critters/{critterId}/deployments/index.ts | 8 ++++---- .../{critterId}/deployments/{bctwDeploymentId}.ts | 4 ++-- .../survey/{surveyId}/critters/{critterId}/telemetry.ts | 4 ++-- .../project/{projectId}/survey/{surveyId}/deployments.ts | 4 ++-- .../{projectId}/survey/{surveyId}/observations/index.ts | 4 ++-- api/src/paths/survey/index.test.ts | 4 ++-- api/src/paths/survey/index.ts | 2 +- api/src/paths/telemetry/code.ts | 4 ++-- api/src/paths/telemetry/device/index.ts | 4 ++-- api/src/paths/telemetry/device/{deviceId}.ts | 4 ++-- api/src/paths/telemetry/index.test.ts | 4 ++-- api/src/paths/telemetry/index.ts | 2 +- api/src/paths/telemetry/manual/delete.ts | 4 ++-- api/src/paths/telemetry/manual/process.ts | 4 ++-- api/src/paths/telemetry/vendors.ts | 4 ++-- api/src/request-handlers/security/authorization.ts | 4 ++-- api/src/services/bctw-service.ts | 4 ++-- 29 files changed, 56 insertions(+), 56 deletions(-) diff --git a/api/src/middleware/critterbase-proxy.ts b/api/src/middleware/critterbase-proxy.ts index f703ec619c..b8d189df9f 100644 --- a/api/src/middleware/critterbase-proxy.ts +++ b/api/src/middleware/critterbase-proxy.ts @@ -165,8 +165,8 @@ export const getCritterbaseProxyMiddleware = () => client.setHeader( 'user', JSON.stringify({ - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }) ); }, diff --git a/api/src/paths/animal/index.test.ts b/api/src/paths/animal/index.test.ts index 09e061154a..6a40874aa7 100644 --- a/api/src/paths/animal/index.test.ts +++ b/api/src/paths/animal/index.test.ts @@ -60,7 +60,7 @@ describe('findAnimals', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -127,7 +127,7 @@ describe('findAnimals', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/animal/index.ts b/api/src/paths/animal/index.ts index e2177196cc..5b37392ef5 100644 --- a/api/src/paths/animal/index.ts +++ b/api/src/paths/animal/index.ts @@ -193,7 +193,7 @@ export function findAnimals(): RequestHandler { const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req['system_user']['role_names'] + req.system_user['role_names'] ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/funding-sources/index.test.ts b/api/src/paths/funding-sources/index.test.ts index 5f48c22b4f..6c3ad68c8a 100644 --- a/api/src/paths/funding-sources/index.test.ts +++ b/api/src/paths/funding-sources/index.test.ts @@ -67,7 +67,7 @@ describe('getFundingSources', () => { agency: null }; // system_user would be set by the authorization-service, if this endpoint was called for real - mockReq['system_user'] = systemUser; + mockreq.system_user = systemUser; const requestHandler = getFundingSources(); @@ -128,7 +128,7 @@ describe('getFundingSources', () => { agency: null }; // system_user would be set by the authorization-service, if this endpoint was called for real - mockReq['system_user'] = systemUser; + mockreq.system_user = systemUser; const requestHandler = getFundingSources(); diff --git a/api/src/paths/funding-sources/index.ts b/api/src/paths/funding-sources/index.ts index b633fd9533..a6a9833b62 100644 --- a/api/src/paths/funding-sources/index.ts +++ b/api/src/paths/funding-sources/index.ts @@ -124,7 +124,7 @@ export function getFundingSources(): RequestHandler { await connection.commit(); - const systemUserObject: SystemUser = req['system_user']; + const systemUserObject: SystemUser = req.system_user; if (!UserService.isAdmin(systemUserObject)) { // User is not an admin, strip sensitive fields from response response = removeNonAdminFieldsFromFundingSourcesResponse(response); diff --git a/api/src/paths/observation/index.test.ts b/api/src/paths/observation/index.test.ts index 5eda7fe56a..b0616cd9dd 100644 --- a/api/src/paths/observation/index.test.ts +++ b/api/src/paths/observation/index.test.ts @@ -80,7 +80,7 @@ describe('findObservations', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -173,7 +173,7 @@ describe('findObservations', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/observation/index.ts b/api/src/paths/observation/index.ts index 30fbbd3b45..611dea6b96 100644 --- a/api/src/paths/observation/index.ts +++ b/api/src/paths/observation/index.ts @@ -178,7 +178,7 @@ export function findObservations(): RequestHandler { const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req['system_user']['role_names'] + req.system_user['role_names'] ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/project/index.test.ts b/api/src/paths/project/index.test.ts index 12b2a2da85..3ab28e91fd 100644 --- a/api/src/paths/project/index.test.ts +++ b/api/src/paths/project/index.test.ts @@ -56,7 +56,7 @@ describe('findProjects', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -118,7 +118,7 @@ describe('findProjects', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/project/index.ts b/api/src/paths/project/index.ts index 779a91b07c..b3aac48029 100644 --- a/api/src/paths/project/index.ts +++ b/api/src/paths/project/index.ts @@ -192,7 +192,7 @@ export function findProjects(): RequestHandler { const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req['system_user']['role_names'] + req.system_user['role_names'] ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts index d89843dcbb..8a67c20968 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts @@ -164,8 +164,8 @@ export function uploadKeyxMedia(): RequestHandler { } const user: IBctwUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const bctwService = new BctwService(user); const bctwUploadResult = await bctwService.uploadKeyX(rawMediaFile); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts index 9c6729d605..f138cd2791 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts @@ -204,8 +204,8 @@ POST.apiDoc = { export function getCrittersFromSurvey(): RequestHandler { return async (req, res) => { const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const surveyId = Number(req.params.surveyId); @@ -251,8 +251,8 @@ export function getCrittersFromSurvey(): RequestHandler { export function addCritterToSurvey(): RequestHandler { return async (req, res) => { const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const surveyId = Number(req.params.surveyId); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts index d08acc83d3..63c4888f2c 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts @@ -86,8 +86,8 @@ PATCH.apiDoc = { export function updateSurveyCritter(): RequestHandler { return async (req, res) => { const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const critterbaseCritterId = req.body.update.critter_id; diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts index de4e0f3cd2..9928a049c9 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts @@ -238,8 +238,8 @@ PATCH.apiDoc = { export function deployDevice(): RequestHandler { return async (req, res) => { const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const critterId = Number(req.params.critterId); @@ -276,8 +276,8 @@ export function deployDevice(): RequestHandler { export function updateDeployment(): RequestHandler { return async (req, res) => { const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const critterId = Number(req.params.critterId); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts index c81bd16ebd..e515a7c6e2 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts @@ -105,8 +105,8 @@ DELETE.apiDoc = { export function deleteDeployment(): RequestHandler { return async (req, res) => { const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const deploymentId = String(req.params.bctwDeploymentId); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts index 7fad5b15f6..bfa2363f8c 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts @@ -258,8 +258,8 @@ GET.apiDoc = { export function getCritterTelemetry(): RequestHandler { return async (req, res) => { const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const critterId = Number(req.params.critterId); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts index cf31154f43..118a457f1f 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts @@ -87,8 +87,8 @@ GET.apiDoc = { export function getDeploymentsInSurvey(): RequestHandler { return async (req, res) => { const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const surveyId = Number(req.params.surveyId); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts index a587ce3cc8..305e91e3a2 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts @@ -426,8 +426,8 @@ export function putObservations(): RequestHandler { const observationRows: InsertUpdateObservations[] = req.body.surveyObservations; const critterBaseService = new CritterbaseService({ - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }); // Validate measurement data against fetched measurement definition diff --git a/api/src/paths/survey/index.test.ts b/api/src/paths/survey/index.test.ts index a6dc37560a..1a855c5d8f 100644 --- a/api/src/paths/survey/index.test.ts +++ b/api/src/paths/survey/index.test.ts @@ -60,7 +60,7 @@ describe('findSurveys', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -126,7 +126,7 @@ describe('findSurveys', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/survey/index.ts b/api/src/paths/survey/index.ts index 0be1fef5c8..466880a7ae 100644 --- a/api/src/paths/survey/index.ts +++ b/api/src/paths/survey/index.ts @@ -228,7 +228,7 @@ export function findSurveys(): RequestHandler { const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req['system_user']['role_names'] + req.system_user['role_names'] ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/telemetry/code.ts b/api/src/paths/telemetry/code.ts index 165816e39b..0038266d93 100644 --- a/api/src/paths/telemetry/code.ts +++ b/api/src/paths/telemetry/code.ts @@ -71,8 +71,8 @@ GET.apiDoc = { export function getCodeValues(): RequestHandler { return async (req, res) => { const user: IBctwUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const bctwService = new BctwService(user); const codeHeader = String(req.query.codeHeader); diff --git a/api/src/paths/telemetry/device/index.ts b/api/src/paths/telemetry/device/index.ts index fe6d9efb9f..c42ed0ffb5 100644 --- a/api/src/paths/telemetry/device/index.ts +++ b/api/src/paths/telemetry/device/index.ts @@ -93,8 +93,8 @@ POST.apiDoc = { export function upsertDevice(): RequestHandler { return async (req, res) => { const user: IBctwUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const bctwService = new BctwService(user); try { diff --git a/api/src/paths/telemetry/device/{deviceId}.ts b/api/src/paths/telemetry/device/{deviceId}.ts index 3d9dd11233..950aa0dcae 100644 --- a/api/src/paths/telemetry/device/{deviceId}.ts +++ b/api/src/paths/telemetry/device/{deviceId}.ts @@ -59,8 +59,8 @@ GET.apiDoc = { export function getDeviceDetails(): RequestHandler { return async (req, res) => { const user: IBctwUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const bctwService = new BctwService(user); const deviceId = Number(req.params.deviceId); diff --git a/api/src/paths/telemetry/index.test.ts b/api/src/paths/telemetry/index.test.ts index bde6472c08..9aef4b0748 100644 --- a/api/src/paths/telemetry/index.test.ts +++ b/api/src/paths/telemetry/index.test.ts @@ -58,7 +58,7 @@ describe('findTelemetry', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -104,7 +104,7 @@ describe('findTelemetry', () => { order: undefined }; mockreq.keycloak_token = {}; - mockReq['system_user'] = { + mockreq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/telemetry/index.ts b/api/src/paths/telemetry/index.ts index 8328d4f63c..daac1256cc 100644 --- a/api/src/paths/telemetry/index.ts +++ b/api/src/paths/telemetry/index.ts @@ -194,7 +194,7 @@ export function findTelemetry(): RequestHandler { const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req['system_user']['role_names'] + req.system_user['role_names'] ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/telemetry/manual/delete.ts b/api/src/paths/telemetry/manual/delete.ts index 2fd6b68173..e916ab15c9 100644 --- a/api/src/paths/telemetry/manual/delete.ts +++ b/api/src/paths/telemetry/manual/delete.ts @@ -51,8 +51,8 @@ POST.apiDoc = { export function deleteManualTelemetry(): RequestHandler { return async (req, res) => { const user: IBctwUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const bctwService = new BctwService(user); try { diff --git a/api/src/paths/telemetry/manual/process.ts b/api/src/paths/telemetry/manual/process.ts index 97c5423824..b96b0c36c6 100644 --- a/api/src/paths/telemetry/manual/process.ts +++ b/api/src/paths/telemetry/manual/process.ts @@ -94,8 +94,8 @@ export function processFile(): RequestHandler { return async (req, res) => { const submissionId = req.body.submission_id; const user: ICritterbaseUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const connection = getDBConnection(req.keycloak_token); try { diff --git a/api/src/paths/telemetry/vendors.ts b/api/src/paths/telemetry/vendors.ts index 2f8ad336dd..b0e72b2581 100644 --- a/api/src/paths/telemetry/vendors.ts +++ b/api/src/paths/telemetry/vendors.ts @@ -62,8 +62,8 @@ GET.apiDoc = { export function getCollarVendors(): RequestHandler { return async (req, res) => { const user: IBctwUser = { - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }; const bctwService = new BctwService(user); try { diff --git a/api/src/request-handlers/security/authorization.ts b/api/src/request-handlers/security/authorization.ts index 166a824769..da17976f6e 100644 --- a/api/src/request-handlers/security/authorization.ts +++ b/api/src/request-handlers/security/authorization.ts @@ -56,7 +56,7 @@ export const authorizeRequest = async (req: Request): Promise => { await connection.open(); const authorizationService = new AuthorizationService(connection, { - systemUser: req['system_user'], + systemUser: req.system_user, keycloakToken: req.keycloak_token }); @@ -65,7 +65,7 @@ export const authorizeRequest = async (req: Request): Promise => { (await authorizationService.executeAuthorizationScheme(authorizationScheme)); // Add the system_user to the request for future use, if needed - req['system_user'] = authorizationService._systemUser; + req.system_user = authorizationService._systemUser; await connection.commit(); diff --git a/api/src/services/bctw-service.ts b/api/src/services/bctw-service.ts index 2860f4add6..1652c3c60c 100644 --- a/api/src/services/bctw-service.ts +++ b/api/src/services/bctw-service.ts @@ -180,8 +180,8 @@ export const DELETE_MANUAL_TELEMETRY = '/manual-telemetry/delete'; export const MANUAL_AND_VENDOR_TELEMETRY = '/all-telemetry'; export const getBctwUser = (req: Request): IBctwUser => ({ - keycloak_guid: req['system_user']?.user_guid, - username: req['system_user']?.user_identifier + keycloak_guid: req.system_user?.user_guid, + username: req.system_user?.user_identifier }); export class BctwService { From 8be699d70d566521f7b4037d8763c75147ea453d Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 19 Jul 2024 16:06:57 -0700 Subject: [PATCH 05/13] chore: using connection details to create critterbase users --- api/src/paths/animal/index.ts | 5 ++++- api/src/paths/funding-sources/index.ts | 7 ++++--- api/src/paths/observation/index.ts | 5 ++++- api/src/paths/project/index.ts | 5 ++++- .../{surveyId}/attachments/keyx/upload.ts | 5 +++-- .../survey/{surveyId}/critters/index.ts | 18 ++++++------------ .../survey/{surveyId}/critters/{critterId}.ts | 9 +++++---- .../critters/{critterId}/deployments/index.ts | 19 ++++++++++--------- .../deployments/{bctwDeploymentId}.ts | 10 +++++----- .../critters/{critterId}/telemetry.ts | 10 +++++----- .../survey/{surveyId}/deployments.ts | 10 +++++----- api/src/services/bctw-service.ts | 4 ++-- 12 files changed, 57 insertions(+), 50 deletions(-) diff --git a/api/src/paths/animal/index.ts b/api/src/paths/animal/index.ts index 5b37392ef5..4c41fc5075 100644 --- a/api/src/paths/animal/index.ts +++ b/api/src/paths/animal/index.ts @@ -12,6 +12,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/animal'); @@ -191,9 +192,11 @@ export function findAnimals(): RequestHandler { const systemUserId = connection.systemUserId(); + const systemUser = getSystemUserFromRequest(req); + const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req.system_user['role_names'] + systemUser.role_names ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/funding-sources/index.ts b/api/src/paths/funding-sources/index.ts index a6a9833b62..c1e351df47 100644 --- a/api/src/paths/funding-sources/index.ts +++ b/api/src/paths/funding-sources/index.ts @@ -3,11 +3,11 @@ import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; import { FundingSource, FundingSourceSupplementaryData } from '../../repositories/funding-source-repository'; -import { SystemUser } from '../../repositories/user-repository'; import { authorizeRequestHandler } from '../../request-handlers/security/authorization'; import { FundingSourceService, IFundingSourceSearchParams } from '../../services/funding-source-service'; import { UserService } from '../../services/user-service'; import { getLogger } from '../../utils/logger'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/funding-sources/index'); @@ -124,8 +124,9 @@ export function getFundingSources(): RequestHandler { await connection.commit(); - const systemUserObject: SystemUser = req.system_user; - if (!UserService.isAdmin(systemUserObject)) { + const systemUser = getSystemUserFromRequest(req); + + if (!UserService.isAdmin(systemUser)) { // User is not an admin, strip sensitive fields from response response = removeNonAdminFieldsFromFundingSourcesResponse(response); } diff --git a/api/src/paths/observation/index.ts b/api/src/paths/observation/index.ts index 611dea6b96..f90f83be54 100644 --- a/api/src/paths/observation/index.ts +++ b/api/src/paths/observation/index.ts @@ -13,6 +13,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/observation/index'); @@ -176,9 +177,11 @@ export function findObservations(): RequestHandler { const systemUserId = connection.systemUserId(); + const systemUser = getSystemUserFromRequest(req); + const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req.system_user['role_names'] + systemUser.role_names ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/project/index.ts b/api/src/paths/project/index.ts index b3aac48029..8d75b4294c 100644 --- a/api/src/paths/project/index.ts +++ b/api/src/paths/project/index.ts @@ -12,6 +12,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/project/index'); @@ -190,9 +191,11 @@ export function findProjects(): RequestHandler { const systemUserId = connection.systemUserId(); + const systemUser = getSystemUserFromRequest(req); + const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req.system_user['role_names'] + systemUser.role_names ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts index 8a67c20968..d80a89b271 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/attachments/keyx/upload.ts @@ -164,9 +164,10 @@ export function uploadKeyxMedia(): RequestHandler { } const user: IBctwUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() }; + const bctwService = new BctwService(user); const bctwUploadResult = await bctwService.uploadKeyX(rawMediaFile); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts index f138cd2791..28260460a1 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/index.ts @@ -203,11 +203,6 @@ POST.apiDoc = { export function getCrittersFromSurvey(): RequestHandler { return async (req, res) => { - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; - const surveyId = Number(req.params.surveyId); const connection = getDBConnection(req.keycloak_token); @@ -224,8 +219,7 @@ export function getCrittersFromSurvey(): RequestHandler { const critterIds = surveyCritters.map((critter) => String(critter.critterbase_critter_id)); - const critterbaseService = new CritterbaseService(user); - const result = await critterbaseService.getMultipleCrittersByIds(critterIds); + const result = await surveyService.critterbaseService.getMultipleCrittersByIds(critterIds); const critterMap = new Map(); for (const item of result) { @@ -250,11 +244,6 @@ export function getCrittersFromSurvey(): RequestHandler { export function addCritterToSurvey(): RequestHandler { return async (req, res) => { - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; - const surveyId = Number(req.params.surveyId); let critterId = req.body.critter_id; @@ -263,6 +252,11 @@ export function addCritterToSurvey(): RequestHandler { try { await connection.open(); + const user: ICritterbaseUser = { + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() + }; + const critterbaseService = new CritterbaseService(user); // If request does not include critter ID, create a new critter and use its critter ID diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts index 63c4888f2c..d4236aa486 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}.ts @@ -85,16 +85,17 @@ PATCH.apiDoc = { export function updateSurveyCritter(): RequestHandler { return async (req, res) => { - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; const critterbaseCritterId = req.body.update.critter_id; const critterId = Number(req.params.critterId); const connection = getDBConnection(req.keycloak_token); try { + const user: ICritterbaseUser = { + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() + }; + if (!critterbaseCritterId) { throw new HTTPError(HTTPErrorType.BAD_REQUEST, 400, 'No external critter ID was found.'); } diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts index 9928a049c9..41c06c9629 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/index.ts @@ -237,11 +237,6 @@ PATCH.apiDoc = { export function deployDevice(): RequestHandler { return async (req, res) => { - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; - const critterId = Number(req.params.critterId); const newDeploymentId = v4(); // New deployment ID const newDeploymentDevice = { @@ -254,6 +249,11 @@ export function deployDevice(): RequestHandler { try { await connection.open(); + const user: ICritterbaseUser = { + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() + }; + const surveyCritterService = new SurveyCritterService(connection); await surveyCritterService.upsertDeployment(critterId, newDeploymentId); @@ -275,10 +275,6 @@ export function deployDevice(): RequestHandler { export function updateDeployment(): RequestHandler { return async (req, res) => { - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; const critterId = Number(req.params.critterId); const connection = getDBConnection(req.keycloak_token); @@ -286,6 +282,11 @@ export function updateDeployment(): RequestHandler { try { await connection.open(); + const user: ICritterbaseUser = { + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() + }; + const surveyCritterService = new SurveyCritterService(connection); const bctw = new BctwService(user); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts index e515a7c6e2..1538e5e5fd 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/deployments/{bctwDeploymentId}.ts @@ -104,11 +104,6 @@ DELETE.apiDoc = { export function deleteDeployment(): RequestHandler { return async (req, res) => { - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; - const deploymentId = String(req.params.bctwDeploymentId); const critterId = Number(req.params.critterId); @@ -117,6 +112,11 @@ export function deleteDeployment(): RequestHandler { try { await connection.open(); + const user: ICritterbaseUser = { + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() + }; + const surveyCritterService = new SurveyCritterService(connection); await surveyCritterService.removeDeployment(critterId, deploymentId); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts index bfa2363f8c..20fcda05be 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/critters/{critterId}/telemetry.ts @@ -257,11 +257,6 @@ GET.apiDoc = { export function getCritterTelemetry(): RequestHandler { return async (req, res) => { - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; - const critterId = Number(req.params.critterId); const surveyId = Number(req.params.surveyId); @@ -270,6 +265,11 @@ export function getCritterTelemetry(): RequestHandler { try { await connection.open(); + const user: ICritterbaseUser = { + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() + }; + const surveyCritterService = new SurveyCritterService(connection); const surveyCritters = await surveyCritterService.getCrittersInSurvey(surveyId); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts index 118a457f1f..2c5684841a 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/deployments.ts @@ -86,17 +86,17 @@ GET.apiDoc = { export function getDeploymentsInSurvey(): RequestHandler { return async (req, res) => { - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; - const surveyId = Number(req.params.surveyId); const connection = getDBConnection(req.keycloak_token); try { await connection.open(); + const user: ICritterbaseUser = { + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() + }; + const surveyCritterService = new SurveyCritterService(connection); const bctwService = new BctwService(user); diff --git a/api/src/services/bctw-service.ts b/api/src/services/bctw-service.ts index 1652c3c60c..d53b5f5423 100644 --- a/api/src/services/bctw-service.ts +++ b/api/src/services/bctw-service.ts @@ -180,8 +180,8 @@ export const DELETE_MANUAL_TELEMETRY = '/manual-telemetry/delete'; export const MANUAL_AND_VENDOR_TELEMETRY = '/all-telemetry'; export const getBctwUser = (req: Request): IBctwUser => ({ - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier + keycloak_guid: req.system_user?.user_guid as string, + username: req.system_user?.user_identifier as string }); export class BctwService { From 27935a5637be999526587964d4e759fd8b17ea65 Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 19 Jul 2024 16:20:54 -0700 Subject: [PATCH 06/13] chore: updating bad critterbase / bctw user objects --- .../survey/{surveyId}/observations/index.ts | 12 +++++---- api/src/paths/survey/index.ts | 5 +++- api/src/paths/telemetry/code.ts | 9 +++---- api/src/paths/telemetry/device/index.ts | 8 +++--- api/src/paths/telemetry/device/{deviceId}.ts | 8 +++--- api/src/paths/telemetry/index.ts | 5 +++- api/src/paths/telemetry/manual/delete.ts | 8 +++--- api/src/paths/telemetry/manual/process.ts | 8 +++--- api/src/paths/telemetry/vendors.ts | 8 +++--- api/src/services/bctw-service.ts | 26 +++++++++++++++---- 10 files changed, 55 insertions(+), 42 deletions(-) diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts index 305e91e3a2..23ee4994d9 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts @@ -5,7 +5,7 @@ import { getDBConnection } from '../../../../../../database/db'; import { observervationsWithSubcountDataSchema } from '../../../../../../openapi/schemas/observation'; import { paginationRequestQueryParamSchema } from '../../../../../../openapi/schemas/pagination'; import { authorizeRequestHandler } from '../../../../../../request-handlers/security/authorization'; -import { CritterbaseService } from '../../../../../../services/critterbase-service'; +import { CritterbaseService, ICritterbaseUser } from '../../../../../../services/critterbase-service'; import { InsertUpdateObservations, ObservationService } from '../../../../../../services/observation-service'; import { getLogger } from '../../../../../../utils/logger'; import { ensureCompletePaginationOptions, makePaginationResponse } from '../../../../../../utils/pagination'; @@ -425,10 +425,12 @@ export function putObservations(): RequestHandler { const observationRows: InsertUpdateObservations[] = req.body.surveyObservations; - const critterBaseService = new CritterbaseService({ - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }); + const user: ICritterbaseUser = { + keycloak_guid: connection.systemUserGUID(), + username: connection.systemUserIdentifier() + }; + + const critterBaseService = new CritterbaseService(user); // Validate measurement data against fetched measurement definition const isValid = await observationService.validateSurveyObservations(observationRows, critterBaseService); diff --git a/api/src/paths/survey/index.ts b/api/src/paths/survey/index.ts index 466880a7ae..e443efa1a7 100644 --- a/api/src/paths/survey/index.ts +++ b/api/src/paths/survey/index.ts @@ -12,6 +12,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/survey/index'); @@ -226,9 +227,11 @@ export function findSurveys(): RequestHandler { const systemUserId = connection.systemUserId(); + const systemUser = getSystemUserFromRequest(req); + const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req.system_user['role_names'] + systemUser.role_names ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/telemetry/code.ts b/api/src/paths/telemetry/code.ts index 0038266d93..2386b3dc3c 100644 --- a/api/src/paths/telemetry/code.ts +++ b/api/src/paths/telemetry/code.ts @@ -1,7 +1,7 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { authorizeRequestHandler } from '../../request-handlers/security/authorization'; -import { BctwService, IBctwUser } from '../../services/bctw-service'; +import { BctwService, getBctwUser } from '../../services/bctw-service'; import { getLogger } from '../../utils/logger'; const defaultLog = getLogger('paths/telemetry/code'); @@ -70,12 +70,11 @@ GET.apiDoc = { export function getCodeValues(): RequestHandler { return async (req, res) => { - const user: IBctwUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; + const user = getBctwUser(req); + const bctwService = new BctwService(user); const codeHeader = String(req.query.codeHeader); + try { const result = await bctwService.getCode(codeHeader); return res.status(200).json(result); diff --git a/api/src/paths/telemetry/device/index.ts b/api/src/paths/telemetry/device/index.ts index c42ed0ffb5..a166f4944b 100644 --- a/api/src/paths/telemetry/device/index.ts +++ b/api/src/paths/telemetry/device/index.ts @@ -1,7 +1,7 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { authorizeRequestHandler } from '../../../request-handlers/security/authorization'; -import { BctwService, IBctwUser } from '../../../services/bctw-service'; +import { BctwService, getBctwUser } from '../../../services/bctw-service'; import { getLogger } from '../../../utils/logger'; const defaultLog = getLogger('paths/telemetry/device/{deviceId}'); @@ -92,10 +92,8 @@ POST.apiDoc = { export function upsertDevice(): RequestHandler { return async (req, res) => { - const user: IBctwUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; + const user = getBctwUser(req); + const bctwService = new BctwService(user); try { const results = await bctwService.updateDevice(req.body); diff --git a/api/src/paths/telemetry/device/{deviceId}.ts b/api/src/paths/telemetry/device/{deviceId}.ts index 950aa0dcae..7e1f4bfebe 100644 --- a/api/src/paths/telemetry/device/{deviceId}.ts +++ b/api/src/paths/telemetry/device/{deviceId}.ts @@ -1,7 +1,7 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { authorizeRequestHandler } from '../../../request-handlers/security/authorization'; -import { BctwService, IBctwUser } from '../../../services/bctw-service'; +import { BctwService, getBctwUser } from '../../../services/bctw-service'; import { getLogger } from '../../../utils/logger'; const defaultLog = getLogger('paths/telemetry/device/{deviceId}'); @@ -58,10 +58,8 @@ GET.apiDoc = { export function getDeviceDetails(): RequestHandler { return async (req, res) => { - const user: IBctwUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; + const user = getBctwUser(req); + const bctwService = new BctwService(user); const deviceId = Number(req.params.deviceId); const deviceMake = String(req.query.make); diff --git a/api/src/paths/telemetry/index.ts b/api/src/paths/telemetry/index.ts index daac1256cc..be9e8ae91b 100644 --- a/api/src/paths/telemetry/index.ts +++ b/api/src/paths/telemetry/index.ts @@ -12,6 +12,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/telemetry'); @@ -192,9 +193,11 @@ export function findTelemetry(): RequestHandler { const systemUserId = connection.systemUserId(); + const systemUser = getSystemUserFromRequest(req); + const isUserAdmin = userHasValidRole( [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.DATA_ADMINISTRATOR], - req.system_user['role_names'] + systemUser.role_names ); const filterFields = parseQueryParams(req); diff --git a/api/src/paths/telemetry/manual/delete.ts b/api/src/paths/telemetry/manual/delete.ts index e916ab15c9..b1f57b158e 100644 --- a/api/src/paths/telemetry/manual/delete.ts +++ b/api/src/paths/telemetry/manual/delete.ts @@ -2,7 +2,7 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { manual_telemetry_responses } from '.'; import { authorizeRequestHandler } from '../../../request-handlers/security/authorization'; -import { BctwService, IBctwUser } from '../../../services/bctw-service'; +import { BctwService, getBctwUser } from '../../../services/bctw-service'; import { getLogger } from '../../../utils/logger'; const defaultLog = getLogger('paths/telemetry/manual/delete'); @@ -50,10 +50,8 @@ POST.apiDoc = { export function deleteManualTelemetry(): RequestHandler { return async (req, res) => { - const user: IBctwUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; + const user = getBctwUser(req); + const bctwService = new BctwService(user); try { const result = await bctwService.deleteManualTelemetry(req.body); diff --git a/api/src/paths/telemetry/manual/process.ts b/api/src/paths/telemetry/manual/process.ts index b96b0c36c6..cad1db8208 100644 --- a/api/src/paths/telemetry/manual/process.ts +++ b/api/src/paths/telemetry/manual/process.ts @@ -3,7 +3,7 @@ import { Operation } from 'express-openapi'; import { PROJECT_PERMISSION, SYSTEM_ROLE } from '../../../constants/roles'; import { getDBConnection } from '../../../database/db'; import { authorizeRequestHandler } from '../../../request-handlers/security/authorization'; -import { ICritterbaseUser } from '../../../services/critterbase-service'; +import { getBctwUser } from '../../../services/bctw-service'; import { TelemetryService } from '../../../services/telemetry-service'; import { getLogger } from '../../../utils/logger'; @@ -92,11 +92,9 @@ POST.apiDoc = { export function processFile(): RequestHandler { return async (req, res) => { + const user = getBctwUser(req); + const submissionId = req.body.submission_id; - const user: ICritterbaseUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; const connection = getDBConnection(req.keycloak_token); try { await connection.open(); diff --git a/api/src/paths/telemetry/vendors.ts b/api/src/paths/telemetry/vendors.ts index b0e72b2581..b0901914ab 100644 --- a/api/src/paths/telemetry/vendors.ts +++ b/api/src/paths/telemetry/vendors.ts @@ -1,7 +1,7 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { authorizeRequestHandler } from '../../request-handlers/security/authorization'; -import { BctwService, IBctwUser } from '../../services/bctw-service'; +import { BctwService, getBctwUser } from '../../services/bctw-service'; import { getLogger } from '../../utils/logger'; const defaultLog = getLogger('paths/telemetry/vendors'); @@ -61,10 +61,8 @@ GET.apiDoc = { export function getCollarVendors(): RequestHandler { return async (req, res) => { - const user: IBctwUser = { - keycloak_guid: req.system_user?.user_guid, - username: req.system_user?.user_identifier - }; + const user = getBctwUser(req); + const bctwService = new BctwService(user); try { const result = await bctwService.getCollarVendors(); diff --git a/api/src/services/bctw-service.ts b/api/src/services/bctw-service.ts index d53b5f5423..136aee209a 100644 --- a/api/src/services/bctw-service.ts +++ b/api/src/services/bctw-service.ts @@ -4,8 +4,9 @@ import FormData from 'form-data'; import { GeometryCollection } from 'geojson'; import { URLSearchParams } from 'url'; import { z } from 'zod'; -import { ApiError, ApiErrorType } from '../errors/api-error'; +import { ApiError, ApiErrorType, ApiGeneralError } from '../errors/api-error'; import { HTTP500 } from '../errors/http-error'; +import { getSystemUserFromRequest } from '../utils/request'; import { KeycloakService } from './keycloak-service'; export const IDeployDevice = z.object({ @@ -179,10 +180,25 @@ export const VENDOR_TELEMETRY = '/vendor-telemetry'; export const DELETE_MANUAL_TELEMETRY = '/manual-telemetry/delete'; export const MANUAL_AND_VENDOR_TELEMETRY = '/all-telemetry'; -export const getBctwUser = (req: Request): IBctwUser => ({ - keycloak_guid: req.system_user?.user_guid as string, - username: req.system_user?.user_identifier as string -}); +/** + * Safely attempt to retrieve system user fields for BCTW user dependency. + * + * @param {Request} req + * @throws {ApiGeneralError} - Missing required fields + * @returns {IBctwUser} + */ +export const getBctwUser = (req: Request): IBctwUser => { + const systemUser = getSystemUserFromRequest(req); + + if (!systemUser.user_guid || !systemUser.user_identifier) { + throw new ApiGeneralError('System user missing required fields', ['bctw-service->getBctwUser']); + } + + return { + keycloak_guid: systemUser.user_guid, + username: systemUser.user_identifier + }; +}; export class BctwService { user: IBctwUser; From 1df2a5428c2f5d734bdb5f0cf826e0b2ca4d4140 Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 19 Jul 2024 16:28:51 -0700 Subject: [PATCH 07/13] fix: updated mockreq -> mockReq and casted as KeycloakUserInformation --- api/src/paths/administrative-activity.test.ts | 4 ++-- api/src/paths/animal/index.test.ts | 9 +++++---- api/src/paths/funding-sources/index.test.ts | 4 ++-- api/src/paths/observation/index.test.ts | 9 +++++---- api/src/paths/project/index.test.ts | 9 +++++---- api/src/paths/project/{projectId}/survey/index.test.ts | 5 +++-- api/src/paths/survey/index.test.ts | 9 +++++---- api/src/paths/telemetry/index.test.ts | 9 +++++---- api/src/paths/user/add.ts | 9 +++++---- 9 files changed, 37 insertions(+), 30 deletions(-) diff --git a/api/src/paths/administrative-activity.test.ts b/api/src/paths/administrative-activity.test.ts index e03cf1917f..7b2d023dd9 100644 --- a/api/src/paths/administrative-activity.test.ts +++ b/api/src/paths/administrative-activity.test.ts @@ -117,7 +117,7 @@ describe('getAdministrativeActivityStanding', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockreq.keycloak_token = { + mockReq.keycloak_token = { idir_user_guid: 'testguid', identity_provider: 'idir', idir_username: 'testuser', @@ -158,7 +158,7 @@ describe('getAdministrativeActivityStanding', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockreq.keycloak_token = { + mockReq.keycloak_token = { idir_user_guid: 'testguid', identity_provider: 'idir', idir_username: 'testuser', diff --git a/api/src/paths/animal/index.test.ts b/api/src/paths/animal/index.test.ts index 6a40874aa7..53694e85f8 100644 --- a/api/src/paths/animal/index.test.ts +++ b/api/src/paths/animal/index.test.ts @@ -6,6 +6,7 @@ import { SYSTEM_ROLE } from '../../constants/roles'; import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; import { FindCrittersResponse, SurveyCritterService } from '../../services/survey-critter-service'; +import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; import { findAnimals } from './index'; @@ -59,8 +60,8 @@ describe('findAnimals', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -126,8 +127,8 @@ describe('findAnimals', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/funding-sources/index.test.ts b/api/src/paths/funding-sources/index.test.ts index 6c3ad68c8a..d0e80e2a4a 100644 --- a/api/src/paths/funding-sources/index.test.ts +++ b/api/src/paths/funding-sources/index.test.ts @@ -67,7 +67,7 @@ describe('getFundingSources', () => { agency: null }; // system_user would be set by the authorization-service, if this endpoint was called for real - mockreq.system_user = systemUser; + mockReq.system_user = systemUser; const requestHandler = getFundingSources(); @@ -128,7 +128,7 @@ describe('getFundingSources', () => { agency: null }; // system_user would be set by the authorization-service, if this endpoint was called for real - mockreq.system_user = systemUser; + mockReq.system_user = systemUser; const requestHandler = getFundingSources(); diff --git a/api/src/paths/observation/index.test.ts b/api/src/paths/observation/index.test.ts index b0616cd9dd..3c520bce90 100644 --- a/api/src/paths/observation/index.test.ts +++ b/api/src/paths/observation/index.test.ts @@ -7,6 +7,7 @@ import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; import { ObservationRecordWithSamplingAndSubcountData } from '../../repositories/observation-repository/observation-repository'; import { ObservationService } from '../../services/observation-service'; +import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; import { findObservations } from './index'; @@ -79,8 +80,8 @@ describe('findObservations', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -172,8 +173,8 @@ describe('findObservations', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/project/index.test.ts b/api/src/paths/project/index.test.ts index 3ab28e91fd..23a851ffb5 100644 --- a/api/src/paths/project/index.test.ts +++ b/api/src/paths/project/index.test.ts @@ -7,6 +7,7 @@ import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; import { FindProjectsResponse } from '../../models/project-view'; import { ProjectService } from '../../services/project-service'; +import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; import { findProjects } from './index'; @@ -55,8 +56,8 @@ describe('findProjects', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -117,8 +118,8 @@ describe('findProjects', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/project/{projectId}/survey/index.test.ts b/api/src/paths/project/{projectId}/survey/index.test.ts index 682758b64f..414684cb6f 100644 --- a/api/src/paths/project/{projectId}/survey/index.test.ts +++ b/api/src/paths/project/{projectId}/survey/index.test.ts @@ -6,6 +6,7 @@ import { getSurveys } from '.'; import * as db from '../../../../database/db'; import { HTTPError } from '../../../../errors/http-error'; import { SurveyService } from '../../../../services/survey-service'; +import { KeycloakUserInformation } from '../../../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../../../__mocks__/db'; chai.use(sinonChai); @@ -24,7 +25,7 @@ describe('survey list', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockreq.keycloak_token = {}; + mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.params = { projectId: '1' }; @@ -72,7 +73,7 @@ describe('survey list', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); const projectId = 3; - mockreq.keycloak_token = {}; + mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.params = { projectId: String(projectId) }; diff --git a/api/src/paths/survey/index.test.ts b/api/src/paths/survey/index.test.ts index 1a855c5d8f..c21d14fc8d 100644 --- a/api/src/paths/survey/index.test.ts +++ b/api/src/paths/survey/index.test.ts @@ -7,6 +7,7 @@ import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; import { FindSurveysResponse } from '../../models/survey-view'; import { SurveyService } from '../../services/survey-service'; +import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; import { findSurveys } from './index'; @@ -59,8 +60,8 @@ describe('findSurveys', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -125,8 +126,8 @@ describe('findSurveys', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/telemetry/index.test.ts b/api/src/paths/telemetry/index.test.ts index 9aef4b0748..8021352745 100644 --- a/api/src/paths/telemetry/index.test.ts +++ b/api/src/paths/telemetry/index.test.ts @@ -6,6 +6,7 @@ import { SYSTEM_ROLE } from '../../constants/roles'; import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; import { FindTelemetryResponse, TelemetryService } from '../../services/telemetry-service'; +import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; import { findTelemetry } from './index'; @@ -57,8 +58,8 @@ describe('findTelemetry', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] }; @@ -103,8 +104,8 @@ describe('findTelemetry', () => { sort: undefined, order: undefined }; - mockreq.keycloak_token = {}; - mockreq.system_user = { + mockReq.keycloak_token = {} as KeycloakUserInformation; + mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] }; diff --git a/api/src/paths/user/add.ts b/api/src/paths/user/add.ts index 91b1716d1a..f8cfea33b6 100644 --- a/api/src/paths/user/add.ts +++ b/api/src/paths/user/add.ts @@ -7,6 +7,7 @@ import { authorizeRequestHandler } from '../../request-handlers/security/authori import { UserService } from '../../services/user-service'; import { getKeycloakSource } from '../../utils/keycloak-utils'; import { getLogger } from '../../utils/logger'; +import { getKeycloakTokenFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/user/add'); @@ -132,11 +133,11 @@ export function addSystemRoleUser(): RequestHandler { const family_name: string = req.body?.family_name; const role_name: string = req.body?.role_name; - const sourceSystem = getKeycloakSource(req.keycloak_token); + const keycloakToken = getKeycloakTokenFromRequest(req); - const connection = sourceSystem - ? getServiceClientDBConnection(sourceSystem) - : getDBConnection(req.keycloak_token); + const sourceSystem = getKeycloakSource(keycloakToken); + + const connection = sourceSystem ? getServiceClientDBConnection(sourceSystem) : getDBConnection(keycloakToken); try { await connection.open(); From 0385c045dfbf3247efc1b1f2e6cfc4b2a2d2cf6a Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 19 Jul 2024 16:41:40 -0700 Subject: [PATCH 08/13] chore: updated broken tests --- api/src/paths/animal/index.test.ts | 5 +++-- api/src/paths/observation/index.test.ts | 5 +++-- api/src/paths/project/index.test.ts | 5 +++-- api/src/paths/survey/index.test.ts | 5 +++-- api/src/paths/telemetry/code.test.ts | 7 +++++++ api/src/paths/telemetry/deployments.test.ts | 7 +++++++ api/src/paths/telemetry/device/index.test.ts | 6 ++++++ .../paths/telemetry/device/{deviceId}.test.ts | 7 +++++++ api/src/paths/telemetry/index.test.ts | 5 +++-- api/src/paths/telemetry/manual/delete.test.ts | 7 +++++++ .../telemetry/manual/deployments.test.ts | 7 +++++++ api/src/paths/telemetry/manual/index.test.ts | 19 +++++++++++++++++++ .../telemetry/vendor/deployments.test.ts | 7 +++++++ api/src/paths/telemetry/vendors.test.ts | 7 +++++++ api/src/paths/user/add.test.ts | 4 ++++ 15 files changed, 93 insertions(+), 10 deletions(-) diff --git a/api/src/paths/animal/index.test.ts b/api/src/paths/animal/index.test.ts index 53694e85f8..7726a0ed4a 100644 --- a/api/src/paths/animal/index.test.ts +++ b/api/src/paths/animal/index.test.ts @@ -5,6 +5,7 @@ import sinonChai from 'sinon-chai'; import { SYSTEM_ROLE } from '../../constants/roles'; import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; +import { SystemUser } from '../../repositories/user-repository'; import { FindCrittersResponse, SurveyCritterService } from '../../services/survey-critter-service'; import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; @@ -63,7 +64,7 @@ describe('findAnimals', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] - }; + } as SystemUser; const requestHandler = findAnimals(); @@ -130,7 +131,7 @@ describe('findAnimals', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] - }; + } as SystemUser; const requestHandler = findAnimals(); diff --git a/api/src/paths/observation/index.test.ts b/api/src/paths/observation/index.test.ts index 3c520bce90..8a15318fe6 100644 --- a/api/src/paths/observation/index.test.ts +++ b/api/src/paths/observation/index.test.ts @@ -6,6 +6,7 @@ import { SYSTEM_ROLE } from '../../constants/roles'; import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; import { ObservationRecordWithSamplingAndSubcountData } from '../../repositories/observation-repository/observation-repository'; +import { SystemUser } from '../../repositories/user-repository'; import { ObservationService } from '../../services/observation-service'; import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; @@ -83,7 +84,7 @@ describe('findObservations', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] - }; + } as SystemUser; const requestHandler = findObservations(); @@ -176,7 +177,7 @@ describe('findObservations', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] - }; + } as SystemUser; const requestHandler = findObservations(); diff --git a/api/src/paths/project/index.test.ts b/api/src/paths/project/index.test.ts index 23a851ffb5..d36b2c6d0f 100644 --- a/api/src/paths/project/index.test.ts +++ b/api/src/paths/project/index.test.ts @@ -6,6 +6,7 @@ import { SYSTEM_ROLE } from '../../constants/roles'; import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; import { FindProjectsResponse } from '../../models/project-view'; +import { SystemUser } from '../../repositories/user-repository'; import { ProjectService } from '../../services/project-service'; import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; @@ -59,7 +60,7 @@ describe('findProjects', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] - }; + } as SystemUser; const requestHandler = findProjects(); @@ -121,7 +122,7 @@ describe('findProjects', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] - }; + } as SystemUser; const requestHandler = findProjects(); diff --git a/api/src/paths/survey/index.test.ts b/api/src/paths/survey/index.test.ts index c21d14fc8d..8ecd973ccf 100644 --- a/api/src/paths/survey/index.test.ts +++ b/api/src/paths/survey/index.test.ts @@ -6,6 +6,7 @@ import { SYSTEM_ROLE } from '../../constants/roles'; import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; import { FindSurveysResponse } from '../../models/survey-view'; +import { SystemUser } from '../../repositories/user-repository'; import { SurveyService } from '../../services/survey-service'; import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; @@ -63,7 +64,7 @@ describe('findSurveys', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] - }; + } as SystemUser; const requestHandler = findSurveys(); @@ -129,7 +130,7 @@ describe('findSurveys', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] - }; + } as SystemUser; const requestHandler = findSurveys(); diff --git a/api/src/paths/telemetry/code.test.ts b/api/src/paths/telemetry/code.test.ts index 1de6816519..442a39d752 100644 --- a/api/src/paths/telemetry/code.test.ts +++ b/api/src/paths/telemetry/code.test.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import sinon from 'sinon'; +import { SystemUser } from '../../repositories/user-repository'; import { BctwService } from '../../services/bctw-service'; import { getRequestHandlerMocks } from '../../__mocks__/db'; import { getCodeValues } from './code'; @@ -23,6 +24,9 @@ describe('getCodeValues', () => { const mockGetCode = sinon.stub(BctwService.prototype, 'getCode').resolves(mockCodeValues); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getCodeValues(); await requestHandler(mockReq, mockRes, mockNext); @@ -37,6 +41,9 @@ describe('getCodeValues', () => { const mockGetCode = sinon.stub(BctwService.prototype, 'getCode').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getCodeValues(); try { diff --git a/api/src/paths/telemetry/deployments.test.ts b/api/src/paths/telemetry/deployments.test.ts index 0e66886c56..facb4c577c 100644 --- a/api/src/paths/telemetry/deployments.test.ts +++ b/api/src/paths/telemetry/deployments.test.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import sinon from 'sinon'; +import { SystemUser } from '../../repositories/user-repository'; import { BctwService, IAllTelemetry } from '../../services/bctw-service'; import { getRequestHandlerMocks } from '../../__mocks__/db'; import { getAllTelemetryByDeploymentIds } from './deployments'; @@ -35,6 +36,9 @@ describe('getAllTelemetryByDeploymentIds', () => { .resolves(mockTelemetry); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getAllTelemetryByDeploymentIds(); await requestHandler(mockReq, mockRes, mockNext); @@ -48,6 +52,9 @@ describe('getAllTelemetryByDeploymentIds', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'getAllTelemetryByDeploymentIds').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getAllTelemetryByDeploymentIds(); try { diff --git a/api/src/paths/telemetry/device/index.test.ts b/api/src/paths/telemetry/device/index.test.ts index 106b471fc0..9bfc486707 100644 --- a/api/src/paths/telemetry/device/index.test.ts +++ b/api/src/paths/telemetry/device/index.test.ts @@ -2,6 +2,7 @@ import Ajv from 'ajv'; import { expect } from 'chai'; import sinon from 'sinon'; import { HTTPError } from '../../../errors/http-error'; +import { SystemUser } from '../../../repositories/user-repository'; import { BctwService } from '../../../services/bctw-service'; import { getRequestHandlerMocks } from '../../../__mocks__/db'; import { POST, upsertDevice } from './index'; @@ -23,6 +24,9 @@ describe('upsertDevice', () => { const mockUpsertDevice = sinon.stub(BctwService.prototype, 'updateDevice'); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = upsertDevice(); await requestHandler(mockReq, mockRes, mockNext); @@ -37,6 +41,8 @@ describe('upsertDevice', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = upsertDevice(); try { await requestHandler(mockReq, mockRes, mockNext); diff --git a/api/src/paths/telemetry/device/{deviceId}.test.ts b/api/src/paths/telemetry/device/{deviceId}.test.ts index 3addc860f5..6c90dff8f5 100644 --- a/api/src/paths/telemetry/device/{deviceId}.test.ts +++ b/api/src/paths/telemetry/device/{deviceId}.test.ts @@ -1,6 +1,7 @@ import Ajv from 'ajv'; import { expect } from 'chai'; import sinon from 'sinon'; +import { SystemUser } from '../../../repositories/user-repository'; import { BctwService } from '../../../services/bctw-service'; import { getRequestHandlerMocks } from '../../../__mocks__/db'; import { GET, getDeviceDetails } from './{deviceId}'; @@ -24,6 +25,9 @@ describe('getDeviceDetails', () => { const mockGetKeyXDetails = sinon.stub(BctwService.prototype, 'getKeyXDetails').resolves([]); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getDeviceDetails(); await requestHandler(mockReq, mockRes, mockNext); @@ -39,6 +43,9 @@ describe('getDeviceDetails', () => { const mockGetDeviceDetails = sinon.stub(BctwService.prototype, 'getDeviceDetails').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getDeviceDetails(); try { diff --git a/api/src/paths/telemetry/index.test.ts b/api/src/paths/telemetry/index.test.ts index 8021352745..4e53a7fea1 100644 --- a/api/src/paths/telemetry/index.test.ts +++ b/api/src/paths/telemetry/index.test.ts @@ -5,6 +5,7 @@ import sinonChai from 'sinon-chai'; import { SYSTEM_ROLE } from '../../constants/roles'; import * as db from '../../database/db'; import { HTTPError } from '../../errors/http-error'; +import { SystemUser } from '../../repositories/user-repository'; import { FindTelemetryResponse, TelemetryService } from '../../services/telemetry-service'; import { KeycloakUserInformation } from '../../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db'; @@ -61,7 +62,7 @@ describe('findTelemetry', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.SYSTEM_ADMIN] - }; + } as SystemUser; const requestHandler = findTelemetry(); @@ -107,7 +108,7 @@ describe('findTelemetry', () => { mockReq.keycloak_token = {} as KeycloakUserInformation; mockReq.system_user = { role_names: [SYSTEM_ROLE.PROJECT_CREATOR] - }; + } as SystemUser; const requestHandler = findTelemetry(); diff --git a/api/src/paths/telemetry/manual/delete.test.ts b/api/src/paths/telemetry/manual/delete.test.ts index a0fa851e9c..0bd0c7837c 100644 --- a/api/src/paths/telemetry/manual/delete.test.ts +++ b/api/src/paths/telemetry/manual/delete.test.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import sinon from 'sinon'; +import { SystemUser } from '../../../repositories/user-repository'; import { BctwService, IManualTelemetry } from '../../../services/bctw-service'; import { getRequestHandlerMocks } from '../../../__mocks__/db'; import { deleteManualTelemetry } from './delete'; @@ -21,6 +22,9 @@ describe('deleteManualTelemetry', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'deleteManualTelemetry').resolves(mockTelemetry); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = deleteManualTelemetry(); await requestHandler(mockReq, mockRes, mockNext); @@ -34,6 +38,9 @@ describe('deleteManualTelemetry', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'deleteManualTelemetry').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = deleteManualTelemetry(); try { diff --git a/api/src/paths/telemetry/manual/deployments.test.ts b/api/src/paths/telemetry/manual/deployments.test.ts index 6e7f831eda..1120703417 100644 --- a/api/src/paths/telemetry/manual/deployments.test.ts +++ b/api/src/paths/telemetry/manual/deployments.test.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import sinon from 'sinon'; +import { SystemUser } from '../../../repositories/user-repository'; import { BctwService, IManualTelemetry } from '../../../services/bctw-service'; import { getRequestHandlerMocks } from '../../../__mocks__/db'; import { getManualTelemetryByDeploymentIds } from './deployments'; @@ -23,6 +24,9 @@ describe('getManualTelemetryByDeploymentIds', () => { .resolves(mockTelemetry); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getManualTelemetryByDeploymentIds(); await requestHandler(mockReq, mockRes, mockNext); @@ -36,6 +40,9 @@ describe('getManualTelemetryByDeploymentIds', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'getManualTelemetryByDeploymentIds').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getManualTelemetryByDeploymentIds(); try { diff --git a/api/src/paths/telemetry/manual/index.test.ts b/api/src/paths/telemetry/manual/index.test.ts index ca82e19789..47a5c92cd7 100644 --- a/api/src/paths/telemetry/manual/index.test.ts +++ b/api/src/paths/telemetry/manual/index.test.ts @@ -2,6 +2,7 @@ import Ajv from 'ajv'; import { expect } from 'chai'; import sinon from 'sinon'; import { createManualTelemetry, GET, getManualTelemetry, PATCH, POST, updateManualTelemetry } from '.'; +import { SystemUser } from '../../../repositories/user-repository'; import { BctwService, IManualTelemetry } from '../../../services/bctw-service'; import { getRequestHandlerMocks } from '../../../__mocks__/db'; @@ -30,6 +31,9 @@ describe('manual telemetry endpoints', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'getManualTelemetry').resolves(mockTelemetry); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getManualTelemetry(); await requestHandler(mockReq, mockRes, mockNext); @@ -44,6 +48,9 @@ describe('manual telemetry endpoints', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'getManualTelemetry').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getManualTelemetry(); try { @@ -66,6 +73,9 @@ describe('manual telemetry endpoints', () => { const mockCreateTelemetry = sinon.stub(BctwService.prototype, 'createManualTelemetry').resolves(mockTelemetry); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = createManualTelemetry(); await requestHandler(mockReq, mockRes, mockNext); @@ -79,6 +89,9 @@ describe('manual telemetry endpoints', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'createManualTelemetry').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = createManualTelemetry(); try { @@ -101,6 +114,9 @@ describe('manual telemetry endpoints', () => { const mockCreateTelemetry = sinon.stub(BctwService.prototype, 'updateManualTelemetry').resolves(mockTelemetry); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = updateManualTelemetry(); await requestHandler(mockReq, mockRes, mockNext); @@ -114,6 +130,9 @@ describe('manual telemetry endpoints', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'updateManualTelemetry').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = updateManualTelemetry(); try { diff --git a/api/src/paths/telemetry/vendor/deployments.test.ts b/api/src/paths/telemetry/vendor/deployments.test.ts index cb9cf157f4..709101c1f5 100644 --- a/api/src/paths/telemetry/vendor/deployments.test.ts +++ b/api/src/paths/telemetry/vendor/deployments.test.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import sinon from 'sinon'; +import { SystemUser } from '../../../repositories/user-repository'; import { BctwService, IVendorTelemetry } from '../../../services/bctw-service'; import { getRequestHandlerMocks } from '../../../__mocks__/db'; import { getVendorTelemetryByDeploymentIds } from './deployments'; @@ -41,6 +42,9 @@ describe('getVendorTelemetryByDeploymentIds', () => { .resolves(mockTelemetry); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getVendorTelemetryByDeploymentIds(); await requestHandler(mockReq, mockRes, mockNext); @@ -54,6 +58,9 @@ describe('getVendorTelemetryByDeploymentIds', () => { const mockGetTelemetry = sinon.stub(BctwService.prototype, 'getVendorTelemetryByDeploymentIds').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getVendorTelemetryByDeploymentIds(); try { diff --git a/api/src/paths/telemetry/vendors.test.ts b/api/src/paths/telemetry/vendors.test.ts index eb3622797f..ce9c5acc8e 100644 --- a/api/src/paths/telemetry/vendors.test.ts +++ b/api/src/paths/telemetry/vendors.test.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import sinon from 'sinon'; +import { SystemUser } from '../../repositories/user-repository'; import { BctwService } from '../../services/bctw-service'; import { getRequestHandlerMocks } from '../../__mocks__/db'; import { getCollarVendors } from './vendors'; @@ -14,6 +15,9 @@ describe('getCollarVendors', () => { const mockGetCollarVendors = sinon.stub(BctwService.prototype, 'getCollarVendors').resolves(mockVendors); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getCollarVendors(); await requestHandler(mockReq, mockRes, mockNext); @@ -29,6 +33,9 @@ describe('getCollarVendors', () => { const mockGetCollarVendors = sinon.stub(BctwService.prototype, 'getCollarVendors').rejects(mockError); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + + mockReq.system_user = { user_identifier: 'user', user_guid: 'guid' } as SystemUser; + const requestHandler = getCollarVendors(); try { diff --git a/api/src/paths/user/add.test.ts b/api/src/paths/user/add.test.ts index ed4bb716ce..e805ab49fd 100644 --- a/api/src/paths/user/add.test.ts +++ b/api/src/paths/user/add.test.ts @@ -26,6 +26,8 @@ describe('user', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + mockReq.keycloak_token = {} as keycloakUtils.KeycloakUserInformation; + mockReq.body = { userGuid: 'aaaa', userIdentifier: 'username', @@ -70,6 +72,8 @@ describe('user', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); + mockReq.keycloak_token = {} as keycloakUtils.KeycloakUserInformation; + mockReq.body = { identitySource: SYSTEM_IDENTITY_SOURCE.IDIR, userIdentifier: 'username', From 346d75a823418ea34803744860c7caf9600508e1 Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Mon, 22 Jul 2024 10:04:24 -0700 Subject: [PATCH 09/13] fix: moved express request module to express/request.ts --- api/src/app.ts | 13 ------ api/src/express/request.ts | 57 ++++++++++++++++++++++++ api/src/paths/administrative-activity.ts | 2 +- api/src/paths/animal/index.ts | 2 +- api/src/paths/funding-sources/index.ts | 2 +- api/src/paths/observation/index.ts | 2 +- api/src/paths/project/index.ts | 2 +- api/src/paths/survey/index.ts | 2 +- api/src/paths/telemetry/index.ts | 2 +- api/src/paths/user/add.ts | 2 +- api/src/services/bctw-service.ts | 2 +- api/src/utils/request.ts | 2 +- 12 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 api/src/express/request.ts diff --git a/api/src/app.ts b/api/src/app.ts index 6ed1dca058..c8bae12e0b 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -12,24 +12,11 @@ import { replaceAuthorizationHeaderMiddleware } from './middleware/critterbase-proxy'; import { rootAPIDoc } from './openapi/root-api-doc'; -import { SystemUser } from './repositories/user-repository'; import { authenticateRequest, authenticateRequestOptional } from './request-handlers/security/authentication'; -import { KeycloakUserInformation } from './utils/keycloak-utils'; import { getLogger } from './utils/logger'; const defaultLog = getLogger('app'); -/** - * Extending express request type. - * - */ -declare module 'express-serve-static-core' { - interface Request { - keycloak_token?: KeycloakUserInformation; - system_user?: SystemUser; - } -} - const HOST = process.env.API_HOST; const PORT = Number(process.env.API_PORT); diff --git a/api/src/express/request.ts b/api/src/express/request.ts new file mode 100644 index 0000000000..bd7de79c79 --- /dev/null +++ b/api/src/express/request.ts @@ -0,0 +1,57 @@ +import { Request } from 'express'; +import { SystemUser } from '../repositories/user-repository'; +import { KeycloakUserInformation } from '../utils/keycloak-utils'; + +/** + * Extending express request type. + * + */ +declare module 'express-serve-static-core' { + interface Request { + /** + * Keycloak user JWT token. + * + */ + keycloak_token?: KeycloakUserInformation; + /** + * SIMS system user details. + * + */ + system_user?: SystemUser; + } +} + +/** + * Get keycloak token from request or throw error. + * + * Value is defined for endpoints that specify `Bearer` security with correct JWT token. + * + * @see authentication.ts -> authenticateRequest() + * + * @param {Request} req + * @throws {Error} - Missing keycloak token + * @returns {KeycloakUserInformation} + */ +export const getKeycloakTokenFromRequest = (req: Request): KeycloakUserInformation => { + if (!req.keycloak_token) { + throw new Error('Request missing keycloak token.'); + } + return req.keycloak_token; +}; + +/** + * Get system user from request of throw error. + * + * @see authorization.ts -> authorizeRequest() + * + * @param {Request} req + * @throws {Error} - Missing system user + * @returns {SystemUser} + */ +export const getSystemUserFromRequest = (req: Request): SystemUser => { + if (!req.system_user) { + throw new Error('Request missing system user.'); + } + + return req.system_user; +}; diff --git a/api/src/paths/administrative-activity.ts b/api/src/paths/administrative-activity.ts index 77ea91d106..b74a88c978 100644 --- a/api/src/paths/administrative-activity.ts +++ b/api/src/paths/administrative-activity.ts @@ -2,10 +2,10 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { getAPIUserDBConnection } from '../database/db'; import { HTTP400, HTTP500 } from '../errors/http-error'; +import { getKeycloakTokenFromRequest } from '../express/request'; import { AdministrativeActivityService } from '../services/administrative-activity-service'; import { getUserGuid } from '../utils/keycloak-utils'; import { getLogger } from '../utils/logger'; -import { getKeycloakTokenFromRequest } from '../utils/request'; const defaultLog = getLogger('paths/administrative-activity-request'); diff --git a/api/src/paths/animal/index.ts b/api/src/paths/animal/index.ts index 4c41fc5075..33e27cb60f 100644 --- a/api/src/paths/animal/index.ts +++ b/api/src/paths/animal/index.ts @@ -2,6 +2,7 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; +import { getSystemUserFromRequest } from '../../express/request'; import { IAnimalAdvancedFilters } from '../../models/animal-view'; import { paginationRequestQueryParamSchema, paginationResponseSchema } from '../../openapi/schemas/pagination'; import { authorizeRequestHandler, userHasValidRole } from '../../request-handlers/security/authorization'; @@ -12,7 +13,6 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; -import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/animal'); diff --git a/api/src/paths/funding-sources/index.ts b/api/src/paths/funding-sources/index.ts index c1e351df47..b06c056d35 100644 --- a/api/src/paths/funding-sources/index.ts +++ b/api/src/paths/funding-sources/index.ts @@ -2,12 +2,12 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; +import { getSystemUserFromRequest } from '../../express/request'; import { FundingSource, FundingSourceSupplementaryData } from '../../repositories/funding-source-repository'; import { authorizeRequestHandler } from '../../request-handlers/security/authorization'; import { FundingSourceService, IFundingSourceSearchParams } from '../../services/funding-source-service'; import { UserService } from '../../services/user-service'; import { getLogger } from '../../utils/logger'; -import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/funding-sources/index'); diff --git a/api/src/paths/observation/index.ts b/api/src/paths/observation/index.ts index f90f83be54..bb62e98814 100644 --- a/api/src/paths/observation/index.ts +++ b/api/src/paths/observation/index.ts @@ -2,6 +2,7 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; +import { getSystemUserFromRequest } from '../../express/request'; import { IObservationAdvancedFilters } from '../../models/observation-view'; import { observervationsWithSubcountDataSchema } from '../../openapi/schemas/observation'; import { paginationRequestQueryParamSchema } from '../../openapi/schemas/pagination'; @@ -13,7 +14,6 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; -import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/observation/index'); diff --git a/api/src/paths/project/index.ts b/api/src/paths/project/index.ts index 8d75b4294c..706229b28c 100644 --- a/api/src/paths/project/index.ts +++ b/api/src/paths/project/index.ts @@ -2,6 +2,7 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; +import { getSystemUserFromRequest } from '../../express/request'; import { IProjectAdvancedFilters } from '../../models/project-view'; import { paginationRequestQueryParamSchema, paginationResponseSchema } from '../../openapi/schemas/pagination'; import { authorizeRequestHandler, userHasValidRole } from '../../request-handlers/security/authorization'; @@ -12,7 +13,6 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; -import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/project/index'); diff --git a/api/src/paths/survey/index.ts b/api/src/paths/survey/index.ts index e443efa1a7..00bb977146 100644 --- a/api/src/paths/survey/index.ts +++ b/api/src/paths/survey/index.ts @@ -2,6 +2,7 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; +import { getSystemUserFromRequest } from '../../express/request'; import { ISurveyAdvancedFilters } from '../../models/survey-view'; import { paginationRequestQueryParamSchema, paginationResponseSchema } from '../../openapi/schemas/pagination'; import { authorizeRequestHandler, userHasValidRole } from '../../request-handlers/security/authorization'; @@ -12,7 +13,6 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; -import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/survey/index'); diff --git a/api/src/paths/telemetry/index.ts b/api/src/paths/telemetry/index.ts index be9e8ae91b..67bd17eb09 100644 --- a/api/src/paths/telemetry/index.ts +++ b/api/src/paths/telemetry/index.ts @@ -2,6 +2,7 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; +import { getSystemUserFromRequest } from '../../express/request'; import { ITelemetryAdvancedFilters } from '../../models/telemetry-view'; import { paginationRequestQueryParamSchema, paginationResponseSchema } from '../../openapi/schemas/pagination'; import { authorizeRequestHandler, userHasValidRole } from '../../request-handlers/security/authorization'; @@ -12,7 +13,6 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; -import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/telemetry'); diff --git a/api/src/paths/user/add.ts b/api/src/paths/user/add.ts index f8cfea33b6..5860fe691b 100644 --- a/api/src/paths/user/add.ts +++ b/api/src/paths/user/add.ts @@ -3,11 +3,11 @@ import { Operation } from 'express-openapi'; import { SOURCE_SYSTEM, SYSTEM_IDENTITY_SOURCE } from '../../constants/database'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection, getServiceClientDBConnection } from '../../database/db'; +import { getKeycloakTokenFromRequest } from '../../express/request'; import { authorizeRequestHandler } from '../../request-handlers/security/authorization'; import { UserService } from '../../services/user-service'; import { getKeycloakSource } from '../../utils/keycloak-utils'; import { getLogger } from '../../utils/logger'; -import { getKeycloakTokenFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/user/add'); diff --git a/api/src/services/bctw-service.ts b/api/src/services/bctw-service.ts index 136aee209a..2742d1c661 100644 --- a/api/src/services/bctw-service.ts +++ b/api/src/services/bctw-service.ts @@ -6,7 +6,7 @@ import { URLSearchParams } from 'url'; import { z } from 'zod'; import { ApiError, ApiErrorType, ApiGeneralError } from '../errors/api-error'; import { HTTP500 } from '../errors/http-error'; -import { getSystemUserFromRequest } from '../utils/request'; +import { getSystemUserFromRequest } from '../express/request'; import { KeycloakService } from './keycloak-service'; export const IDeployDevice = z.object({ diff --git a/api/src/utils/request.ts b/api/src/utils/request.ts index 019d077437..16c8c12904 100644 --- a/api/src/utils/request.ts +++ b/api/src/utils/request.ts @@ -1,6 +1,6 @@ import { Request } from 'express'; import { SystemUser } from '../repositories/user-repository'; -import { KeycloakUserInformation } from './keycloak-utils'; +import { KeycloakUserInformation } from '../utils/keycloak-utils'; /** * Get keycloak token from request or throw error. From 43f445a3b3511b49ac62f9133463ce05f29a93be Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Mon, 22 Jul 2024 10:20:02 -0700 Subject: [PATCH 10/13] feat: extended express request to include authorization_scheme --- api/src/express/request.ts | 24 +++++++++++++++---- api/src/middleware/critterbase-proxy.ts | 2 +- .../security/authorization.ts | 7 +++--- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/api/src/express/request.ts b/api/src/express/request.ts index bd7de79c79..df09f33397 100644 --- a/api/src/express/request.ts +++ b/api/src/express/request.ts @@ -1,23 +1,37 @@ import { Request } from 'express'; import { SystemUser } from '../repositories/user-repository'; +import { AuthorizationScheme } from '../services/authorization-service'; import { KeycloakUserInformation } from '../utils/keycloak-utils'; /** * Extending express request type. * + * Additional properties are populated during different stages of . + * */ declare module 'express-serve-static-core' { interface Request { /** * Keycloak user JWT token. * + * @see authentication.ts -> authenticateRequest() + * */ keycloak_token?: KeycloakUserInformation; /** * SIMS system user details. * + * @see authorization.ts -> authorizeRequest() + * */ system_user?: SystemUser; + /** + * Authorization Scheme object. + * + * @see authorization.ts -> authorizeRequestHandler() + * + */ + authorization_scheme?: AuthorizationScheme; } } @@ -28,13 +42,13 @@ declare module 'express-serve-static-core' { * * @see authentication.ts -> authenticateRequest() * - * @param {Request} req + * @param {Request} req - Express Request * @throws {Error} - Missing keycloak token * @returns {KeycloakUserInformation} */ export const getKeycloakTokenFromRequest = (req: Request): KeycloakUserInformation => { if (!req.keycloak_token) { - throw new Error('Request missing keycloak token.'); + throw new Error('Request missing keycloak token. Must be authenticated.'); } return req.keycloak_token; }; @@ -42,15 +56,17 @@ export const getKeycloakTokenFromRequest = (req: Request): KeycloakUserInformati /** * Get system user from request of throw error. * + * Value is defined for endpoints that authorize a user successfully against `AuthorizationScheme`. + * * @see authorization.ts -> authorizeRequest() * - * @param {Request} req + * @param {Request} req - Express Request * @throws {Error} - Missing system user * @returns {SystemUser} */ export const getSystemUserFromRequest = (req: Request): SystemUser => { if (!req.system_user) { - throw new Error('Request missing system user.'); + throw new Error('Request missing system user. Must be authorized.'); } return req.system_user; diff --git a/api/src/middleware/critterbase-proxy.ts b/api/src/middleware/critterbase-proxy.ts index b8d189df9f..fd0caa0205 100644 --- a/api/src/middleware/critterbase-proxy.ts +++ b/api/src/middleware/critterbase-proxy.ts @@ -104,7 +104,7 @@ export const getCritterbaseApiHostUrl = () => { export const authorizeAndAuthenticateMiddleware: RequestHandler = async (req, _, next) => { await authenticateRequest(req); - req['authorization_scheme'] = { + req.authorization_scheme = { and: [ { discriminator: 'SystemUser' diff --git a/api/src/request-handlers/security/authorization.ts b/api/src/request-handlers/security/authorization.ts index da17976f6e..0dfb0d0ae6 100644 --- a/api/src/request-handlers/security/authorization.ts +++ b/api/src/request-handlers/security/authorization.ts @@ -20,7 +20,8 @@ export type AuthorizationSchemeCallback = (req: Request) => AuthorizationScheme; */ export function authorizeRequestHandler(authorizationSchemeCallback: AuthorizationSchemeCallback): RequestHandler { return async (req, _, next) => { - req['authorization_scheme'] = authorizationSchemeCallback(req); + req.authorization_scheme = authorizationSchemeCallback(req); + const isAuthorized = await authorizeRequest(req); if (!isAuthorized) { @@ -35,7 +36,7 @@ export function authorizeRequestHandler(authorizationSchemeCallback: Authorizati /** * Returns `true` if the user is authorized successfully against the `AuthorizationScheme` in - * `req['authorization_scheme']`, `false` otherwise. + * `req.authorization_scheme`, `false` otherwise. * * Note: System administrators are automatically granted access, regardless of the authorization scheme provided. * @@ -46,7 +47,7 @@ export const authorizeRequest = async (req: Request): Promise => { const connection = getAPIUserDBConnection(); try { - const authorizationScheme: AuthorizationScheme = req['authorization_scheme']; + const authorizationScheme = req.authorization_scheme; if (!authorizationScheme) { // No authorization scheme specified, all authenticated users are authorized From 844eaa8da146cc586a09ea2ce93c7ffe3e5f75bb Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Mon, 22 Jul 2024 12:19:37 -0700 Subject: [PATCH 11/13] chore: moved express type to own file in types/express.d.ts --- api/src/express/request.ts | 73 ------------------------ api/src/paths/administrative-activity.ts | 2 +- api/src/paths/animal/index.ts | 2 +- api/src/paths/funding-sources/index.ts | 2 +- api/src/paths/observation/index.ts | 2 +- api/src/paths/project/index.ts | 2 +- api/src/paths/survey/index.ts | 2 +- api/src/paths/telemetry/index.ts | 2 +- api/src/paths/user/add.ts | 2 +- api/src/services/bctw-service.ts | 2 +- api/src/types/express.d.ts | 45 +++++++++++++++ api/src/utils/request.ts | 19 ++++-- 12 files changed, 68 insertions(+), 87 deletions(-) delete mode 100644 api/src/express/request.ts create mode 100644 api/src/types/express.d.ts diff --git a/api/src/express/request.ts b/api/src/express/request.ts deleted file mode 100644 index df09f33397..0000000000 --- a/api/src/express/request.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Request } from 'express'; -import { SystemUser } from '../repositories/user-repository'; -import { AuthorizationScheme } from '../services/authorization-service'; -import { KeycloakUserInformation } from '../utils/keycloak-utils'; - -/** - * Extending express request type. - * - * Additional properties are populated during different stages of . - * - */ -declare module 'express-serve-static-core' { - interface Request { - /** - * Keycloak user JWT token. - * - * @see authentication.ts -> authenticateRequest() - * - */ - keycloak_token?: KeycloakUserInformation; - /** - * SIMS system user details. - * - * @see authorization.ts -> authorizeRequest() - * - */ - system_user?: SystemUser; - /** - * Authorization Scheme object. - * - * @see authorization.ts -> authorizeRequestHandler() - * - */ - authorization_scheme?: AuthorizationScheme; - } -} - -/** - * Get keycloak token from request or throw error. - * - * Value is defined for endpoints that specify `Bearer` security with correct JWT token. - * - * @see authentication.ts -> authenticateRequest() - * - * @param {Request} req - Express Request - * @throws {Error} - Missing keycloak token - * @returns {KeycloakUserInformation} - */ -export const getKeycloakTokenFromRequest = (req: Request): KeycloakUserInformation => { - if (!req.keycloak_token) { - throw new Error('Request missing keycloak token. Must be authenticated.'); - } - return req.keycloak_token; -}; - -/** - * Get system user from request of throw error. - * - * Value is defined for endpoints that authorize a user successfully against `AuthorizationScheme`. - * - * @see authorization.ts -> authorizeRequest() - * - * @param {Request} req - Express Request - * @throws {Error} - Missing system user - * @returns {SystemUser} - */ -export const getSystemUserFromRequest = (req: Request): SystemUser => { - if (!req.system_user) { - throw new Error('Request missing system user. Must be authorized.'); - } - - return req.system_user; -}; diff --git a/api/src/paths/administrative-activity.ts b/api/src/paths/administrative-activity.ts index b74a88c978..77ea91d106 100644 --- a/api/src/paths/administrative-activity.ts +++ b/api/src/paths/administrative-activity.ts @@ -2,10 +2,10 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { getAPIUserDBConnection } from '../database/db'; import { HTTP400, HTTP500 } from '../errors/http-error'; -import { getKeycloakTokenFromRequest } from '../express/request'; import { AdministrativeActivityService } from '../services/administrative-activity-service'; import { getUserGuid } from '../utils/keycloak-utils'; import { getLogger } from '../utils/logger'; +import { getKeycloakTokenFromRequest } from '../utils/request'; const defaultLog = getLogger('paths/administrative-activity-request'); diff --git a/api/src/paths/animal/index.ts b/api/src/paths/animal/index.ts index 33e27cb60f..4c41fc5075 100644 --- a/api/src/paths/animal/index.ts +++ b/api/src/paths/animal/index.ts @@ -2,7 +2,6 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; -import { getSystemUserFromRequest } from '../../express/request'; import { IAnimalAdvancedFilters } from '../../models/animal-view'; import { paginationRequestQueryParamSchema, paginationResponseSchema } from '../../openapi/schemas/pagination'; import { authorizeRequestHandler, userHasValidRole } from '../../request-handlers/security/authorization'; @@ -13,6 +12,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/animal'); diff --git a/api/src/paths/funding-sources/index.ts b/api/src/paths/funding-sources/index.ts index b06c056d35..c1e351df47 100644 --- a/api/src/paths/funding-sources/index.ts +++ b/api/src/paths/funding-sources/index.ts @@ -2,12 +2,12 @@ import { RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; -import { getSystemUserFromRequest } from '../../express/request'; import { FundingSource, FundingSourceSupplementaryData } from '../../repositories/funding-source-repository'; import { authorizeRequestHandler } from '../../request-handlers/security/authorization'; import { FundingSourceService, IFundingSourceSearchParams } from '../../services/funding-source-service'; import { UserService } from '../../services/user-service'; import { getLogger } from '../../utils/logger'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/funding-sources/index'); diff --git a/api/src/paths/observation/index.ts b/api/src/paths/observation/index.ts index bb62e98814..f90f83be54 100644 --- a/api/src/paths/observation/index.ts +++ b/api/src/paths/observation/index.ts @@ -2,7 +2,6 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; -import { getSystemUserFromRequest } from '../../express/request'; import { IObservationAdvancedFilters } from '../../models/observation-view'; import { observervationsWithSubcountDataSchema } from '../../openapi/schemas/observation'; import { paginationRequestQueryParamSchema } from '../../openapi/schemas/pagination'; @@ -14,6 +13,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/observation/index'); diff --git a/api/src/paths/project/index.ts b/api/src/paths/project/index.ts index 706229b28c..8d75b4294c 100644 --- a/api/src/paths/project/index.ts +++ b/api/src/paths/project/index.ts @@ -2,7 +2,6 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; -import { getSystemUserFromRequest } from '../../express/request'; import { IProjectAdvancedFilters } from '../../models/project-view'; import { paginationRequestQueryParamSchema, paginationResponseSchema } from '../../openapi/schemas/pagination'; import { authorizeRequestHandler, userHasValidRole } from '../../request-handlers/security/authorization'; @@ -13,6 +12,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/project/index'); diff --git a/api/src/paths/survey/index.ts b/api/src/paths/survey/index.ts index 00bb977146..e443efa1a7 100644 --- a/api/src/paths/survey/index.ts +++ b/api/src/paths/survey/index.ts @@ -2,7 +2,6 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; -import { getSystemUserFromRequest } from '../../express/request'; import { ISurveyAdvancedFilters } from '../../models/survey-view'; import { paginationRequestQueryParamSchema, paginationResponseSchema } from '../../openapi/schemas/pagination'; import { authorizeRequestHandler, userHasValidRole } from '../../request-handlers/security/authorization'; @@ -13,6 +12,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/survey/index'); diff --git a/api/src/paths/telemetry/index.ts b/api/src/paths/telemetry/index.ts index 67bd17eb09..be9e8ae91b 100644 --- a/api/src/paths/telemetry/index.ts +++ b/api/src/paths/telemetry/index.ts @@ -2,7 +2,6 @@ import { Request, RequestHandler } from 'express'; import { Operation } from 'express-openapi'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection } from '../../database/db'; -import { getSystemUserFromRequest } from '../../express/request'; import { ITelemetryAdvancedFilters } from '../../models/telemetry-view'; import { paginationRequestQueryParamSchema, paginationResponseSchema } from '../../openapi/schemas/pagination'; import { authorizeRequestHandler, userHasValidRole } from '../../request-handlers/security/authorization'; @@ -13,6 +12,7 @@ import { makePaginationOptionsFromRequest, makePaginationResponse } from '../../utils/pagination'; +import { getSystemUserFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/telemetry'); diff --git a/api/src/paths/user/add.ts b/api/src/paths/user/add.ts index 5860fe691b..f8cfea33b6 100644 --- a/api/src/paths/user/add.ts +++ b/api/src/paths/user/add.ts @@ -3,11 +3,11 @@ import { Operation } from 'express-openapi'; import { SOURCE_SYSTEM, SYSTEM_IDENTITY_SOURCE } from '../../constants/database'; import { SYSTEM_ROLE } from '../../constants/roles'; import { getDBConnection, getServiceClientDBConnection } from '../../database/db'; -import { getKeycloakTokenFromRequest } from '../../express/request'; import { authorizeRequestHandler } from '../../request-handlers/security/authorization'; import { UserService } from '../../services/user-service'; import { getKeycloakSource } from '../../utils/keycloak-utils'; import { getLogger } from '../../utils/logger'; +import { getKeycloakTokenFromRequest } from '../../utils/request'; const defaultLog = getLogger('paths/user/add'); diff --git a/api/src/services/bctw-service.ts b/api/src/services/bctw-service.ts index 2742d1c661..136aee209a 100644 --- a/api/src/services/bctw-service.ts +++ b/api/src/services/bctw-service.ts @@ -6,7 +6,7 @@ import { URLSearchParams } from 'url'; import { z } from 'zod'; import { ApiError, ApiErrorType, ApiGeneralError } from '../errors/api-error'; import { HTTP500 } from '../errors/http-error'; -import { getSystemUserFromRequest } from '../express/request'; +import { getSystemUserFromRequest } from '../utils/request'; import { KeycloakService } from './keycloak-service'; export const IDeployDevice = z.object({ diff --git a/api/src/types/express.d.ts b/api/src/types/express.d.ts new file mode 100644 index 0000000000..372c576922 --- /dev/null +++ b/api/src/types/express.d.ts @@ -0,0 +1,45 @@ +import { SystemUser } from '../repositories/user-repository'; +import { AuthorizationScheme } from '../services/authorization-service'; +import { KeycloakUserInformation } from '../utils/keycloak-utils'; + +/** + * Extended Express Request. + * + * Note: Additional properties are populated during different stages of request. + * + * @see utils/request.ts - Request getter functions for extended properties + * + */ +declare module 'express-serve-static-core' { + interface Request { + /** + * Keycloak user JWT token object. + * + * Value is defined for endpoints that specify `Bearer` security with correct JWT token. + * + * @see authentication.ts -> authenticateRequest() + * + */ + keycloak_token?: KeycloakUserInformation; + + /** + * SIMS system user details object. + * + * Value is defined for endpoints that authorize a user successfully against `AuthorizationScheme`. + * + * @see authorization.ts -> authorizeRequest() + * + */ + system_user?: SystemUser; + + /** + * Authorization Scheme object. + * + * Value is defined for endpoints with Authorization. + * + * @see authorization.ts -> authorizeRequestHandler() + * + */ + authorization_scheme?: AuthorizationScheme; + } +} diff --git a/api/src/utils/request.ts b/api/src/utils/request.ts index 16c8c12904..a20e79fe86 100644 --- a/api/src/utils/request.ts +++ b/api/src/utils/request.ts @@ -1,31 +1,40 @@ import { Request } from 'express'; import { SystemUser } from '../repositories/user-repository'; -import { KeycloakUserInformation } from '../utils/keycloak-utils'; +import { KeycloakUserInformation } from './keycloak-utils'; /** * Get keycloak token from request or throw error. * - * @param {Request} req + * Value is defined for endpoints that specify `Bearer` security with correct JWT token. + * + * @see authentication.ts -> authenticateRequest() + * + * @param {Request} req - Express Request * @throws {Error} - Missing keycloak token * @returns {KeycloakUserInformation} */ export const getKeycloakTokenFromRequest = (req: Request): KeycloakUserInformation => { if (!req.keycloak_token) { - throw new Error('Request missing keycloak token.'); + throw new Error('Request missing keycloak token. Must be authenticated.'); } + return req.keycloak_token; }; /** * Get system user from request of throw error. * - * @param {Request} req + * Value is defined for endpoints that authorize a user successfully against `AuthorizationScheme`. + * + * @see authorization.ts -> authorizeRequest() + * + * @param {Request} req - Express Request * @throws {Error} - Missing system user * @returns {SystemUser} */ export const getSystemUserFromRequest = (req: Request): SystemUser => { if (!req.system_user) { - throw new Error('Request missing system user.'); + throw new Error('Request missing system user. Must be authorized.'); } return req.system_user; From 384a442f116c6cc8a2eaae3c4d143ef53bb759cb Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Mon, 22 Jul 2024 12:43:11 -0700 Subject: [PATCH 12/13] fix: updated mocks in db.ts --- api/src/__mocks__/db.ts | 5 ----- api/src/paths/codes.test.ts | 8 ++++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/api/src/__mocks__/db.ts b/api/src/__mocks__/db.ts index 771b31b503..8b528995cc 100644 --- a/api/src/__mocks__/db.ts +++ b/api/src/__mocks__/db.ts @@ -65,11 +65,6 @@ export class MockReq { query = {}; params = {}; body = {}; - files: any[] = []; - // Exists on authenticated requests. @see authentication.ts and authorization.ts - keycloak_token?: Record; - // Exists on authenticated requests. @see authentication.ts and authorization.ts - system_user?: Record; } export type ExtendedMockRes = MockRes & Response; diff --git a/api/src/paths/codes.test.ts b/api/src/paths/codes.test.ts index c7704de0b8..2e51289491 100644 --- a/api/src/paths/codes.test.ts +++ b/api/src/paths/codes.test.ts @@ -1,10 +1,10 @@ import chai, { expect } from 'chai'; -import { describe } from 'mocha'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; import * as db from '../database/db'; import { HTTPError } from '../errors/http-error'; import { CodeService } from '../services/code-service'; +import { KeycloakUserInformation } from '../utils/keycloak-utils'; import { getMockDBConnection, getRequestHandlerMocks } from '../__mocks__/db'; import * as codes from './codes'; @@ -24,7 +24,7 @@ describe('codes', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockReq.keycloak_token = {}; + mockReq.keycloak_token = {} as KeycloakUserInformation; try { const requestHandler = codes.getAllCodes(); @@ -47,7 +47,7 @@ describe('codes', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockReq.keycloak_token = {}; + mockReq.keycloak_token = {} as KeycloakUserInformation; const requestHandler = codes.getAllCodes(); @@ -66,7 +66,7 @@ describe('codes', () => { const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); - mockReq.keycloak_token = {}; + mockReq.keycloak_token = {} as KeycloakUserInformation; try { const requestHandler = codes.getAllCodes(); From f9bf299e4a3e431e8871b839cf136e758ff7b8cd Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Mon, 22 Jul 2024 12:46:56 -0700 Subject: [PATCH 13/13] fix: updated casting of KeycloakUserInformation in authentication.ts --- api/src/request-handlers/security/authentication.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/request-handlers/security/authentication.ts b/api/src/request-handlers/security/authentication.ts index 6ad6c74a46..c3d0fb6afb 100644 --- a/api/src/request-handlers/security/authentication.ts +++ b/api/src/request-handlers/security/authentication.ts @@ -73,7 +73,7 @@ export const authenticateRequest = async function (req: Request): Promise const signingKey = key.getPublicKey(); // Verify token using public signing key - const verifiedToken = verify(tokenString, signingKey, { issuer: [KEYCLOAK_ISSUER] }); + const verifiedToken = verify(tokenString, signingKey, { issuer: [KEYCLOAK_ISSUER] }) as KeycloakUserInformation; if (!verifiedToken) { defaultLog.warn({ label: 'authenticate', message: 'verified token was null' }); @@ -81,7 +81,7 @@ export const authenticateRequest = async function (req: Request): Promise } // Add the verified token to the request for future use, if needed - req.keycloak_token = verifiedToken as KeycloakUserInformation; + req.keycloak_token = verifiedToken; return true; } catch (error) {