diff --git a/.gitignore b/.gitignore index e073a39..05878a8 100644 --- a/.gitignore +++ b/.gitignore @@ -112,3 +112,7 @@ config/config.json # Sass output public/stylesheets + +# Floobits +.floo +.flooignore diff --git a/agenda/index.js b/agenda/index.js new file mode 100644 index 0000000..813cb12 --- /dev/null +++ b/agenda/index.js @@ -0,0 +1,18 @@ +const { Worker } = require("worker_threads"); +let nb = 0; + + +function startWorker(workerArgs) { + let worker = new Worker(...workerArgs); + worker.on("error", (err) => { + console.error(err); + nb--; + if (nb > 0) + startWorker(workerArgs); + }); +} + +module.exports = (app) => { + const workerArgs = ["./agenda/worker.js", {workerData: app.get("config")}]; + startWorker(workerArgs); +}; diff --git a/agenda/worker.js b/agenda/worker.js new file mode 100644 index 0000000..5a5f934 --- /dev/null +++ b/agenda/worker.js @@ -0,0 +1,229 @@ +const https = require("https"); +const config = require("worker_threads").workerData; +const models = require("../models"); + +const reg_event = /(?:(?:BEGIN:VEVENT\nDTSTAMP:(?:[A-Z0-9]*?)\nDTSTART:([A-Z0-9]*?)\nDTEND:([A-Z0-9]*?)\nSUMMARY: {0,}([a-zéèàA-Z0-9-. \, \\/ô]*?)\nLOCATION:([a-zA-Zéèà0-9-. \,\\]*?)\nDESCRIPTION:(?:\\n){0,}(LP(?:[ a-zA-Z0-9]*))\\n((?:(?:[A-Z]*) (?:[A-Z]*)(?: (?:[A-Z]*)){0,}\\n){0,})(?:.*?)\nEND:VEVENT)|(?:BEGIN:VEVENT\nDTSTAMP:(?:[A-Z0-9]*?)\nDTSTART:([A-Z0-9]*?)\nDTEND:([A-Z0-9]*?)\nSUMMARY: {0,}((?:S(?:[A-Z0-9-]*)|M(?:[A-Z0-9-]*)(?:\/M(?:[A-Z0-9-]*)){0,}|Conférence)[a-zéèàA-Z0-9-. \, \\/]*?)\nLOCATION:([a-zA-Zéèà0-9-. \,\\]*?)\nDESCRIPTION:(?:\\n){0,}((?:(?:G[0-9]S[0-9]|S[0-9]|ASPE)\\n){0,})((?:(?:[A-Z]*) (?:[A-Z]*)(?: (?:[A-Z]*)){0,}\\n){0,})(?:.*?)\nEND:VEVENT))/gs; +const reg_location = /((?:[SH0-9][0-9]{2})|(?:(?:Préfa |Amphi)[0-9]))/g; +const reg_teachers = /^(?:((?:[a-zA-Z]*[ -]{0,}){0,}) ([a-zA-Z]*))$/m; +const reg_date = /([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z/; +const reg_classe = /(?:(LP)[ -]{0,}(.*)|(?:(G[0-9])(S[0-9])))/; +const base_url = config["edt"]; + +function fetchEvents(days = 1, TS_Start = new Date()) { + return new Promise((resolve, reject) => { + let start = new Date(TS_Start); + if (start == "Invalid Date") + start = new Date(); + let end = new Date(start); + end.setDate(end.getDate() + days); + + let url = base_url + start.getFullYear() + "-" + start.getMonth() + "-" + start.getDate() + "&lastDate=" + end.getFullYear() + "-" + end.getMonth() + "-" + end.getDate(); + https.get(url, (resp) => { + let data = ""; + resp.on("data", (chunk) => { + data += chunk; + }); + resp.on("end", () => { + let output = []; + data = data.replace(/\r/g, ""); + let m; + while ((m = reg_event.exec(data)) !== null) { + if (m.index === reg_event.lastIndex) { + reg_event.lastIndex++; + } + let event = []; + let promotion = []; + let classe = []; + /* + m = [ + FullMatch, + StartTime, + EndTime, + EventDescription ( SubjectID,Name,Class?) , + Location, + ClassGroup, + Teacher(s) + ] + */ + if (m[1] !== undefined) { + // LPXXXX + classe.push(m[5]); + } else { + m.splice(1, 6); + // GXSX | SX | ASPE + let csplit = m[5].split("\\n"); + csplit.pop(); + csplit.forEach(e => { + if (e === "ASPE") promotion.push(e); + if (/^S[0-9]$/.test(e)) promotion.push(e); + if (/^G[0-9]S[0-9]$/.test(e)) classe.push(e); + }); + } + event["title"] = m[3]; + event["promotion"] = promotion; + event["class"] = classe; + /* + Date + */ + let d1 = reg_date.exec(m[1]); + let d2 = reg_date.exec(m[2]); + event["startDate"] = new Date(d1[1] + "-" + d1[2] + "-" + d1[3] + "T" + d1[4] + ":" + d1[5] + ":" + d1[6] + ".00Z"); + event["endDate"] = new Date(d2[1] + "-" + d2[2] + "-" + d2[3] + "T" + d2[4] + ":" + d2[5] + ":" + d2[6] + ".00Z"); + /* + Location + */ + event["locations"] = []; + let loc; + while ((loc = reg_location.exec(m[4])) !== null) { + if (loc.index === reg_location.lastIndex) { + reg_location.lastIndex++; + } + event["locations"].push(loc[1]); + } + /* + Teachers + */ + event['teachers'] = [] + let fullTeachers = m[6].split('\\n'); + fullTeachers.forEach(e => { + if(e !== ""){ + let splittedTeachers = reg_teachers.exec(e); + event['teachers'].push([splittedTeachers[1],splittedTeachers[2]]); + } + }); + output.push(event); + } + resolve(output); + }); + }).on("error", (err) => { + reject(err); + }); + }); +} + +function compare(a, b) { + if (a.length !== b.length) { + return false; + } + let set = {}; + a.forEach((i) => { + if (set[i] !== undefined) { + set[i]++; + } else { + set[i] = 1; + } + }); + let difference = b.every((i) => { + if (set[i] === undefined) { + return false; + } else { + set[i]--; + if (set[i] === 0) { + delete set[i]; + } + return true; + } + }); + return Object.keys(set) == 0 && difference; +} + +function compareGroups(list1, list2) { + return compare(list1, list2.map(g => [g.number, g.Semester.name, g.Semester.year])); +} + +function compareTeachers(list1, list2) { + return compare(list1, list2.map(t => t.lastName.toUpperCase() + " " + t.firstName.toUpperCase())); +} + +function compareSemesters(list1, list2) { + return compare(list1, list2.map(s => s.name)); +} + +async function updateDatabase() { + let events = await fetchEvents(365, new Date(2020, 9, 1)); + for (let event of await models.Event.findAll({ + include: [{ + model: models.Group, + include: {model: models.Semester, required: true} + }, models.User, models.Semester] + })) { + if (!events.find(e => (e.title === event.name && e.startDate.getTime() === event.startDate.getTime() && + e.endDate.getTime() === event.endDate.getTime() && e.locations.join(", ") === event.locations && + compareGroups(e.class, event.Groups) && compareTeachers(e.teachers, event.Users) && + compareSemesters(e.semesters, event.Semesters)))) + await event.destroy(); + else + delete events[events.indexOf(event)]; + } + + for (let event of events) { + let e = await models.Event.create({ + name: event.title, + startDate: event.startDate, + endDate: event.endDate, + locations: event.locations.join(", ") + }); + + let teachers = []; + for (let teacher of event.teachers) { + let t = await models.User.findOne({where: {permissions: 2, lastName: teacher[0], firstName: teacher[1]}}); + if (!t) + t = await models.User.create({ + email: teacher[1].toLowerCase().replace(" ", "-") + "." + teacher[0].toLowerCase().replace(" ", "-") + "@univ-lyon1.fr", + firstName: teacher[1], + lastName: teacher[0], + permissions: 2, + passwordHash: Math.round((Math.pow(36, 12 + 1) - Math.random() * Math.pow(36, 12))).toString(36).slice(1) + }); + teachers.push(t); + } + await e.addUsers(teachers); + + let semesters = []; + for (let semester of event.promotion) { + let s = await models.Semester.findOne({where: {name: semester, year: event.startDate.getFullYear()}}); + if (!s) + s = await models.Semester.create({ + name: semester, + year: event.startDate.getFullYear() + }); + semesters.push(s); + } + await e.addSemesters(semesters); + + let groups = []; + for (let group of event.class) { + let rGroup = reg_classe.exec(group); + let semesterName; + let groupName; + if (rGroup[1] !== undefined) { + // LP + semesterName = 'LP'; + groupName = rGroup[2]; + } else { + // GXSX + semesterName = rGroup[4]; + groupName = rGroup[3]; + } + + + let s = await models.Semester.findOne({where: {name: semesterName, year: event.startDate.getFullYear()}}); + if (!s) + s = await models.Semester.create({ + name: semesterName, + year: event.startDate.getFullYear() + }); + + let g = await models.Group.findOne({where: {number: groupName, SemesterId: s.id}}); + if (!g) + g = await models.Group.create({ + number: groupName, + SemesterId: s.id + }); + groups.push(g); + } + await e.addGroups(groups); + } +} + +updateDatabase().then(() => setInterval(updateDatabase, 30000)); diff --git a/app.js b/app.js index 5d204c4..caba270 100644 --- a/app.js +++ b/app.js @@ -12,8 +12,8 @@ const edtRouter = require("./routes/edt"); const homeRouter = require("./routes/home"); const marksRouter = require("./routes/marks"); const registerRouter = require("./routes/register"); -const viescolRouter = require("./routes/viescol") -const profilRouter = require("./routes/profil") +const viescolRouter = require("./routes/viescol"); +const profilRouter = require("./routes/profil"); let app = express(); const sessionMiddleware = session({ diff --git a/bin/www b/bin/www index e8cd115..b75ec66 100755 --- a/bin/www +++ b/bin/www @@ -30,7 +30,7 @@ fs.writeFileSync("public/stylesheets/style.css", css.css); * Get port from environment and store in Express. */ -let port = normalizePort(process.env.PORT || "3000"); +const port = normalizePort(process.env.PORT || "3000"); app.set("port", port); app.set("mailClient", mailClient); @@ -38,7 +38,7 @@ app.set("mailClient", mailClient); * Create HTTP server. */ -let server = http.createServer(app); +const server = http.createServer(app); /** * Create socket.io server @@ -66,7 +66,7 @@ models.sequelize.sync().then(() => { */ function normalizePort(val) { - let port = parseInt(val, 10); + const port = parseInt(val, 10); if (isNaN(port)) { // named pipe @@ -90,7 +90,7 @@ function onError(error) { throw error; } - let bind = typeof port === "string" + const bind = typeof port === "string" ? "Pipe " + port : "Port " + port; @@ -114,9 +114,10 @@ function onError(error) { */ function onListening() { - let addr = server.address(); - let bind = typeof addr === "string" + const addr = server.address(); + const bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port; debug("Listening on " + bind); + require("../agenda")(app); } diff --git a/config/config_example.json b/config/config_example.json index 6e93448..702ca17 100644 --- a/config/config_example.json +++ b/config/config_example.json @@ -18,6 +18,7 @@ "contact": "Your Contact ", "mailPath": "https://yourServer.com" }, + "edt": "https://adelb.univ-lyon1.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=XXXX&projectId=XXXX&calType=ical&firstDate=", "secret": "keyboard cat", "passwordPrivateKey": "ecc635295f200847b79299df48e15759" } diff --git a/models/UE.js b/models/UE.js new file mode 100644 index 0000000..acda65b --- /dev/null +++ b/models/UE.js @@ -0,0 +1,23 @@ +"use strict"; + +const { Model } = require("sequelize"); + +module.exports = (sequelize, DataTypes) => { + class UE extends Model { + static associate(models) { + UE.hasMany(models.Event); + UE.belongsToMany(models.User, {through: "UEUser"}); + } + } + UE.init({ + name : { + type: DataTypes.STRING, + allowNull: false, + unique: true + } + }, { + sequelize, + modelName: "UE", + }); + return UE; +}; diff --git a/models/event.js b/models/event.js new file mode 100644 index 0000000..8e0da6e --- /dev/null +++ b/models/event.js @@ -0,0 +1,36 @@ +"use strict"; + +const { Model } = require("sequelize"); + +module.exports = (sequelize, DataTypes) => { + class Event extends Model { + static associate(models) { + Event.belongsToMany(models.Semester, {through: "EventSemester"}); + Event.belongsToMany(models.Group, {through: "EventGroup"}); + Event.belongsToMany(models.User, {through: "EventTeacher"}); + Event.belongsTo(models.UE); + } + } + Event.init({ + name: { + type: DataTypes.STRING, + allowNull: false + }, + locations: { + type: DataTypes.STRING, + allowNull: false + }, + startDate: { + type: DataTypes.DATE, + allowNull: false + }, + endDate: { + type: DataTypes.DATE, + allowNull: false + } + }, { + sequelize, + modelName: "Event", + }); + return Event; +}; diff --git a/models/group.js b/models/group.js new file mode 100644 index 0000000..d9a2cf7 --- /dev/null +++ b/models/group.js @@ -0,0 +1,23 @@ +"use strict"; + +const { Model } = require("sequelize"); + +module.exports = (sequelize, DataTypes) => { + class Group extends Model { + static associate(models) { + Group.belongsTo(models.Semester); + Group.belongsToMany(models.User, {through: "UserGroup"}); + Group.belongsToMany(models.Event, {through: "EventGroup"}); + } + } + Group.init({ + number: { + type: DataTypes.STRING, + allowNull: false + } + }, { + sequelize, + modelName: "Group", + }); + return Group; +}; diff --git a/models/semester.js b/models/semester.js new file mode 100644 index 0000000..fac1dad --- /dev/null +++ b/models/semester.js @@ -0,0 +1,28 @@ +"use strict"; + +const { Model } = require("sequelize"); + +module.exports = (sequelize, DataTypes) => { + class Semester extends Model { + static associate(models) { + Semester.hasMany(models.Group); + Semester.belongsToMany(models.Event, {through: "EventSemester"}); + } + } + Semester.init({ + year: { + type: DataTypes.INTEGER, + allowNull: false, + unique: "semester" + }, + name : { + type: DataTypes.STRING, + allowNull: false, + unique: "semester" + } + }, { + sequelize, + modelName: "Semester", + }); + return Semester; +}; diff --git a/models/user.js b/models/user.js index 82657b0..d2ccef9 100644 --- a/models/user.js +++ b/models/user.js @@ -8,7 +8,7 @@ const { } = require("sequelize"); module.exports = (sequelize, DataTypes) => { function hash(password, email) { - let cipher = crypto.createCipheriv( + const cipher = crypto.createCipheriv( "aes-256-cbc", privateKey, crypto.createHash("md5").update(email).digest("base64").slice(0, 16) @@ -18,6 +18,9 @@ module.exports = (sequelize, DataTypes) => { class User extends Model { static associate(models) { + User.belongsToMany(models.Group, {through: "UserGroup"}); + User.belongsToMany(models.Event, {through: "EventTeacher"}); + User.belongsToMany(models.UE, {through: "UEUser"}); } checkPassword(password) { diff --git a/public/javascripts/login.js b/public/javascripts/login.js index ece14e1..1f04c1b 100644 --- a/public/javascripts/login.js +++ b/public/javascripts/login.js @@ -11,7 +11,7 @@ document.getElementById("login").addEventListener("submit", e=>{ alert('Format d\'email incorrect.'); } return false; -}) +}); socket.on("login", data=>{ if(data.error){ @@ -19,4 +19,4 @@ socket.on("login", data=>{ }else{ window.location.href = "/"; } -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/public/javascripts/main.js b/public/javascripts/main.js index 1a1fcda..74ddccb 100644 --- a/public/javascripts/main.js +++ b/public/javascripts/main.js @@ -18,4 +18,9 @@ socket.on("logout", data=>{ }else{ window.location.href = "/"; } -}) \ No newline at end of file +}); + + +function profilRedirect(){ + document.location.href="/profil"; +} \ No newline at end of file diff --git a/public/javascripts/marks.js b/public/javascripts/marks.js new file mode 100644 index 0000000..0cd6cae --- /dev/null +++ b/public/javascripts/marks.js @@ -0,0 +1,11 @@ +function setVisible(targetId) { + document.getElementById("notvisible").id = "visible"; +} + +function setNotVisible(targetId) { + document.getElementById(targetId).id = "notvisible"; +} + +function marksformChange(targetId) { + document.getElementById("marksform").style.display = "block"; +} diff --git a/public/javascripts/profil.js b/public/javascripts/profil.js new file mode 100644 index 0000000..3d2b7f8 --- /dev/null +++ b/public/javascripts/profil.js @@ -0,0 +1,21 @@ +let socket = io.connect(); + +document.getElementById("editprofil").addEventListener("submit", e=>{ + e.preventDefault(); + socket.emit("profileEdit", { + "email": mail, + "firstName": document.getElementById("firstname-input").value, + "lastName": document.getElementById("lastname-input").value, + "newPassword": document.getElementById("new-password").value, + "password": document.getElementById("password").value + }); +}); + + +socket.on("profileEdit", data=>{ + if(data.error){ + alert(data.error.message); + }else{ + window.location.href = "/"; + } +}); \ No newline at end of file diff --git a/public/javascripts/register.js b/public/javascripts/register.js index 3b5833a..aad9acf 100644 --- a/public/javascripts/register.js +++ b/public/javascripts/register.js @@ -20,4 +20,4 @@ socket.on("register", data=>{ }else{ window.location.href = "/"; } -}) +}); diff --git a/routes/edt.js b/routes/edt.js index 6e74d6b..753a638 100644 --- a/routes/edt.js +++ b/routes/edt.js @@ -1,8 +1,8 @@ -let express = require("express"); -let router = express.Router(); +const express = require("express"); +const router = express.Router(); router.get("/", (req, res) => { res.render("pages/edt", { title: "L'ETU" }); }); -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/routes/email.js b/routes/email.js index 0597f15..0771a69 100644 --- a/routes/email.js +++ b/routes/email.js @@ -8,7 +8,7 @@ const sessionCheck = require("./utils/sessionCheck"); router.get("/check", async (req, res) => { if (!req.query.token) return error(req, res, "Missing argument", 400); - let user = await models.User.findOne({where: {emailToken: req.query.token}}); + const user = await models.User.findOne({where: {emailToken: req.query.token}}); if (user) { user.emailVerified = true; if (user.email.endsWith("@etu.univ-lyon1.fr")) @@ -25,7 +25,7 @@ router.get("/forget", sessionCheck(-1), async (req, res) => { if (!req.query.token) res.render("forget", {title: "L'ETU"}); else { - let user = await models.User.findOne({where: {passwordToken: data.token}}); + const user = await models.User.findOne({where: {passwordToken: data.token}}); if (!user) return error(req, res, "Invalid token", 400); else if (user.passwordTokenDate && ((new Date().getTime() - user.passwordTokenDate.getTime()) / 1000 > 3600)) diff --git a/routes/home.js b/routes/home.js index 10276d9..0e85584 100644 --- a/routes/home.js +++ b/routes/home.js @@ -1,9 +1,9 @@ -let express = require("express"); -let router = express.Router(); +const express = require("express"); +const router = express.Router(); /* GET home page. */ router.get("/", (req, res) => { res.render("pages/home", { title: "L'ETU" }); }); -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/routes/index.js b/routes/index.js index ced825d..fee5fcb 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,5 +1,5 @@ -let express = require("express"); -let router = express.Router(); +const express = require("express"); +const router = express.Router(); const sessionCheck = require("./utils/sessionCheck"); router.get("/", sessionCheck(1), (req, res) => { diff --git a/routes/login.js b/routes/login.js index 0a899f0..1f1aef2 100644 --- a/routes/login.js +++ b/routes/login.js @@ -1,5 +1,5 @@ -let express = require("express"); -let router = express.Router(); +const express = require("express"); +const router = express.Router(); const sessionCheck = require("./utils/sessionCheck"); router.get("/",sessionCheck(-1), (req, res) => { diff --git a/routes/marks.js b/routes/marks.js index c4d5cb9..db46ce0 100644 --- a/routes/marks.js +++ b/routes/marks.js @@ -1,5 +1,5 @@ -let express = require("express"); -let router = express.Router(); +const express = require("express"); +const router = express.Router(); router.get("/", (req, res) => { res.render("pages/marks", { title: "L'ETU" }); diff --git a/routes/profil.js b/routes/profil.js index 529ff2b..82c23b8 100644 --- a/routes/profil.js +++ b/routes/profil.js @@ -1,5 +1,5 @@ -let express = require("express"); -let router = express.Router(); +const express = require("express"); +const router = express.Router(); router.get("/", (req, res) => { res.render("pages/profil", { title: "L'ETU" }); diff --git a/routes/register.js b/routes/register.js index 9e99f1c..a7410dd 100644 --- a/routes/register.js +++ b/routes/register.js @@ -1,5 +1,5 @@ -let express = require("express"); -let router = express.Router(); +const express = require("express"); +const router = express.Router(); const sessionCheck = require("./utils/sessionCheck"); router.get("/",sessionCheck(-1), (req, res) => { diff --git a/routes/utils/sessionCheck.js b/routes/utils/sessionCheck.js index 5a54bc5..5c66215 100644 --- a/routes/utils/sessionCheck.js +++ b/routes/utils/sessionCheck.js @@ -1,4 +1,4 @@ -let error = require("./error"); +const error = require("./error"); function sessionCheck(permission) { return (req, res, next) => { diff --git a/routes/viescol.js b/routes/viescol.js index bc0c341..e846717 100644 --- a/routes/viescol.js +++ b/routes/viescol.js @@ -1,8 +1,8 @@ -let express = require("express"); -let router = express.Router(); +const express = require("express"); +const router = express.Router(); router.get("/", (req, res) => { res.render("pages/viescol", { title: "L'ETU" }); }); -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/sass/style.sass b/sass/style.sass index ddf66ff..eab44b6 100644 --- a/sass/style.sass +++ b/sass/style.sass @@ -512,4 +512,10 @@ div#visible + div font-size: 20px #hamburger - position: fixed \ No newline at end of file + position: fixed + +#notvisible + display: none + +#marksform + display: none diff --git a/sockets/email/checkResend.js b/sockets/email/checkResend.js index 07d85c5..d0de62a 100644 --- a/sockets/email/checkResend.js +++ b/sockets/email/checkResend.js @@ -11,4 +11,4 @@ module.exports = socket => { else await emailCheck(socket, user, null); } -} +}; diff --git a/sockets/email/forgotPassword.js b/sockets/email/forgotPassword.js index d415c15..b13bccc 100644 --- a/sockets/email/forgotPassword.js +++ b/sockets/email/forgotPassword.js @@ -10,4 +10,4 @@ module.exports = socket => { else await emailPassword(socket, user, null); } -} +}; diff --git a/sockets/email/setPassword.js b/sockets/email/setPassword.js index 809de18..7c3399a 100644 --- a/sockets/email/setPassword.js +++ b/sockets/email/setPassword.js @@ -5,7 +5,7 @@ module.exports = socket => { return async (data) => { let user = await models.User.findOne({where: {passwordToken: data.token}}); if (!user) - socket.emit("setPassword", {error: {message: "invalid_token"}}) + socket.emit("setPassword", {error: {message: "invalid_token"}}); else if (user.passwordTokenDate && ((new Date().getTime() - user.passwordTokenDate.getTime()) / 1000 > 3600)) socket.emit("setPassword", {error: {message: "expired_token"}}); else { @@ -16,4 +16,4 @@ module.exports = socket => { socket.emit("setPassword", true); } } -} +}; diff --git a/sockets/get/agendaGet.js b/sockets/get/agendaGet.js new file mode 100644 index 0000000..c27a05c --- /dev/null +++ b/sockets/get/agendaGet.js @@ -0,0 +1,39 @@ +const models = require("../../models"); + +module.exports = socket => { + return async (data) => { + let startDate = data.startDate ? data.startDate : new Date(), endDate = data.endDate ? data.endDate : new Date(); + let options = {where: {startDate: startDate, endDate: endDate}, include: []}; + if (data.semesters) { + for (let semester of data.semesters) { + let s = await models.Semester.findByPk(semester); + if (!s) { + socket.emit("agendaGet", {error: {message: "semester_not_found"}}); + return + } else + options.include.push({model: models.Semester, where: {id: s.id}, require: true}); + } + } + if (data.groups) { + for (let group of data.groups) { + let g = await models.Group.findByPk(group); + if (!g) { + socket.emit("agendaGet", {error: {message: "group_not_found"}}); + return + } else + options.include.push({model: models.Group, where: {id: g.id}, require: true}); + } + } + if (data.teachers) { + for (let teacher of data.teachers) { + let t = await models.User.findByPk(teacher); + if (!t) { + socket.emit("agendaGet", {error: {message: "teacher_not_found"}}); + return + } else + options.include.push({model: models.User, where: {id: t.email}, require: true}); + } + } + socket.emit("agendaGet", await models.Event.findAll(options)); + } +}; diff --git a/sockets/get/groupGet.js b/sockets/get/groupGet.js new file mode 100644 index 0000000..12f16ba --- /dev/null +++ b/sockets/get/groupGet.js @@ -0,0 +1,21 @@ +const models = require("../../models"); + +module.exports = socket => { + return async (data) => { + let options = {where: {}, include: [{model: models.Semester, require: true}]}; + if (data.number) + options.where.number = data.number; + if (data.semester) { + let s = await models.Semester.findByPk(data.semester); + if (!s) { + socket.emit("groupGet", {error: {message: "semester_not_found"}}); + return + } + options.include[0].where = {id: s.id}; + } + if (data.users) + options.include.push({model: models.User, require: true}); + + socket.emit("groupGet", await models.Group.findAll(options)); + } +}; diff --git a/sockets/get/semesterGet.js b/sockets/get/semesterGet.js new file mode 100644 index 0000000..a7ef457 --- /dev/null +++ b/sockets/get/semesterGet.js @@ -0,0 +1,15 @@ +const models = require("../../models"); + +module.exports = socket => { + return async (data) => { + let options = {where: {}, include: []}; + if (data.name) + options.where.name = data.name; + if (data.year) + options.where.year = data.year; + if (data.groups) + options.include.push({model: models.Group, require: true}); + + socket.emit("semesterGet", await models.Semester.findAll(options)); + } +}; diff --git a/sockets/get/userGet.js b/sockets/get/userGet.js new file mode 100644 index 0000000..0b905c5 --- /dev/null +++ b/sockets/get/userGet.js @@ -0,0 +1,17 @@ +const models = require("../../models"); + +module.exports = socket => { + return async (data) => { + let options = {where: {}}; + if (data.email) + options.where.email = data.email; + if (data.firstName && data.lastName) { + options.where.firstName = data.firstName; + options.where.lastName = data.lastName; + } + if (data.permissions) + options.where.permissions = data.permissions; + + socket.emit("userGet", await models.User.findAll(options)); + } +}; diff --git a/sockets/index.js b/sockets/index.js index 604338a..b420000 100644 --- a/sockets/index.js +++ b/sockets/index.js @@ -10,6 +10,7 @@ module.exports = socket => { } else { socket.on("profileEdit", require("./profile/edit")(socket)); socket.on("logout", require("./logout")(socket)); + socket.on("agendaGet", require("./get/agendaGet")(socket)); } socket.emit("connected"); -} +}; diff --git a/sockets/login.js b/sockets/login.js index e1a7341..6d0b89a 100644 --- a/sockets/login.js +++ b/sockets/login.js @@ -15,4 +15,4 @@ module.exports = socket => { socket.emit("login", user) } } -} +}; diff --git a/sockets/logout.js b/sockets/logout.js index 2244722..6e7be2f 100644 --- a/sockets/logout.js +++ b/sockets/logout.js @@ -7,4 +7,4 @@ module.exports = socket => { socket.emit("logout", {error: { message: "not_logged_in"}}); } } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/sockets/profile/edit.js b/sockets/profile/edit.js index 2fcaff5..1b93aec 100644 --- a/sockets/profile/edit.js +++ b/sockets/profile/edit.js @@ -6,17 +6,18 @@ module.exports = socket => { if (!user) socket.emit("profileEdit", {error: {message: "not_found"}}); else if (!user.checkPassword(data.oldPassword)) - socket.emit("profileEdit", {error: {message: "invalid_password"}}) + socket.emit("profileEdit", {error: {message: "invalid_password"}}); else { if (data.firstName !== user.firstName) user.firstName = data.firstName; if (data.lastName !== user.lastName) user.lastName = data.lastName; + user.newPassword = data.newPassword; if (data.password && !user.checkPassword(data.password)) - user.passwordHash = data.password + user.passwordHash = data.password; socket.request.session.user = user; socket.request.session.save(); socket.emit("profileEdit", user) } } -} +}; diff --git a/sockets/register.js b/sockets/register.js index 740b2c8..eaa8381 100644 --- a/sockets/register.js +++ b/sockets/register.js @@ -18,4 +18,4 @@ module.exports = socket => { await emailCheck(socket, user, null); } } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/sockets/utils/emailPassword.js b/sockets/utils/emailPassword.js index 3bc7132..281499d 100644 --- a/sockets/utils/emailPassword.js +++ b/sockets/utils/emailPassword.js @@ -16,7 +16,7 @@ module.exports = async (socket, user, callBack) => { subject: "forgot password" }), async (err, message) => { if (err) - socket.emit("forgotPassword", {error: {message: "fail_send_mail"}}) + socket.emit("forgotPassword", {error: {message: "fail_send_mail"}}); else { user.passwordToken = token; user.passwordTokenDate = new Date(); diff --git a/test/test-pages.js b/test/test-pages.js index f4afba0..c75dee1 100644 --- a/test/test-pages.js +++ b/test/test-pages.js @@ -20,7 +20,7 @@ async function clean() { before(async () => { [app, models] = await setup(); -}) +}); it("Main page content", async () => { await request(app) diff --git a/views/pages/marks.pug b/views/pages/marks.pug index d6cc47a..6baa24c 100644 --- a/views/pages/marks.pug +++ b/views/pages/marks.pug @@ -2,7 +2,7 @@ extends ../template/navbar block content if student === true - div(class="marksdetails" id="visibl") + div(class="marksdetails" id="notvisible" onclick="setNotVisible(this.getAttribute('id'))") table tr th(colspan="2") Details @@ -22,24 +22,24 @@ block content th(colspan="2") Maths tbody tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 @@ -50,17 +50,17 @@ block content th(colspan="2") TP SE tbody tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 @@ -71,17 +71,17 @@ block content th(colspan="2") PHP tbody tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 @@ -92,17 +92,17 @@ block content th(colspan="2") Anglais tbody tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 tr - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 1 p 18/20 - td + td(onclick="setVisible(this.getAttribute('id'))") p DS 2 p 16/20 @@ -111,11 +111,11 @@ block content div(class="col s12 m10 offset-m1 marksgroup") h3 Select a group div(id="flexgroup") - p G1S1 - p G2S2 - p G3S3 + p(onclick="marksformChange(this.getAttribute('id'))") G1S1 + p(onclick="marksformChange(this.getAttribute('id'))") G2S2 + p(onclick="marksformChange(this.getAttribute('id'))") G3S3 - form + form(id="marksform") table(id="markstable") thead tr @@ -185,4 +185,6 @@ block content input(type="number" value="16") td input(type="number") - input(id="marksubmit" type="submit" value="Enregistrer") \ No newline at end of file + input(id="marksubmit" type="submit" value="Enregistrer") + + script(src="/javascripts/marks.js") \ No newline at end of file