diff --git a/src/api/RouteDescription.js b/src/api/RouteDescription.js
index 6ca426b..290fc82 100644
--- a/src/api/RouteDescription.js
+++ b/src/api/RouteDescription.js
@@ -56,10 +56,12 @@ export class RouteMethod {
* @type {Promise}
*/
method;
-
description;
-
exampleBody;
+ /*
+ * @type {Map<string, string>}
+ */
+ exampleHeaders = [];
/**
* @param data {RouteMethod}
@@ -68,7 +70,5 @@ export class RouteMethod {
for (const key of Object.keys(data)) {
this[key] = data[key];
}
-
- if (!Array.isArray(this.middlewares)) this.middlewares = [];
}
}
diff --git a/src/api/routes.js b/src/api/routes.js
index e808d50..b91e7ba 100644
--- a/src/api/routes.js
+++ b/src/api/routes.js
@@ -1,13 +1,26 @@
import * as routes from './routes/index.js';
+import * as url from 'node:url';
+import express from 'express';
-function logHttpEntry(method, route, exampleBody, description) {
- if (description) console.log('%', '#', description);
+function logHttpEntry(method, route, routeMethod) {
+ if (routeMethod.description) console.log('%', '#', routeMethod.description);
console.log('%', method, '{{baseUrl}}' + route, 'HTTP/1.1');
- if (exampleBody) {
+ if (routeMethod.exampleHeaders) {
+ for (var key of Object.keys(routeMethod.exampleHeaders)) {
+ console.log('%', `${key}: ${routeMethod.exampleHeaders[key]}`);
+ }
+ }
+ if (routeMethod.exampleBody) {
console.log('%', 'Content-Type: application/json');
console.log('% ');
- console.log('%', JSON.stringify(exampleBody, null, 4));
+ console.log(
+ '%',
+ JSON.stringify(routeMethod.exampleBody, null, 4).replaceAll(
+ '\n',
+ '\n% '
+ )
+ );
console.log('% ');
}
console.log('% ');
@@ -24,12 +37,15 @@ export function registerRoutes(app) {
* @type {RouteDescription}
*/
const route = routes[routeName];
+ if (route === undefined) return;
Object.keys(route.methods).forEach(routeMethodName => {
/**
* @type {RouteMethod}
*/
const routeMethod = route.methods[routeMethodName];
+ if (routeMethod === undefined) return;
+
console.log(
'Registering',
routeMethodName.toUpperCase(),
@@ -38,7 +54,7 @@ export function registerRoutes(app) {
logHttpEntry(
routeMethodName.toUpperCase(),
route.path,
- routeMethod.exampleBody
+ routeMethod
);
app[routeMethodName](route.path, [
...routeMethod.middlewares,
@@ -50,3 +66,12 @@ export function registerRoutes(app) {
console.log(`Registered ${routeCount} routes.`);
}
+
+if (import.meta.url.startsWith('file:')) {
+ const modulePath = url.fileURLToPath(import.meta.url);
+ if (process.argv[1] === modulePath) {
+ const app = express();
+ registerRoutes(app);
+ process.exit(1);
+ }
+}
diff --git a/src/api/routes/auth/accountRoutes.js b/src/api/routes/auth/accountRoutes.js
index 76452e3..a2181d1 100644
--- a/src/api/routes/auth/accountRoutes.js
+++ b/src/api/routes/auth/accountRoutes.js
@@ -9,6 +9,13 @@ export const registerRoute = {
path: '/auth/register',
methods: {
post: new RouteMethod({
+ description: 'Create a new user',
+ exampleBody: {
+ username: '{{username}}',
+ email: '{{email}}',
+ password: '{{email}}',
+ type: '{{userType}}'
+ },
async method(req, res) {
const data = await RegisterDto.create(req.body);
await registerUser(data);
@@ -25,6 +32,12 @@ export const loginRoute = {
path: '/auth/login',
methods: {
post: new RouteMethod({
+ description: 'Log in as a user',
+ exampleBody: {
+ username: '{{username}}',
+ email: '{{email}}',
+ password: '{{email}}'
+ },
async method(req, res) {
const data = await AuthDto.create(req.body);
const loginResult = await loginUser(
@@ -44,6 +57,10 @@ export const logoutRoute = {
path: '/auth/logout',
methods: {
post: new RouteMethod({
+ description: 'Log out from a device (TODO)',
+ exampleHeaders: {
+ Authorization: 'Bearer {{accessToken}}'
+ },
async method(req, res) {
const data = await AuthDto.create(req.body);
// const loginResult = await deleteDevice(data, );
@@ -60,6 +77,12 @@ export const deleteRoute = {
path: '/auth/delete',
methods: {
delete: new RouteMethod({
+ description: 'Delete account',
+ exampleBody: {
+ username: '{{username}}',
+ email: '{{email}}',
+ password: '{{email}}'
+ },
async method(req, res) {
const data = await AuthDto.create(req.body);
await deleteUser(data);
diff --git a/src/api/routes/auth/adminAccountRoutes.js b/src/api/routes/auth/adminAccountRoutes.js
index eb9b270..2153945 100644
--- a/src/api/routes/auth/adminAccountRoutes.js
+++ b/src/api/routes/auth/adminAccountRoutes.js
@@ -10,6 +10,10 @@ export const adminGetUsersRoute = {
path: '/admin/users',
methods: {
get: new RouteMethod({
+ description: 'Get all users (raw)',
+ exampleHeaders: {
+ Authorization: 'Bearer {{accessToken}}'
+ },
middlewares: [requireAdmin],
async method(req, res) {
res.send(DbUser.find({}).exec());
@@ -25,6 +29,10 @@ export const adminUserRoute = {
path: '/admin/user/:id',
methods: {
get: new RouteMethod({
+ description: 'Get a user (raw)',
+ exampleHeaders: {
+ Authorization: 'Bearer {{accessToken}}'
+ },
middlewares: [requireAdmin],
async method(req, res) {
const user = await getUserById(req.params.id);
diff --git a/src/api/routes/budgetRoutes.js b/src/api/routes/budgetRoutes.js
index a808f58..d7ebde4 100644
--- a/src/api/routes/budgetRoutes.js
+++ b/src/api/routes/budgetRoutes.js
@@ -4,23 +4,31 @@ import {
validateAuth
} from '#api/middlewares/index.js';
import { UserType } from '#db/schemas/index.js';
-import { RouteDescription, RouteMethod } from '#api/RouteDescription.js';
-import {getUserById} from "#db/dbAccess/index.js";
+import {
+ RouteDescription,
+ RouteMethod,
+ RouteMethodList
+} from '#api/RouteDescription.js';
+import { getUserById } from '#db/dbAccess/index.js';
/**
* @type {RouteDescription}
*/
export const getBudgetByUserRoute = {
path: '/budget/:id',
- methods: {
+ methods: new RouteMethodList({
get: new RouteMethod({
middlewares: [requireMonitor],
async method(req, res) {
- if (!req.)
- const user = await getUserById(req.);
+ if (req.user.type !== UserType.ADMIN) {
+ if (!req.user.monitoredUsers.includes(req.params.id))
+ throw new Error('meow');
+ }
+ //if (!req.)
+ // const user = await getUserById(req.);
}
})
- }
+ })
};
/**
@@ -44,7 +52,9 @@ export const getBudgetRoute = {
methods: {
get: new RouteMethod({
middlewares: [requireUser],
- async method(req, res) {}
+ async method(req, res) {
+ res.send({ currentBalance: req.user.balance });
+ }
})
}
};
diff --git a/src/api/routes/indexRoute.js b/src/api/routes/indexRoute.js
index b6fe28e..0c15b73 100644
--- a/src/api/routes/indexRoute.js
+++ b/src/api/routes/indexRoute.js
@@ -7,8 +7,11 @@ export const indexRoute = {
path: '/',
methods: {
get: new RouteMethod({
+ description: 'Get the index page (empty)',
method(req, res) {
- res.send('What art thou doing here???');
+ res.send(
+ "Welcome to SafeNSound! If you're confused, please visit the app instead!"
+ );
}
})
}
diff --git a/src/api/routes/statusRoute.js b/src/api/routes/statusRoute.js
index 1dbca45..2c111a8 100644
--- a/src/api/routes/statusRoute.js
+++ b/src/api/routes/statusRoute.js
@@ -8,6 +8,7 @@ export const statusRoute = {
path: '/status',
methods: {
get: new RouteMethod({
+ description: 'Get the server status',
async method(req, res) {
const status = {
status: 'ok',
|