const express = require('express'); const router = express.Router(); import pool from '../db'; import { approveApplication, createApplication, denyApplication, getAllMemberApplications, getApplicationByID, getApplicationComments, getApplicationList, getMemberApplication } from '../services/applicationService'; import { setUserState } from '../services/memberService'; import { MemberState } from '@app/shared/types/member'; import { getRankByName, insertMemberRank } from '../services/rankService'; import { ApplicationFull, CommentRow } from "@app/shared/types/application" import { assignUserToStatus } from '../services/statusService'; import { Request, response, Response } from 'express'; import { getUserRoles } from '../services/rolesService'; import { requireLogin, requireRole } from '../middleware/auth'; //get CoC router.get('/coc', async (req: Request, res: Response) => { const output = await fetch(`${process.env.DOC_HOST}/api/pages/714`, { headers: { Authorization: `Token ${process.env.DOC_TOKEN_ID}:${process.env.DOC_TOKEN_SECRET}`, } }) if (output.ok) { const out = await output.json(); res.status(200).json(out.html); } else { console.error("Failed to fetch LOA policy from bookstack"); res.sendStatus(500); } }) // POST /application router.post('/', [requireLogin], async (req, res) => { try { const App = req.body?.App || {}; const memberID = req.user.id; const appVersion = 1; await createApplication(memberID, appVersion, JSON.stringify(App)) await setUserState(memberID, MemberState.Applicant); res.sendStatus(201); } catch (err) { console.error('Failed to create application: \n', err); res.status(500).json({ error: 'Failed to create application' }); } }); // GET /application/all router.get('/all', [requireLogin, requireRole("Recruiter")], async (req, res) => { try { const rows = await getApplicationList(); res.status(200).json(rows); } catch (err) { console.error(err); res.status(500); } }); router.get('/meList', async (req, res) => { let userID = req.user.id; try { let application = await getAllMemberApplications(userID); return res.status(200).json(application); } catch (error) { console.error('Failed to load applications: \n', error); return res.status(500).json(error); } }) router.get('/me', [requireLogin], async (req, res) => { let userID = req.user.id; try { let application = await getMemberApplication(userID); if (application === undefined) res.sendStatus(204); const comments: CommentRow[] = await getApplicationComments(application.id); const output: ApplicationFull = { application, comments, } return res.status(200).json(output); } catch (error) { console.error('Failed to load application:', error); return res.status(500).json(error); } }) // GET /application/:id router.get('/me/:id', [requireLogin], async (req: Request, res: Response) => { let appID = Number(req.params.id); let member = req.user.id; try { const application = await getApplicationByID(appID); if (application === undefined) return res.sendStatus(204); console.log(application.member_id, member) if (application.member_id != member) { return res.sendStatus(403); } const comments: CommentRow[] = await getApplicationComments(appID); const output: ApplicationFull = { application, comments, } return res.status(200).json(output); } catch (err) { console.error('Query failed:', err); return res.status(500).json({ error: 'Failed to load application' }); } }); // GET /application/:id router.get('/:id', [requireLogin, requireRole("Recruiter")], async (req: Request, res: Response) => { let appID = Number(req.params.id); let asAdmin = !!req.query.admin || false; try { const application = await getApplicationByID(appID); if (application === undefined) return res.sendStatus(204); const comments: CommentRow[] = await getApplicationComments(appID, asAdmin); const output: ApplicationFull = { application, comments, } return res.status(200).json(output); } catch (err) { console.error('Query failed:', err); return res.status(500).json({ error: 'Failed to load application' }); } }); // POST /application/approve/:id router.post('/approve/:id', [requireLogin, requireRole("Recruiter")], async (req: Request, res: Response) => { const appID = Number(req.params.id); const approved_by = req.user.id; try { const app = await getApplicationByID(appID); await approveApplication(appID, approved_by); //update user profile await setUserState(app.member_id, MemberState.Member); await pool.query('CALL sp_accept_new_recruit_validation(?, ?, ?, ?)', [Number(process.env.CONFIG_ID), app.member_id, approved_by, approved_by]) res.sendStatus(200); } catch (err) { console.error('Approve failed:', err); res.status(500).json({ error: 'Failed to approve application' }); } }); // POST /application/deny/:id router.post('/deny/:id', [requireLogin, requireRole("Recruiter")], async (req: Request, res: Response) => { const appID = Number(req.params.id); const approver = Number(req.user.id); try { const app = await getApplicationByID(appID); await denyApplication(appID, approver); await setUserState(app.member_id, MemberState.Denied); res.sendStatus(200); } catch (err) { console.error('Approve failed:', err); res.status(500).json({ error: 'Failed to deny application' }); } }); // POST /application/:id/comment router.post('/:id/comment', [requireLogin], async (req: Request, res: Response) => { const appID = req.params.id; const data = req.body.message; const user = req.user; console.log(user) const sql = `INSERT INTO application_comments( application_id, poster_id, post_content ) VALUES(?, ?, ?);` try { var conn = await pool.getConnection(); const result = await conn.query(sql, [appID, user.id, data]) console.log(result) if (result.affectedRows !== 1) { conn.release(); throw new Error("Insert Failure") } const getSQL = `SELECT app.id AS comment_id, app.post_content, app.poster_id, app.post_time, app.last_modified, member.name AS poster_name FROM application_comments AS app INNER JOIN members AS member ON member.id = app.poster_id WHERE app.id = ?; `; const comment = await conn.query(getSQL, [result.insertId]) res.status(201).json(comment[0]); } catch (err) { console.error('Comment failed:', err); res.status(500).json({ error: 'Could not post comment' }); } finally { conn.release(); } }); // POST /application/:id/comment router.post('/:id/adminComment', [requireLogin, requireRole("Recruiter")], async (req: Request, res: Response) => { const appID = req.params.id; const data = req.body.message; const user = req.user; console.log(user) const sql = `INSERT INTO application_comments( application_id, poster_id, post_content, admin_only ) VALUES(?, ?, ?, 1);` try { var conn = await pool.getConnection(); const result = await conn.query(sql, [appID, user.id, data]) console.log(result) if (result.affectedRows !== 1) { conn.release(); throw new Error("Insert Failure") } const getSQL = `SELECT app.id AS comment_id, app.post_content, app.poster_id, app.post_time, app.last_modified, app.admin_only, member.name AS poster_name FROM application_comments AS app INNER JOIN members AS member ON member.id = app.poster_id WHERE app.id = ?; `; const comment = await conn.query(getSQL, [result.insertId]) res.status(201).json(comment[0]); } catch (err) { console.error('Comment failed:', err); res.status(500).json({ error: 'Could not post comment' }); } finally { conn.release(); } }); router.post('/restart', async (req: Request, res: Response) => { const user = req.user.id; try { await setUserState(user, MemberState.Guest); res.sendStatus(200); } catch (error) { console.error('Comment failed:', error); res.status(500).json({ error: 'Could not rester application' }); } }) export const applicationRouter = router;