finished state and role based auth across the full API

This commit is contained in:
2025-12-14 11:38:45 -05:00
parent b91ecacb60
commit 9229475836
6 changed files with 23 additions and 17 deletions

View File

@@ -14,7 +14,7 @@ export function requireMemberState(state: MemberState) {
if (req.user?.state === state) if (req.user?.state === state)
next(); next();
else else
res.status(403).send("You must be a member of the 17th RBN to access this resource"); res.status(403).send(`You must be a ${state} of the 17th RBN to access this resource`);
} }
} }

View File

@@ -1,7 +1,8 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import { createEvent, getEventAttendance, getEventDetails, getShortEventsInRange, setAttendanceStatus, setEventCancelled, updateEvent } from "../services/calendarService"; import { createEvent, getEventAttendance, getEventDetails, getShortEventsInRange, setAttendanceStatus, setEventCancelled, updateEvent } from "../services/calendarService";
import { CalendarAttendance, CalendarEvent } from "@app/shared/types/calendar"; import { CalendarAttendance, CalendarEvent } from "@app/shared/types/calendar";
import { requireLogin } from "../middleware/auth"; import { requireLogin, requireMemberState, requireRole } from "../middleware/auth";
import { MemberState } from "../services/memberService";
const express = require('express'); const express = require('express');
const r = express.Router(); const r = express.Router();
@@ -36,7 +37,7 @@ r.get('/upcoming', async (req, res) => {
res.sendStatus(501); res.sendStatus(501);
}) })
r.post('/:id/cancel', [requireLogin], async (req: Request, res: Response) => { r.post('/:id/cancel', [requireLogin, requireMemberState(MemberState.Member)], async (req: Request, res: Response) => {
try { try {
const eventID = Number(req.params.id); const eventID = Number(req.params.id);
setEventCancelled(eventID, true); setEventCancelled(eventID, true);
@@ -46,7 +47,7 @@ r.post('/:id/cancel', [requireLogin], async (req: Request, res: Response) => {
res.status(500).send('Error setting cancel status'); res.status(500).send('Error setting cancel status');
} }
}) })
r.post('/:id/uncancel', [requireLogin], async (req: Request, res: Response) => { r.post('/:id/uncancel', [requireLogin, requireMemberState(MemberState.Member)], async (req: Request, res: Response) => {
try { try {
const eventID = Number(req.params.id); const eventID = Number(req.params.id);
setEventCancelled(eventID, false); setEventCancelled(eventID, false);
@@ -58,7 +59,7 @@ r.post('/:id/uncancel', [requireLogin], async (req: Request, res: Response) => {
}) })
r.post('/:id/attendance', [requireLogin], async (req: Request, res: Response) => { r.post('/:id/attendance', [requireLogin, requireMemberState(MemberState.Member)], async (req: Request, res: Response) => {
try { try {
let member = req.user.id; let member = req.user.id;
let event = Number(req.params.id); let event = Number(req.params.id);
@@ -86,7 +87,7 @@ r.get('/:id', async (req: Request, res: Response) => {
//post a new calendar event //post a new calendar event
r.post('/', [requireLogin], async (req: Request, res: Response) => { r.post('/', [requireLogin, requireMemberState(MemberState.Member)], async (req: Request, res: Response) => {
try { try {
const member = req.user.id; const member = req.user.id;
let event: CalendarEvent = req.body; let event: CalendarEvent = req.body;
@@ -101,7 +102,7 @@ r.post('/', [requireLogin], async (req: Request, res: Response) => {
} }
}) })
r.put('/', [requireLogin], async (req: Request, res: Response) => { r.put('/', [requireLogin, requireMemberState(MemberState.Member)], async (req: Request, res: Response) => {
try { try {
let event: CalendarEvent = req.body; let event: CalendarEvent = req.body;
event.start = new Date(event.start); event.start = new Date(event.start);

View File

@@ -1,13 +1,16 @@
import { CourseAttendee, CourseEventDetails } from "@app/shared/types/course"; import { CourseAttendee, CourseEventDetails } from "@app/shared/types/course";
import { getAllCourses, getCourseEventAttendees, getCourseEventDetails, getCourseEventRoles, getCourseEvents, insertCourseEvent } from "../services/CourseSerivce"; import { getAllCourses, getCourseEventAttendees, getCourseEventDetails, getCourseEventRoles, getCourseEvents, insertCourseEvent } from "../services/CourseSerivce";
import { Request, Response, Router } from "express"; import { Request, Response, Router } from "express";
import { requireLogin } from "../middleware/auth"; import { requireLogin, requireMemberState } from "../middleware/auth";
import { MemberState } from "../services/memberService";
const courseRouter = Router(); const courseRouter = Router();
const eventRouter = Router(); const eventRouter = Router();
courseRouter.use(requireLogin) courseRouter.use(requireLogin)
eventRouter.use(requireLogin) eventRouter.use(requireLogin)
courseRouter.use(requireMemberState(MemberState.Member))
eventRouter.use(requireMemberState(MemberState.Member))
courseRouter.get('/', async (req, res) => { courseRouter.get('/', async (req, res) => {
try { try {

View File

@@ -74,7 +74,7 @@ router.get('/:id', async (req, res) => {
//update a user's display name (stub) //update a user's display name (stub)
router.put('/:id/displayname', async (req, res) => { router.put('/:id/displayname', async (req, res) => {
// Stub: not implemented yet // Stub: not implemented yet
return res.status(501).json({ error: 'Update display name not implemented' }); return res.status(501);
}); });

View File

@@ -2,13 +2,14 @@ const express = require('express');
const r = express.Router(); const r = express.Router();
const ur = express.Router(); const ur = express.Router();
const { getAllRanks, insertMemberRank } = require('../services/rankService'); const { getAllRanks, insertMemberRank } = require('../services/rankService');
const { requireLogin } = require('../middleware/auth'); const { requireLogin, requireMemberState, requireRole } = require('../middleware/auth');
const { MemberState } = require('../services/memberService');
r.use(requireLogin) r.use(requireLogin)
ur.use(requireLogin) ur.use(requireLogin)
//insert a new latest rank for a user //insert a new latest rank for a user
ur.post('/', async (req, res) => { ur.post('/', [requireRole(["17th Command", "17th Administrator", "17th HQ"]),requireMemberState(MemberState.Member)], async (req, res) => {
3 3
try { try {
const change = req.body?.change; const change = req.body?.change;

View File

@@ -3,14 +3,15 @@ const r = express.Router();
const ur = express.Router(); const ur = express.Router();
import pool from '../db'; import pool from '../db';
import { requireLogin } from '../middleware/auth'; import { requireLogin, requireMemberState, requireRole } from '../middleware/auth';
import { MemberState } from '../services/memberService';
import { assignUserGroup, createGroup } from '../services/rolesService'; import { assignUserGroup, createGroup } from '../services/rolesService';
r.use(requireLogin) r.use(requireLogin)
ur.use(requireLogin) ur.use(requireLogin)
//manually assign a member to a group //manually assign a member to a group
ur.post('/', async (req, res) => { ur.post('/', [requireMemberState(MemberState.member), requireRole("17th Administrator")], async (req, res) => {
try { try {
const body = req.body; const body = req.body;
@@ -24,7 +25,7 @@ ur.post('/', async (req, res) => {
}); });
//manually remove member from group //manually remove member from group
ur.delete('/', async (req, res) => { ur.delete('/', [requireMemberState(MemberState.member), requireRole("17th Administrator")], async (req, res) => {
try { try {
const body = req.body; const body = req.body;
console.log(body); console.log(body);
@@ -42,7 +43,7 @@ ur.delete('/', async (req, res) => {
}) })
//get all roles //get all roles
r.get('/', async (req, res) => { r.get('/', [requireMemberState(MemberState.member)], async (req, res) => {
try { try {
const con = await pool.getConnection(); const con = await pool.getConnection();
@@ -81,7 +82,7 @@ r.get('/', async (req, res) => {
}); });
//create a new role //create a new role
r.post('/', async (req, res) => { r.post('/', [requireMemberState(MemberState.member), requireRole("17th Administrator")], async (req, res) => {
try { try {
const { name, color, description } = req.body; const { name, color, description } = req.body;
console.log('Creating role:', { name, color, description }); console.log('Creating role:', { name, color, description });
@@ -103,7 +104,7 @@ r.post('/', async (req, res) => {
} }
}) })
r.delete('/:id', async (req, res) => { r.delete('/:id', [requireMemberState(MemberState.member), requireRole("17th Administrator")], async (req, res) => {
try { try {
const id = req.params.id; const id = req.params.id;