Commit | Line | Data |
---|---|---|
e99c53fb BA |
1 | let router = require("express").Router(); |
2 | const access = require("../utils/access"); | |
43828378 | 3 | const UserModel = require("../models/user"); |
e99c53fb | 4 | const AssessmentModel = require("../models/assessment"); |
43828378 | 5 | const CourseModel = require("../models/course"); |
e99c53fb BA |
6 | |
7 | // Actual pages (least specific last) | |
8 | ||
9 | // List initials and count assessments | |
10 | router.get("/", (req,res) => { | |
43828378 | 11 | UserModel.getAll( (err,userArray) => { |
e99c53fb BA |
12 | if (!!err) |
13 | return res.json(err); | |
14 | res.render("index", { | |
15 | title: "home", | |
16 | userArray: userArray, | |
17 | }); | |
18 | }); | |
19 | }); | |
20 | ||
21 | // Login screen | |
22 | router.get("/login", access.unlogged, (req,res) => { | |
23 | res.render("login", { | |
24 | title: "login", | |
25 | }); | |
26 | }); | |
27 | ||
28 | // Redirection screens when possible cheating attempt detected in exam | |
29 | router.get("/enablejs", (req,res) => { | |
cc7c0f5e | 30 | res.render("enablejs", { |
e99c53fb BA |
31 | title: "JS disabled", |
32 | }); | |
33 | }); | |
34 | ||
cc7c0f5e BA |
35 | router.get("/fullscreen", (req,res) => { |
36 | res.render("fullscreen", { | |
37 | title: "Not in fullscreen", | |
38 | }); | |
39 | }); | |
40 | ||
41 | router.get("/noblur", (req,res) => { | |
42 | res.render("noblur", { | |
43 | title: "Lost focus", | |
e99c53fb BA |
44 | }); |
45 | }); | |
46 | ||
47 | // List courses of some user (should be [a-z]+[0-9]* but fails...) | |
48 | router.get("/:initials([a-z0-9]+)", (req,res) => { | |
49 | let initials = req.params["initials"]; | |
50 | CourseModel.getByInitials(initials, (err,courseArray) => { | |
51 | if (!!err) | |
52 | return res.json(err); | |
53 | access.getUser(req, res, (err2,user) => { | |
54 | const isTeacher = !!user && user.initials == initials; | |
55 | // Strip students from courses if not course admin (TODO: not required in any case) | |
56 | if (!isTeacher) | |
57 | { | |
58 | courseArray.forEach( c => { | |
59 | delete c["students"]; | |
60 | }); | |
61 | } | |
62 | res.render("course-list", { | |
63 | title: initials + " courses", | |
64 | courseArray: courseArray, | |
65 | teacher: isTeacher, | |
66 | initials: initials, | |
67 | }); | |
68 | }); | |
69 | }); | |
70 | }); | |
71 | ||
72 | // Detailed content of one course | |
73 | router.get("/:initials([a-z0-9]+)/:courseCode([a-z0-9._-]+)", (req,res) => { | |
74 | let initials = req.params["initials"]; | |
75 | let code = req.params["courseCode"]; | |
76 | CourseModel.getByRefs(initials, code, (err,course) => { | |
77 | access.checkRequest(res, err, course, "Course not found", () => { | |
43828378 | 78 | AssessmentModel.getByCourse(course._id, (err2,assessmentArray) => { |
e99c53fb BA |
79 | if (!!err) |
80 | return res.json(err); | |
81 | access.getUser(req, res, (err2,user) => { | |
82 | const isTeacher = !!user && user.initials == initials; | |
83 | // Strip students from course if not course admin | |
84 | if (!isTeacher) | |
85 | delete course["students"]; | |
86 | res.render("course", { | |
87 | title: "course " + initials + "/" + code, | |
88 | course: course, | |
89 | assessmentArray: assessmentArray, | |
90 | teacher: isTeacher, | |
91 | initials: initials, | |
92 | }); | |
93 | }); | |
94 | }); | |
95 | }); | |
96 | }); | |
97 | }); | |
98 | ||
43828378 BA |
99 | // Grading students answers: --> after identification (password), always send secret with requests |
100 | router.get("/:initials([a-z0-9]+)/:courseCode([a-z0-9._-]+)/grade", (req,res) => { | |
101 | let initials = req.params["initials"]; | |
102 | let code = req.params["courseCode"]; | |
103 | // TODO: if (main) teacher, also send secret, saving one request | |
104 | res.render("grade", { | |
105 | title: "grade exams " + code + "/" + name, | |
106 | initials: initials, | |
107 | courseCode: code, | |
108 | }); | |
109 | }); | |
110 | ||
e99c53fb BA |
111 | // Display assessment (exam or open status) |
112 | router.get("/:initials([a-z0-9]+)/:courseCode([a-z0-9._-]+)/:assessmentName([a-z0-9._-]+)", (req,res) => { | |
113 | let initials = req.params["initials"]; | |
114 | let code = req.params["courseCode"]; | |
115 | let name = req.params["assessmentName"]; | |
116 | AssessmentModel.getByRefs(initials, code, name, (err,assessment) => { | |
117 | access.checkRequest(res, err, assessment, "Assessment not found", () => { | |
118 | if (!assessment.active) | |
119 | return res.json({errmsg: "Assessment is idle"}); | |
120 | delete assessment["papers"]; //always remove recorded students answers | |
121 | if (assessment.mode == "exam") | |
122 | { | |
123 | if (!!req.headers['user-agent'].match(/(SpecialAgent|HeadlessChrome|PhantomJS)/)) | |
124 | { | |
125 | // Basic headless browser detection | |
126 | return res.json({errmsg: "Headless browser detected"}); | |
127 | } | |
db5571d6 | 128 | // Strip questions if exam mode (stepwise process) |
e99c53fb BA |
129 | delete assessment["questions"]; |
130 | } | |
131 | res.render("assessment", { | |
132 | title: "assessment " + initials + "/" + code + "/" + name, | |
133 | assessment: assessment, | |
134 | }); | |
135 | }); | |
136 | }); | |
137 | }); | |
138 | ||
71d1ca9c | 139 | // Monitor: --> after identification (password), always send secret with requests |
e99c53fb BA |
140 | router.get("/:initials([a-z0-9]+)/:courseCode([a-z0-9._-]+)/:assessmentName([a-z0-9._-]+)/monitor", (req,res) => { |
141 | let initials = req.params["initials"]; | |
142 | let code = req.params["courseCode"]; | |
143 | let name = req.params["assessmentName"]; | |
71d1ca9c | 144 | // TODO: if (main) teacher, also send secret, saving one request |
e99c53fb BA |
145 | res.render("monitor", { |
146 | title: "monitor assessment " + code + "/" + name, | |
147 | initials: initials, | |
71d1ca9c BA |
148 | courseCode: code, |
149 | examName: name, | |
e99c53fb BA |
150 | }); |
151 | }); | |
152 | ||
153 | module.exports = router; |