diff --git a/src/controllers/passwordReset.controllers.js b/src/controllers/passwordReset.controllers.js index ec7af50..4f7bc12 100644 --- a/src/controllers/passwordReset.controllers.js +++ b/src/controllers/passwordReset.controllers.js @@ -55,26 +55,50 @@ async function render_reset_form(req, res) { try { const { token, userType } = req.query; + // ❌ Missing params if (!token || !userType) { - return res.render('auth/reset-password-error', { error: 'Reset token or user type is missing', userType: userType || 'va' }); + return res.render('auth/reset-password-error', { + title: "Reset Password", + layout: 'layouts/auth', + error: 'Reset token or user type is missing', + userType: userType || 'va' + }); } - // Validate token + // ✅ Validate token const validation = await passwordResetService.validateResetToken(token, userType); if (!validation.valid) { - return res.render('auth/reset-password-error', { error: validation.message, userType: userType || 'va' }); + return res.render('auth/reset-password-error', { + title: "Reset Password", + layout: 'layouts/auth', + error: validation.message, + userType: userType || 'va' + }); } - // Render reset form with token - res.render('auth/reset-password-form', { token, userType, error: null }); + // ✅ Render reset password form + return res.render('auth/reset-password-form', { + title: "Reset Password", + layout: 'layouts/auth', + token, + userType, + error: null + }); } catch (error) { logger.error(`PasswordResetController - Render form error: ${error.message}`); - res.render('auth/reset-password-error', { error: 'Failed to load reset form' }); + + return res.render('auth/reset-password-error', { + title: "Reset Password", + layout: 'layouts/auth', + error: 'Failed to load reset form', + userType: 'va' + }); } } + // Process password reset form submission (shared for both VA and Client) async function process_reset(req, res) { try { diff --git a/src/server.js b/src/server.js index 2657eb4..0a2a1b0 100644 --- a/src/server.js +++ b/src/server.js @@ -59,7 +59,9 @@ app.use('/api', apiRoutes); app.get("/download-tracker", (req, res) => { res.render("download_tracker", { - version: "3.2.1" + title: 'Download tracker', + version: "3.2.1", + layout: 'layouts/main' }); }); @@ -74,42 +76,64 @@ app.get("/download-file", (req, res) => { }); app.get('/varegister/:sf_token?', (req, res) => { - const { sf_token } = req.params; + const { sf_token } = req.params; - try { - const decoded = jwt.verify(sf_token, process.env.JWT_SECRET_SF_TOKEN); + // No token → invalid request + if (!sf_token) { + return res.status(404).render('not_found', { + title: 'Page Not Found', + layout: 'layouts/error' + }); + } - if (decoded) { - const email = decoded.email; - res.render('va_register', { title: "VA Registration", email }); - } else { - res.render('not_found', { title: "VA Registration" }); - } - } catch (error) { - res.render('not_found', { title: "VA Registration" }); - } + try { + const decoded = jwt.verify(sf_token, process.env.JWT_SECRET_SF_TOKEN); - // if(verified) { - // res.render('va_register', { title: "VA Registration" }); - // } else { - // res.render('not_founf', { title: "VA Registration" }); - // } + // Token valid + return res.render('va_register', { + title: 'VA Registration', + email: decoded.email, + layout: 'layouts/varegisterlayout' + }); + + } catch (error) { + // Invalid / expired token + return res.status(401).render('not_found', { + title: 'Invalid or Expired Link', + layout: 'layouts/error' + }); + } }); -app.get('/clientregister/:sf_token?', (req, res) => { - const { sf_token } = req.params; - try { - const decoded = jwt.verify(sf_token, process.env.JWT_SECRET_SF_TOKEN); - if (decoded) { - const email = decoded.email; - res.render('va_client_register', { title: "Client Registration", email }); - } else { - res.render('not_found', { title: "Client Registration" }); - } - } catch (error) { - res.render('not_found', { title: "Client Registration" }); - } +app.get('/clientregister/:sf_token?', (req, res) => { + const { sf_token } = req.params; + + // No token → invalid request + if (!sf_token) { + return res.status(404).render('not_found', { + title: 'Page Not Found', + layout: 'layouts/error' + }); + } + + try { + const decoded = jwt.verify(sf_token, process.env.JWT_SECRET_SF_TOKEN); + + // Token valid + return res.render('va_client_register', { + title: 'Client Registration', + email: decoded.email, + layout: 'layouts/vaclientlayout' + }); + + } catch (error) { + // Invalid / expired token + return res.status(401).render('not_found', { + title: 'Invalid or Expired Link', + layout: 'layouts/error' + }); + } }); app.get('/auth/password/reset-form', render_reset_form); @@ -119,7 +143,11 @@ app.get("/client/login", (req, res) => { }) app.get("/client/forgot-password", (req, res) => { - res.render("forgot_password") + + res.render("forgot_password", { + title: "Forgot Password", + layout: "layouts/forgotpasswordlayout" + }); }) // Client Dashboard Routes with new file names @@ -184,11 +212,12 @@ app.get('/client/virtual-assistants/view-logs', async (req, res) => { } }); + app.get("/live/:projectId/:vaId", async (req, res) => { const { projectId, vaId } = req.params; if (!projectId || !vaId) { - return res.status(400).send({ "message": "Page not found" }); + return res.status(400).render("not_found", { title: "Page not found" }); } let clientId = null; @@ -199,36 +228,45 @@ app.get("/live/:projectId/:vaId", async (req, res) => { } } catch (err) { console.error("Error fetching client for project:", err.message); - return; + return res.status(500).render("not_found", { title: "Server Error" }); } - if (!clientId) return res.status(400).send({ "message": "Page not found" }); - - res.render("va_live_tracker", { title: "VA Live Tracker", projectId, vaId, clientId }) -}) - -app.get("/live/:projectId/:vaId", async (req, res) => { - const { projectId, vaId } = req.params; - - if (!projectId || !vaId) { - return res.status(400).send({ "message": "Page not found" }); + if (!clientId) { + return res.status(400).render("not_found", { title: "Page not found" }); } - let clientId = null; - try { - const clientRes = await ProjectModel.findById(projectId); - if (clientRes) { - clientId = clientRes.clientId.toString(); - } - } catch (err) { - console.error("Error fetching client for project:", err.message); - return; - } + res.render("va_live_tracker", { + title: "VA Live Tracker", + projectId, + vaId, + clientId, + layout: "layouts/valivetrackerlayout" // ✅ ADD THIS + }); +}); - if (!clientId) return res.status(400).send({ "message": "Page not found" }); - res.render("va_live_tracker", { title: "VA Live Tracker", projectId, vaId, clientId }) -}) +// app.get("/live/:projectId/:vaId", async (req, res) => { +// const { projectId, vaId } = req.params; + + // if (!projectId || !vaId) { + // return res.status(400).send({ "message": "Page not found" }); + // } + + // let clientId = null; + // try { + // const clientRes = await ProjectModel.findById(projectId); + // if (clientRes) { + // clientId = clientRes.clientId.toString(); + // } + // } catch (err) { + // console.error("Error fetching client for project:", err.message); + // return; + // } + +// if (!clientId) return res.status(400).send({ "message": "Page not found" }); + +// res.render("va_live_tracker", { title: "VA Live Tracker", projectId, vaId, clientId }) +// }) // Handling Socket import { VAModel, ProjectModel, ClientModel } from './models/vaModel.js'; @@ -522,12 +560,13 @@ app.post("/post-test", (req, res) => { }); app.use((req, res) => { - res.status(404).render("not_found", { - title: "404 - Page Not Found" - }); + res.status(404).render("not_found", { + layout: "layouts/error", + title: "404 - Page Not Found" + }); }); -server.listen(PORT, "0.0.0.0", () => { +server.listen(PORT, () => { mongoose .connect( process.env.MONGO_URI, diff --git a/views/forgot_password.ejs b/views/forgot_password.ejs index 5dd4367..d70a162 100644 --- a/views/forgot_password.ejs +++ b/views/forgot_password.ejs @@ -1,121 +1,4 @@ - - - - - - DocVA | Reset Password - - - - -

DocTracker

@@ -200,6 +83,3 @@ }); }); - - - \ No newline at end of file diff --git a/views/layouts/auth.ejs b/views/layouts/auth.ejs new file mode 100644 index 0000000..eeac39d --- /dev/null +++ b/views/layouts/auth.ejs @@ -0,0 +1,18 @@ + + + + + + + <%= title || 'Auth' %> + + + + + + + <%- body %> + + + + \ No newline at end of file diff --git a/views/layouts/error.ejs b/views/layouts/error.ejs new file mode 100644 index 0000000..e63c5c8 --- /dev/null +++ b/views/layouts/error.ejs @@ -0,0 +1,103 @@ + + + + + + + 404 - Page Not Found + + + + + + + + <%- body %> + + + + \ No newline at end of file diff --git a/views/layouts/forgotpasswordlayout.ejs b/views/layouts/forgotpasswordlayout.ejs new file mode 100644 index 0000000..fce7d86 --- /dev/null +++ b/views/layouts/forgotpasswordlayout.ejs @@ -0,0 +1,122 @@ + + + + + + + DocVA | Reset Password + + + + + + <%- body %> + + + \ No newline at end of file diff --git a/views/layouts/main.ejs b/views/layouts/main.ejs index 17a9ca6..af8d302 100644 --- a/views/layouts/main.ejs +++ b/views/layouts/main.ejs @@ -13,5 +13,7 @@ <%- body %> + + diff --git a/views/layouts/vaclientlayout.ejs b/views/layouts/vaclientlayout.ejs new file mode 100644 index 0000000..1202493 --- /dev/null +++ b/views/layouts/vaclientlayout.ejs @@ -0,0 +1,17 @@ + + + + + + + Client Registration + + + + + + + <%- body %> + + + \ No newline at end of file diff --git a/views/layouts/valivetrackerlayout.ejs b/views/layouts/valivetrackerlayout.ejs new file mode 100644 index 0000000..3c2c7ec --- /dev/null +++ b/views/layouts/valivetrackerlayout.ejs @@ -0,0 +1,169 @@ + + + + + + Live Screen Feed + + + + + + <%- body %> + + + \ No newline at end of file diff --git a/views/layouts/varegisterlayout.ejs b/views/layouts/varegisterlayout.ejs new file mode 100644 index 0000000..31ca167 --- /dev/null +++ b/views/layouts/varegisterlayout.ejs @@ -0,0 +1,20 @@ + + + + + + Virtual Assistant Registration + + + + + + + + <%- body %> + + diff --git a/views/not_found.ejs b/views/not_found.ejs index e0a32cf..5b4fe9c 100644 --- a/views/not_found.ejs +++ b/views/not_found.ejs @@ -1,105 +1,10 @@ - - - - - - 404 - Page Not Found - - - - -
404 Icon

404

Oops! The page you're looking for does not exist.

- Go Home + Go Home
@@ -124,6 +29,3 @@ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", applyTheme); - - - \ No newline at end of file diff --git a/views/va_client_register.ejs b/views/va_client_register.ejs index 517c09f..b4aba55 100644 --- a/views/va_client_register.ejs +++ b/views/va_client_register.ejs @@ -1,16 +1,4 @@ - - - - - - Client Registration - - - - - - -
+
- +
-
- @@ -180,10 +172,13 @@
- +
- @@ -219,17 +214,20 @@
- +
-
- @@ -238,10 +236,13 @@
- +
- @@ -274,19 +275,26 @@
- - + +
-
- +
- @@ -324,26 +332,33 @@
- +
- +
-
- +
- @@ -355,19 +370,25 @@
- +
-
- +
- @@ -389,10 +410,13 @@
- +
- @@ -409,27 +433,26 @@
✓

Registration Complete!

-

Your account has been successfully created. You will receive a confirmation email shortly.

+

Your account has been successfully created. You will receive a confirmation email shortly. +

- - + - - + \ No newline at end of file diff --git a/views/va_live_tracker.ejs b/views/va_live_tracker.ejs index 471dc26..aa22c4e 100644 --- a/views/va_live_tracker.ejs +++ b/views/va_live_tracker.ejs @@ -1,293 +1,124 @@ - - + +
+ + + +
- - - Live Screen Feed + +
- - - - - -
- - - -
- - -
- - - -
-

Select an app to view

- Live Feed -
No app selected
-
- - - + }); - + socket.on("authError", () => { + socket.disconnect(); + localStorage.removeItem("knoptpq"); + window.location.href = "/client/login"; + }); - \ No newline at end of file + /* Receive images */ + socket.on("receiveImage", (base64, title) => { + if (currentApp && title === currentApp) { + liveImage.src = base64; + liveImage.style.display = "block"; + placeholder.style.display = "none"; + } + }); + \ No newline at end of file diff --git a/views/va_register.ejs b/views/va_register.ejs index cbd8866..83c76cd 100644 --- a/views/va_register.ejs +++ b/views/va_register.ejs @@ -1,25 +1,4 @@ - - - - - - Virtual Assistant Registration - - - - - -
@@ -346,5 +325,4 @@ const savedTheme = getSystemTheme(); setTheme(savedTheme); - - +