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