From 8627c92614bd8e28f712855f2afe03e302cb4959 Mon Sep 17 00:00:00 2001 From: joeljoby02 Date: Thu, 23 Apr 2026 13:41:20 -0500 Subject: [PATCH 1/8] Documentation for routes functions --- routes/create.js | 19 ++++++++++++++++++- routes/delete.js | 21 +++++++++++++++++++-- routes/id.js | 34 ++++++++++++++++++++++++++++++++-- routes/query.js | 34 ++++++++++++++++++++++++++++++++-- routes/release.js | 18 +++++++++++++++++- routes/search.js | 36 ++++++++++++++++++++++++++++++++++-- 6 files changed, 152 insertions(+), 10 deletions(-) diff --git a/routes/create.js b/routes/create.js index 97b86975..66dc3844 100644 --- a/routes/create.js +++ b/routes/create.js @@ -5,8 +5,25 @@ const router = express.Router() import controller from '../db-controller.js' import auth from '../auth/index.js' +/** + * Handle POST /v1/api/create - Create new object + * Requires JWT authentication + * + * @async + * @param {object} req - Express request + * @param {object} req.body - JSON object to create + * @param {string} [req.body.@context] - JSON-LD context (optional) + * @param {object} req.user - Authenticated user from JWT + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Created object with @id and __rerum metadata + */ +export async function handleCreate(req, res, next) { + return controller.create(req, res, next) +} + router.route('/') - .post(auth.checkJwt, controller.create) + .post(auth.checkJwt, handleCreate) .all((req, res, next) => { res.statusMessage = 'Improper request method for creating, please use POST.' res.status(405) diff --git a/routes/delete.js b/routes/delete.js index 7e747ff3..a0d3bb2b 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -4,8 +4,25 @@ const router = express.Router() import controller from '../db-controller.js' import auth from '../auth/index.js' +/** + * Handle DELETE /v1/api/delete - Delete an object by body or ID + * Requires JWT authentication + * + * @async + * @param {object} req - Express request + * @param {string} [req.params._id] - Optional object ID from the URL + * @param {object} req.body - Object containing delete instructions + * @param {object} req.user - Authenticated user from JWT + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Deleted object metadata or status information + */ +export async function handleDelete(req, res, next) { + return controller.deleteObj(req, res, next) +} + router.route('/') - .delete(auth.checkJwt, controller.deleteObj) + .delete(auth.checkJwt, handleDelete) .all((req, res, next) => { res.statusMessage = 'Improper request method for deleting, please use DELETE.' res.status(405) @@ -13,7 +30,7 @@ router.route('/') }) router.route('/:_id') - .delete(auth.checkJwt, controller.deleteObj) + .delete(auth.checkJwt, handleDelete) .all((req, res, next) => { res.statusMessage = 'Improper request method for deleting, please use DELETE.' res.status(405) diff --git a/routes/id.js b/routes/id.js index 3c2e8988..841a307b 100644 --- a/routes/id.js +++ b/routes/id.js @@ -3,9 +3,39 @@ const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' +/** + * Handle GET /v1/id/:_id - Retrieve object by ID or slug + * Public endpoint, no authentication required + * + * @async + * @param {object} req - Express request + * @param {string} req.params._id - Object ID or slug + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Retrieved object or deleted object metadata + */ +export async function handleId(req, res, next) { + return controller.id(req, res, next) +} + +/** + * Handle HEAD /v1/id/:_id - Retrieve metadata headers for an object by ID or slug + * Public endpoint, no authentication required + * + * @async + * @param {object} req - Express request + * @param {string} req.params._id - Object ID or slug + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Head response with object metadata headers + */ +export async function handleIdHead(req, res, next) { + return controller.idHeadRequest(req, res, next) +} + router.route('/:_id') - .get(controller.id) - .head(controller.idHeadRequest) + .get(handleId) + .head(handleIdHead) .all((req, res, next) => { res.statusMessage = 'Improper request method, please use GET.' res.status(405) diff --git a/routes/query.js b/routes/query.js index 61c33c9b..0211c60f 100644 --- a/routes/query.js +++ b/routes/query.js @@ -3,9 +3,39 @@ const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' +/** + * Handle POST /v1/api/query - Query objects by matching properties + * Public endpoint, no authentication required + * + * @async + * @param {object} req - Express request + * @param {object} req.body - Query object with properties to match + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Array of matching objects + */ +export async function handleQuery(req, res, next) { + return controller.query(req, res, next) +} + +/** + * Handle HEAD /v1/api/query - Query head request for matching objects + * Public endpoint, no authentication required + * + * @async + * @param {object} req - Express request + * @param {object} req.body - Query object with properties to match + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Head response with matching object count headers + */ +export async function handleQueryHead(req, res, next) { + return controller.queryHeadRequest(req, res, next) +} + router.route('/') - .post(controller.query) - .head(controller.queryHeadRequest) + .post(handleQuery) + .head(handleQueryHead) .all((req, res, next) => { res.statusMessage = 'Improper request method for requesting objects with matching properties. Please use POST.' res.status(405) diff --git a/routes/release.js b/routes/release.js index 870c0d88..f691c417 100644 --- a/routes/release.js +++ b/routes/release.js @@ -5,8 +5,24 @@ const router = express.Router() import controller from '../db-controller.js' import auth from '../auth/index.js' +/** + * Handle PATCH /v1/api/release/:_id - Release an object to make it immutable + * Requires JWT authentication + * + * @async + * @param {object} req - Express request + * @param {string} req.params._id - Object ID or slug to release + * @param {object} req.user - Authenticated user from JWT + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Released object metadata with updated __rerum state + */ +export async function handleRelease(req, res, next) { + return controller.release(req, res, next) +} + router.route('/:_id') - .patch(auth.checkJwt, controller.release) + .patch(auth.checkJwt, handleRelease) .all((req, res, next) => { res.statusMessage = 'Improper request method for releasing, please use PATCH to release this object.' res.status(405) diff --git a/routes/search.js b/routes/search.js index 2053bf5a..5f00ebe4 100644 --- a/routes/search.js +++ b/routes/search.js @@ -2,16 +2,48 @@ import express from 'express' const router = express.Router() import controller from '../db-controller.js' +/** + * Handle POST /v1/api/search - Full-text search by words + * Public endpoint, no authentication required + * + * @async + * @param {object} req - Express request + * @param {object} req.body - Search query payload + * @param {string} req.body.query - Search terms to match + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Array of matching objects + */ +export async function handleSearchAsWords(req, res, next) { + return controller.searchAsWords(req, res, next) +} + router.route('/') - .post(controller.searchAsWords) + .post(handleSearchAsWords) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) next(res) }) +/** + * Handle POST /v1/api/search/phrase - Full-text search by phrase + * Public endpoint, no authentication required + * + * @async + * @param {object} req - Express request + * @param {object} req.body - Search query payload + * @param {string} req.body.query - Exact phrase to match + * @param {object} res - Express response + * @param {function} next - Express next middleware + * @returns {Promise} Array of matching objects + */ +export async function handleSearchAsPhrase(req, res, next) { + return controller.searchAsPhrase(req, res, next) +} + router.route('/phrase') - .post(controller.searchAsPhrase) + .post(handleSearchAsPhrase) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) From ed521a09bfc65c0b789dd07a3f9848afc6dfd166 Mon Sep 17 00:00:00 2001 From: joeljoby02 Date: Mon, 27 Apr 2026 13:19:49 -0500 Subject: [PATCH 2/8] Add rate limits --- package.json | 3 ++- routes/create.js | 8 +++++++- routes/delete.js | 12 ++++++++++-- routes/id.js | 12 ++++++++++-- routes/query.js | 12 ++++++++++-- routes/release.js | 8 +++++++- routes/search.js | 12 ++++++++++-- 7 files changed, 56 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 057182f6..45ee89d0 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "express-oauth2-jwt-bearer": "~1.7.1", "express-urlrewrite": "~2.0.3", "mongodb": "^7.0.0", - "morgan": "~1.10.1" + "morgan": "~1.10.1", + "express-rate-limit": "^8.4.0" }, "devDependencies": { "@jest/globals": "^30.2.0", diff --git a/routes/create.js b/routes/create.js index 66dc3844..169d13c9 100644 --- a/routes/create.js +++ b/routes/create.js @@ -4,6 +4,12 @@ const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' import auth from '../auth/index.js' +import rateLimit from 'express-rate-limit' + + const createRateLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100 + }) /** * Handle POST /v1/api/create - Create new object @@ -23,7 +29,7 @@ export async function handleCreate(req, res, next) { } router.route('/') - .post(auth.checkJwt, handleCreate) + .post(auth.checkJwt, createRateLimiter, handleCreate) .all((req, res, next) => { res.statusMessage = 'Improper request method for creating, please use POST.' res.status(405) diff --git a/routes/delete.js b/routes/delete.js index a0d3bb2b..151b482b 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -3,6 +3,14 @@ const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' import auth from '../auth/index.js' +import rateLimit from 'express-rate-limit' + +const deleteLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, + max: 100, + standardHeaders: true, + legacyHeaders: false +}) /** * Handle DELETE /v1/api/delete - Delete an object by body or ID @@ -22,7 +30,7 @@ export async function handleDelete(req, res, next) { } router.route('/') - .delete(auth.checkJwt, handleDelete) + .delete(deleteLimiter, auth.checkJwt, handleDelete) .all((req, res, next) => { res.statusMessage = 'Improper request method for deleting, please use DELETE.' res.status(405) @@ -30,7 +38,7 @@ router.route('/') }) router.route('/:_id') - .delete(auth.checkJwt, handleDelete) + .delete(deleteLimiter, auth.checkJwt, handleDelete) .all((req, res, next) => { res.statusMessage = 'Improper request method for deleting, please use DELETE.' res.status(405) diff --git a/routes/id.js b/routes/id.js index 841a307b..ab40785a 100644 --- a/routes/id.js +++ b/routes/id.js @@ -2,6 +2,14 @@ import express from 'express' const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' +import rateLimit from 'express-rate-limit' + +const idRouteLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, // limit each IP to 100 requests per windowMs + standardHeaders: true, + legacyHeaders: false +}) /** * Handle GET /v1/id/:_id - Retrieve object by ID or slug @@ -34,8 +42,8 @@ export async function handleIdHead(req, res, next) { } router.route('/:_id') - .get(handleId) - .head(handleIdHead) + .get(idRouteLimiter, handleId) + .head(idRouteLimiter, handleIdHead) .all((req, res, next) => { res.statusMessage = 'Improper request method, please use GET.' res.status(405) diff --git a/routes/query.js b/routes/query.js index 0211c60f..c1f1794f 100644 --- a/routes/query.js +++ b/routes/query.js @@ -2,6 +2,14 @@ import express from 'express' const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' +import rateLimit from 'express-rate-limit' + +const queryRateLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, + standardHeaders: true, + legacyHeaders: false +}) /** * Handle POST /v1/api/query - Query objects by matching properties @@ -34,8 +42,8 @@ export async function handleQueryHead(req, res, next) { } router.route('/') - .post(handleQuery) - .head(handleQueryHead) + .post(queryRateLimiter, handleQuery) + .head(queryRateLimiter, handleQueryHead) .all((req, res, next) => { res.statusMessage = 'Improper request method for requesting objects with matching properties. Please use POST.' res.status(405) diff --git a/routes/release.js b/routes/release.js index f691c417..9c4e3909 100644 --- a/routes/release.js +++ b/routes/release.js @@ -4,6 +4,12 @@ const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' import auth from '../auth/index.js' +import rateLimit from 'express-rate-limit' + +const releaseRateLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, // limit each IP to 100 requests per windowMs +}) /** * Handle PATCH /v1/api/release/:_id - Release an object to make it immutable @@ -22,7 +28,7 @@ export async function handleRelease(req, res, next) { } router.route('/:_id') - .patch(auth.checkJwt, handleRelease) + .patch(releaseRateLimiter, auth.checkJwt, handleRelease) .all((req, res, next) => { res.statusMessage = 'Improper request method for releasing, please use PATCH to release this object.' res.status(405) diff --git a/routes/search.js b/routes/search.js index 5f00ebe4..67e701fa 100644 --- a/routes/search.js +++ b/routes/search.js @@ -1,6 +1,14 @@ import express from 'express' const router = express.Router() import controller from '../db-controller.js' +import rateLimit from 'express-rate-limit' + +const searchRateLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, // limit each IP to 100 requests per window + standardHeaders: true, + legacyHeaders: false +}) /** * Handle POST /v1/api/search - Full-text search by words @@ -19,7 +27,7 @@ export async function handleSearchAsWords(req, res, next) { } router.route('/') - .post(handleSearchAsWords) + .post(searchRateLimiter, handleSearchAsWords) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) @@ -43,7 +51,7 @@ export async function handleSearchAsPhrase(req, res, next) { } router.route('/phrase') - .post(handleSearchAsPhrase) + .post(searchRateLimiter, handleSearchAsPhrase) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) From e2d4ff7d2b141683c3d7552cf85e3a9c7d5431a3 Mon Sep 17 00:00:00 2001 From: joeljoby02 Date: Mon, 27 Apr 2026 13:35:46 -0500 Subject: [PATCH 3/8] package.json changes --- package-lock.json | 87 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index c5f495e3..640aa60a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { "name": "rerum_server_nodejs", - "version": "0.0.0", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rerum_server_nodejs", - "version": "0.0.0", - "license": "UNLICENSED", + "version": "1.0.0", + "license": "MIT", "dependencies": { "cookie-parser": "~1.4.7", "cors": "^2.8.5", @@ -15,10 +15,14 @@ "dotenv": "~17.2.3", "express": "^5.2.1", "express-oauth2-jwt-bearer": "~1.7.1", + "express-rate-limit": "^8.4.0", "express-urlrewrite": "~2.0.3", "mongodb": "^7.0.0", "morgan": "~1.10.1" }, + "bin": { + "rerum_server_nodejs": "bin/rerum_v1.js" + }, "devDependencies": { "@jest/globals": "^30.2.0", "jest": "^30.2.0", @@ -1755,9 +1759,9 @@ } }, "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, "license": "MIT", "dependencies": { @@ -2579,6 +2583,24 @@ "node": "^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0 || ^20.2.0 || ^22.1.0 || ^24.0.0" } }, + "node_modules/express-rate-limit": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.4.1.tgz", + "integrity": "sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcliS8La5EPRN3p9wzItqBwJrfNw==", + "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, "node_modules/express-urlrewrite": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/express-urlrewrite/-/express-urlrewrite-2.0.3.tgz", @@ -3061,6 +3083,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -3743,9 +3774,9 @@ } }, "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -4093,13 +4124,13 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -4520,9 +4551,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -4623,9 +4654,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -4718,9 +4749,9 @@ } }, "node_modules/router/node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", @@ -5237,9 +5268,9 @@ } }, "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -5270,9 +5301,9 @@ } }, "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { From c597fc27424e903d4c0836168c484f056674da44 Mon Sep 17 00:00:00 2001 From: joeljoby02 Date: Tue, 28 Apr 2026 11:31:15 -0500 Subject: [PATCH 4/8] Revert "package.json changes" This reverts commit e2d4ff7d2b141683c3d7552cf85e3a9c7d5431a3. --- package-lock.json | 87 +++++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 59 deletions(-) diff --git a/package-lock.json b/package-lock.json index 640aa60a..c5f495e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { "name": "rerum_server_nodejs", - "version": "1.0.0", + "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rerum_server_nodejs", - "version": "1.0.0", - "license": "MIT", + "version": "0.0.0", + "license": "UNLICENSED", "dependencies": { "cookie-parser": "~1.4.7", "cors": "^2.8.5", @@ -15,14 +15,10 @@ "dotenv": "~17.2.3", "express": "^5.2.1", "express-oauth2-jwt-bearer": "~1.7.1", - "express-rate-limit": "^8.4.0", "express-urlrewrite": "~2.0.3", "mongodb": "^7.0.0", "morgan": "~1.10.1" }, - "bin": { - "rerum_server_nodejs": "bin/rerum_v1.js" - }, "devDependencies": { "@jest/globals": "^30.2.0", "jest": "^30.2.0", @@ -1759,9 +1755,9 @@ } }, "node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2583,24 +2579,6 @@ "node": "^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0 || ^20.2.0 || ^22.1.0 || ^24.0.0" } }, - "node_modules/express-rate-limit": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.4.1.tgz", - "integrity": "sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcliS8La5EPRN3p9wzItqBwJrfNw==", - "license": "MIT", - "dependencies": { - "ip-address": "10.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": ">= 4.11" - } - }, "node_modules/express-urlrewrite": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/express-urlrewrite/-/express-urlrewrite-2.0.3.tgz", @@ -3083,15 +3061,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -3774,9 +3743,9 @@ } }, "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -4124,13 +4093,13 @@ } }, "node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^2.0.1" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -4551,9 +4520,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { @@ -4654,9 +4623,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -4749,9 +4718,9 @@ } }, "node_modules/router/node_modules/path-to-regexp": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", - "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "license": "MIT", "funding": { "type": "opencollective", @@ -5268,9 +5237,9 @@ } }, "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -5301,9 +5270,9 @@ } }, "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { From 2ee86de6c0d8401b115d8d4382ad072492f0879f Mon Sep 17 00:00:00 2001 From: joeljoby02 Date: Tue, 28 Apr 2026 11:31:28 -0500 Subject: [PATCH 5/8] Revert "Add rate limits" This reverts commit ed521a09bfc65c0b789dd07a3f9848afc6dfd166. --- package.json | 3 +-- routes/create.js | 8 +------- routes/delete.js | 12 ++---------- routes/id.js | 12 ++---------- routes/query.js | 12 ++---------- routes/release.js | 8 +------- routes/search.js | 12 ++---------- 7 files changed, 11 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index 45ee89d0..057182f6 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,7 @@ "express-oauth2-jwt-bearer": "~1.7.1", "express-urlrewrite": "~2.0.3", "mongodb": "^7.0.0", - "morgan": "~1.10.1", - "express-rate-limit": "^8.4.0" + "morgan": "~1.10.1" }, "devDependencies": { "@jest/globals": "^30.2.0", diff --git a/routes/create.js b/routes/create.js index 169d13c9..66dc3844 100644 --- a/routes/create.js +++ b/routes/create.js @@ -4,12 +4,6 @@ const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' import auth from '../auth/index.js' -import rateLimit from 'express-rate-limit' - - const createRateLimiter = rateLimit({ - windowMs: 15 * 60 * 1000, // 15 minutes - max: 100 - }) /** * Handle POST /v1/api/create - Create new object @@ -29,7 +23,7 @@ export async function handleCreate(req, res, next) { } router.route('/') - .post(auth.checkJwt, createRateLimiter, handleCreate) + .post(auth.checkJwt, handleCreate) .all((req, res, next) => { res.statusMessage = 'Improper request method for creating, please use POST.' res.status(405) diff --git a/routes/delete.js b/routes/delete.js index 151b482b..a0d3bb2b 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -3,14 +3,6 @@ const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' import auth from '../auth/index.js' -import rateLimit from 'express-rate-limit' - -const deleteLimiter = rateLimit({ - windowMs: 15 * 60 * 1000, - max: 100, - standardHeaders: true, - legacyHeaders: false -}) /** * Handle DELETE /v1/api/delete - Delete an object by body or ID @@ -30,7 +22,7 @@ export async function handleDelete(req, res, next) { } router.route('/') - .delete(deleteLimiter, auth.checkJwt, handleDelete) + .delete(auth.checkJwt, handleDelete) .all((req, res, next) => { res.statusMessage = 'Improper request method for deleting, please use DELETE.' res.status(405) @@ -38,7 +30,7 @@ router.route('/') }) router.route('/:_id') - .delete(deleteLimiter, auth.checkJwt, handleDelete) + .delete(auth.checkJwt, handleDelete) .all((req, res, next) => { res.statusMessage = 'Improper request method for deleting, please use DELETE.' res.status(405) diff --git a/routes/id.js b/routes/id.js index ab40785a..841a307b 100644 --- a/routes/id.js +++ b/routes/id.js @@ -2,14 +2,6 @@ import express from 'express' const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' -import rateLimit from 'express-rate-limit' - -const idRouteLimiter = rateLimit({ - windowMs: 15 * 60 * 1000, // 15 minutes - max: 100, // limit each IP to 100 requests per windowMs - standardHeaders: true, - legacyHeaders: false -}) /** * Handle GET /v1/id/:_id - Retrieve object by ID or slug @@ -42,8 +34,8 @@ export async function handleIdHead(req, res, next) { } router.route('/:_id') - .get(idRouteLimiter, handleId) - .head(idRouteLimiter, handleIdHead) + .get(handleId) + .head(handleIdHead) .all((req, res, next) => { res.statusMessage = 'Improper request method, please use GET.' res.status(405) diff --git a/routes/query.js b/routes/query.js index c1f1794f..0211c60f 100644 --- a/routes/query.js +++ b/routes/query.js @@ -2,14 +2,6 @@ import express from 'express' const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' -import rateLimit from 'express-rate-limit' - -const queryRateLimiter = rateLimit({ - windowMs: 15 * 60 * 1000, // 15 minutes - max: 100, - standardHeaders: true, - legacyHeaders: false -}) /** * Handle POST /v1/api/query - Query objects by matching properties @@ -42,8 +34,8 @@ export async function handleQueryHead(req, res, next) { } router.route('/') - .post(queryRateLimiter, handleQuery) - .head(queryRateLimiter, handleQueryHead) + .post(handleQuery) + .head(handleQueryHead) .all((req, res, next) => { res.statusMessage = 'Improper request method for requesting objects with matching properties. Please use POST.' res.status(405) diff --git a/routes/release.js b/routes/release.js index 9c4e3909..f691c417 100644 --- a/routes/release.js +++ b/routes/release.js @@ -4,12 +4,6 @@ const router = express.Router() //This controller will handle all MongoDB interactions. import controller from '../db-controller.js' import auth from '../auth/index.js' -import rateLimit from 'express-rate-limit' - -const releaseRateLimiter = rateLimit({ - windowMs: 15 * 60 * 1000, // 15 minutes - max: 100, // limit each IP to 100 requests per windowMs -}) /** * Handle PATCH /v1/api/release/:_id - Release an object to make it immutable @@ -28,7 +22,7 @@ export async function handleRelease(req, res, next) { } router.route('/:_id') - .patch(releaseRateLimiter, auth.checkJwt, handleRelease) + .patch(auth.checkJwt, handleRelease) .all((req, res, next) => { res.statusMessage = 'Improper request method for releasing, please use PATCH to release this object.' res.status(405) diff --git a/routes/search.js b/routes/search.js index 67e701fa..5f00ebe4 100644 --- a/routes/search.js +++ b/routes/search.js @@ -1,14 +1,6 @@ import express from 'express' const router = express.Router() import controller from '../db-controller.js' -import rateLimit from 'express-rate-limit' - -const searchRateLimiter = rateLimit({ - windowMs: 15 * 60 * 1000, // 15 minutes - max: 100, // limit each IP to 100 requests per window - standardHeaders: true, - legacyHeaders: false -}) /** * Handle POST /v1/api/search - Full-text search by words @@ -27,7 +19,7 @@ export async function handleSearchAsWords(req, res, next) { } router.route('/') - .post(searchRateLimiter, handleSearchAsWords) + .post(handleSearchAsWords) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) @@ -51,7 +43,7 @@ export async function handleSearchAsPhrase(req, res, next) { } router.route('/phrase') - .post(searchRateLimiter, handleSearchAsPhrase) + .post(handleSearchAsPhrase) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) From 0ee75128b8b8c65b4aee98c5150c71ca16d7cdca Mon Sep 17 00:00:00 2001 From: joeljoby02 Date: Tue, 28 Apr 2026 11:58:57 -0500 Subject: [PATCH 6/8] Removed async functions --- routes/create.js | 8 ++++---- routes/delete.js | 4 ++-- routes/id.js | 4 ++-- routes/query.js | 10 +++++----- routes/release.js | 8 ++++---- routes/search.js | 8 ++++---- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/routes/create.js b/routes/create.js index 66dc3844..a8b77c95 100644 --- a/routes/create.js +++ b/routes/create.js @@ -18,12 +18,12 @@ import auth from '../auth/index.js' * @param {function} next - Express next middleware * @returns {Promise} Created object with @id and __rerum metadata */ -export async function handleCreate(req, res, next) { - return controller.create(req, res, next) -} +// export async function handleCreate(req, res, next) { +// return controller.create(req, res, next) +// } router.route('/') - .post(auth.checkJwt, handleCreate) + .post(auth.checkJwt, controller.create) .all((req, res, next) => { res.statusMessage = 'Improper request method for creating, please use POST.' res.status(405) diff --git a/routes/delete.js b/routes/delete.js index a0d3bb2b..9baf4cda 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -22,7 +22,7 @@ export async function handleDelete(req, res, next) { } router.route('/') - .delete(auth.checkJwt, handleDelete) + .delete(auth.checkJwt, controller.deleteObj) .all((req, res, next) => { res.statusMessage = 'Improper request method for deleting, please use DELETE.' res.status(405) @@ -30,7 +30,7 @@ router.route('/') }) router.route('/:_id') - .delete(auth.checkJwt, handleDelete) + .delete(auth.checkJwt, controller.deleteObj) .all((req, res, next) => { res.statusMessage = 'Improper request method for deleting, please use DELETE.' res.status(405) diff --git a/routes/id.js b/routes/id.js index 841a307b..31b78554 100644 --- a/routes/id.js +++ b/routes/id.js @@ -34,8 +34,8 @@ export async function handleIdHead(req, res, next) { } router.route('/:_id') - .get(handleId) - .head(handleIdHead) + .get(idRouteLimiter, handleId) + .head(idRouteLimiter, handleIdHead) .all((req, res, next) => { res.statusMessage = 'Improper request method, please use GET.' res.status(405) diff --git a/routes/query.js b/routes/query.js index 0211c60f..d024d46c 100644 --- a/routes/query.js +++ b/routes/query.js @@ -29,13 +29,13 @@ export async function handleQuery(req, res, next) { * @param {function} next - Express next middleware * @returns {Promise} Head response with matching object count headers */ -export async function handleQueryHead(req, res, next) { - return controller.queryHeadRequest(req, res, next) -} +// export async function handleQueryHead(req, res, next) { +// return controller.queryHeadRequest(req, res, next) +// } router.route('/') - .post(handleQuery) - .head(handleQueryHead) + .post(queryRateLimiter, handleQuery) + .head(queryRateLimiter, handleQueryHead) .all((req, res, next) => { res.statusMessage = 'Improper request method for requesting objects with matching properties. Please use POST.' res.status(405) diff --git a/routes/release.js b/routes/release.js index f691c417..80037fc4 100644 --- a/routes/release.js +++ b/routes/release.js @@ -17,12 +17,12 @@ import auth from '../auth/index.js' * @param {function} next - Express next middleware * @returns {Promise} Released object metadata with updated __rerum state */ -export async function handleRelease(req, res, next) { - return controller.release(req, res, next) -} +// export async function handleRelease(req, res, next) { +// return controller.release(req, res, next) +// } router.route('/:_id') - .patch(auth.checkJwt, handleRelease) + .patch(releaseRateLimiter, auth.checkJwt, handleRelease) .all((req, res, next) => { res.statusMessage = 'Improper request method for releasing, please use PATCH to release this object.' res.status(405) diff --git a/routes/search.js b/routes/search.js index 5f00ebe4..3bbf5150 100644 --- a/routes/search.js +++ b/routes/search.js @@ -38,12 +38,12 @@ router.route('/') * @param {function} next - Express next middleware * @returns {Promise} Array of matching objects */ -export async function handleSearchAsPhrase(req, res, next) { - return controller.searchAsPhrase(req, res, next) -} +// export async function handleSearchAsPhrase(req, res, next) { +// return controller.searchAsPhrase(req, res, next) +// } router.route('/phrase') - .post(handleSearchAsPhrase) + .post(searchRateLimiter, handleSearchAsWords) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) From 614c8bddaf4c89ae640e1fec34bdc111b2cb353c Mon Sep 17 00:00:00 2001 From: joeljoby02 Date: Tue, 28 Apr 2026 12:03:27 -0500 Subject: [PATCH 7/8] More reverts --- routes/delete.js | 6 +++--- routes/id.js | 16 ++++++++-------- routes/query.js | 4 ++-- routes/release.js | 2 +- routes/search.js | 10 +++++----- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/routes/delete.js b/routes/delete.js index 9baf4cda..1539ea5d 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -17,9 +17,9 @@ import auth from '../auth/index.js' * @param {function} next - Express next middleware * @returns {Promise} Deleted object metadata or status information */ -export async function handleDelete(req, res, next) { - return controller.deleteObj(req, res, next) -} +// export async function handleDelete(req, res, next) { +// return controller.deleteObj(req, res, next) +// } router.route('/') .delete(auth.checkJwt, controller.deleteObj) diff --git a/routes/id.js b/routes/id.js index 31b78554..28a31df1 100644 --- a/routes/id.js +++ b/routes/id.js @@ -14,9 +14,9 @@ import controller from '../db-controller.js' * @param {function} next - Express next middleware * @returns {Promise} Retrieved object or deleted object metadata */ -export async function handleId(req, res, next) { - return controller.id(req, res, next) -} +// export async function handleId(req, res, next) { +// return controller.id(req, res, next) +// } /** * Handle HEAD /v1/id/:_id - Retrieve metadata headers for an object by ID or slug @@ -29,13 +29,13 @@ export async function handleId(req, res, next) { * @param {function} next - Express next middleware * @returns {Promise} Head response with object metadata headers */ -export async function handleIdHead(req, res, next) { - return controller.idHeadRequest(req, res, next) -} +// export async function handleIdHead(req, res, next) { +// return controller.idHeadRequest(req, res, next) +// } router.route('/:_id') - .get(idRouteLimiter, handleId) - .head(idRouteLimiter, handleIdHead) + .get(controller.id) + .head(controller.idHeadRequest) .all((req, res, next) => { res.statusMessage = 'Improper request method, please use GET.' res.status(405) diff --git a/routes/query.js b/routes/query.js index d024d46c..eb65f1ca 100644 --- a/routes/query.js +++ b/routes/query.js @@ -34,8 +34,8 @@ export async function handleQuery(req, res, next) { // } router.route('/') - .post(queryRateLimiter, handleQuery) - .head(queryRateLimiter, handleQueryHead) + .post(controller.query) + .head(controller.queryHeadRequest) .all((req, res, next) => { res.statusMessage = 'Improper request method for requesting objects with matching properties. Please use POST.' res.status(405) diff --git a/routes/release.js b/routes/release.js index 80037fc4..10b4ce4f 100644 --- a/routes/release.js +++ b/routes/release.js @@ -22,7 +22,7 @@ import auth from '../auth/index.js' // } router.route('/:_id') - .patch(releaseRateLimiter, auth.checkJwt, handleRelease) + .patch(auth.checkJwt, controller.release) .all((req, res, next) => { res.statusMessage = 'Improper request method for releasing, please use PATCH to release this object.' res.status(405) diff --git a/routes/search.js b/routes/search.js index 3bbf5150..7e4ed8bf 100644 --- a/routes/search.js +++ b/routes/search.js @@ -14,12 +14,12 @@ import controller from '../db-controller.js' * @param {function} next - Express next middleware * @returns {Promise} Array of matching objects */ -export async function handleSearchAsWords(req, res, next) { - return controller.searchAsWords(req, res, next) -} +// export async function handleSearchAsWords(req, res, next) { +// return controller.searchAsWords(req, res, next) +// } router.route('/') - .post(handleSearchAsWords) + .post(controller.searchAsWords) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) @@ -43,7 +43,7 @@ router.route('/') // } router.route('/phrase') - .post(searchRateLimiter, handleSearchAsWords) + .post(controller.searchAsPhrase) .all((req, res, next) => { res.statusMessage = 'Improper request method for search. Please use POST.' res.status(405) From 119d085378989a7a0811a0f51b45df980545ba52 Mon Sep 17 00:00:00 2001 From: joeljoby02 Date: Tue, 28 Apr 2026 12:22:49 -0500 Subject: [PATCH 8/8] Reverted and only added docs to routes --- routes/create.js | 16 ++++------------ routes/delete.js | 18 +++++------------- routes/id.js | 30 ++++-------------------------- routes/query.js | 30 ++++-------------------------- routes/release.js | 16 ++++------------ routes/search.js | 28 ++++++---------------------- 6 files changed, 27 insertions(+), 111 deletions(-) diff --git a/routes/create.js b/routes/create.js index a8b77c95..386724f8 100644 --- a/routes/create.js +++ b/routes/create.js @@ -6,22 +6,14 @@ import controller from '../db-controller.js' import auth from '../auth/index.js' /** - * Handle POST /v1/api/create - Create new object + * POST /v1/api/create - Create new object * Requires JWT authentication - * - * @async - * @param {object} req - Express request + * * @param {object} req.body - JSON object to create * @param {string} [req.body.@context] - JSON-LD context (optional) - * @param {object} req.user - Authenticated user from JWT - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Created object with @id and __rerum metadata + * @param {object} req.user - Authenticated user from JWT token + * @returns {object} Created object with @id and __rerum metadata */ -// export async function handleCreate(req, res, next) { -// return controller.create(req, res, next) -// } - router.route('/') .post(auth.checkJwt, controller.create) .all((req, res, next) => { diff --git a/routes/delete.js b/routes/delete.js index 1539ea5d..74940f14 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -5,22 +5,14 @@ import controller from '../db-controller.js' import auth from '../auth/index.js' /** - * Handle DELETE /v1/api/delete - Delete an object by body or ID + * DELETE /v1/api/delete or DELETE /v1/api/delete/:_id - Delete an object * Requires JWT authentication - * - * @async - * @param {object} req - Express request - * @param {string} [req.params._id] - Optional object ID from the URL + * + * @param {string} [req.params._id] - Optional object ID from URL * @param {object} req.body - Object containing delete instructions - * @param {object} req.user - Authenticated user from JWT - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Deleted object metadata or status information + * @param {object} req.user - Authenticated user from JWT token + * @returns {object} Deleted object metadata or status information */ -// export async function handleDelete(req, res, next) { -// return controller.deleteObj(req, res, next) -// } - router.route('/') .delete(auth.checkJwt, controller.deleteObj) .all((req, res, next) => { diff --git a/routes/id.js b/routes/id.js index 28a31df1..37c30232 100644 --- a/routes/id.js +++ b/routes/id.js @@ -4,35 +4,13 @@ const router = express.Router() import controller from '../db-controller.js' /** - * Handle GET /v1/id/:_id - Retrieve object by ID or slug + * GET /v1/id/:_id - Retrieve object by ID or slug + * HEAD /v1/id/:_id - Retrieve metadata headers for an object * Public endpoint, no authentication required - * - * @async - * @param {object} req - Express request + * * @param {string} req.params._id - Object ID or slug - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Retrieved object or deleted object metadata + * @returns {object} Retrieved object or deleted object metadata */ -// export async function handleId(req, res, next) { -// return controller.id(req, res, next) -// } - -/** - * Handle HEAD /v1/id/:_id - Retrieve metadata headers for an object by ID or slug - * Public endpoint, no authentication required - * - * @async - * @param {object} req - Express request - * @param {string} req.params._id - Object ID or slug - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Head response with object metadata headers - */ -// export async function handleIdHead(req, res, next) { -// return controller.idHeadRequest(req, res, next) -// } - router.route('/:_id') .get(controller.id) .head(controller.idHeadRequest) diff --git a/routes/query.js b/routes/query.js index eb65f1ca..41717ce3 100644 --- a/routes/query.js +++ b/routes/query.js @@ -4,35 +4,13 @@ const router = express.Router() import controller from '../db-controller.js' /** - * Handle POST /v1/api/query - Query objects by matching properties + * POST /v1/api/query - Query objects by matching properties + * HEAD /v1/api/query - Query head request for matching objects * Public endpoint, no authentication required - * - * @async - * @param {object} req - Express request + * * @param {object} req.body - Query object with properties to match - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Array of matching objects + * @returns {object[]} Array of matching objects */ -export async function handleQuery(req, res, next) { - return controller.query(req, res, next) -} - -/** - * Handle HEAD /v1/api/query - Query head request for matching objects - * Public endpoint, no authentication required - * - * @async - * @param {object} req - Express request - * @param {object} req.body - Query object with properties to match - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Head response with matching object count headers - */ -// export async function handleQueryHead(req, res, next) { -// return controller.queryHeadRequest(req, res, next) -// } - router.route('/') .post(controller.query) .head(controller.queryHeadRequest) diff --git a/routes/release.js b/routes/release.js index 10b4ce4f..2c3b4ff6 100644 --- a/routes/release.js +++ b/routes/release.js @@ -6,21 +6,13 @@ import controller from '../db-controller.js' import auth from '../auth/index.js' /** - * Handle PATCH /v1/api/release/:_id - Release an object to make it immutable + * PATCH /v1/api/release/:_id - Release an object to make it immutable * Requires JWT authentication - * - * @async - * @param {object} req - Express request + * * @param {string} req.params._id - Object ID or slug to release - * @param {object} req.user - Authenticated user from JWT - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Released object metadata with updated __rerum state + * @param {object} req.user - Authenticated user from JWT token + * @returns {object} Released object metadata with updated __rerum state */ -// export async function handleRelease(req, res, next) { -// return controller.release(req, res, next) -// } - router.route('/:_id') .patch(auth.checkJwt, controller.release) .all((req, res, next) => { diff --git a/routes/search.js b/routes/search.js index 7e4ed8bf..a4c95a89 100644 --- a/routes/search.js +++ b/routes/search.js @@ -3,21 +3,13 @@ const router = express.Router() import controller from '../db-controller.js' /** - * Handle POST /v1/api/search - Full-text search by words + * POST /v1/api/search - Full-text search by words * Public endpoint, no authentication required - * - * @async - * @param {object} req - Express request + * * @param {object} req.body - Search query payload * @param {string} req.body.query - Search terms to match - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Array of matching objects + * @returns {object[]} Array of matching objects */ -// export async function handleSearchAsWords(req, res, next) { -// return controller.searchAsWords(req, res, next) -// } - router.route('/') .post(controller.searchAsWords) .all((req, res, next) => { @@ -27,21 +19,13 @@ router.route('/') }) /** - * Handle POST /v1/api/search/phrase - Full-text search by phrase + * POST /v1/api/search/phrase - Full-text search by phrase * Public endpoint, no authentication required - * - * @async - * @param {object} req - Express request + * * @param {object} req.body - Search query payload * @param {string} req.body.query - Exact phrase to match - * @param {object} res - Express response - * @param {function} next - Express next middleware - * @returns {Promise} Array of matching objects + * @returns {object[]} Array of matching objects */ -// export async function handleSearchAsPhrase(req, res, next) { -// return controller.searchAsPhrase(req, res, next) -// } - router.route('/phrase') .post(controller.searchAsPhrase) .all((req, res, next) => {