diff --git a/src/index.ts b/src/index.ts index 46bc8db..66a7866 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,11 +22,6 @@ declare global { namespace Express { export interface User extends IUser { _id: mongoose.Types.ObjectId; - // pass: string; - // uname: string; - // admin?: number; - // locked?: boolean; - // room?: string } } } @@ -34,7 +29,7 @@ declare global { //#region express initialization var app = express(); app.use(bodyParser.json()) -app.use(bodyParser.urlencoded({extended: true})) +app.use(bodyParser.urlencoded({ extended: true })) app.use(cors({ origin: ["http://localhost:4200", `https://${process.env.DOMAIN}`,], credentials: true @@ -44,7 +39,7 @@ app.use(session({ rolling: true, secret: process.env.SECRET, saveUninitialized: false, - store: MongoStore.create({mongoUrl: connectionString, dbName: "ipwa", collectionName: "sessions", touchAfter: 60, autoRemove: 'disabled'}), + store: MongoStore.create({ mongoUrl: connectionString, dbName: "ipwa", collectionName: "sessions", touchAfter: 60, autoRemove: 'disabled' }), cookie: { maxAge: 1209600000, } @@ -53,32 +48,32 @@ app.use(passport.session()) //#endregion //#region Passport strategies initialization -passport.use("normal",new LocalStrategy(async function verify(uname,pass,done) { - let query = await User.findOne({uname: uname.toLowerCase()}) +passport.use("normal", new LocalStrategy(async function verify(uname, pass, done) { + let query = await User.findOne({ uname: uname.toLowerCase() }) if (query) { - if (query.locked == true) return done({type: "locked", message: "Twoje konto jest zablokowane. Skontaktuj się z administratorem."}, false) + if (query.locked == true) return done({ type: "locked", message: "Twoje konto jest zablokowane. Skontaktuj się z administratorem." }, false) var timeout = security.check(query._id) if (timeout) { timeout = Math.ceil(timeout / 1000 / 60) - return done({type: "timeout", message: `Zbyt wiele nieudanych prób logowania. Odczekaj ${timeout} minut lub skontaktuj się z administratorem.`}, false) + return done({ type: "timeout", message: `Zbyt wiele nieudanych prób logowania. Odczekaj ${timeout} minut lub skontaktuj się z administratorem.` }, false) } if (await bcrypt.compare(pass, query.pass)) { return done(null, query) } else { security.addAttempt(query._id) - done({type: "unf"}, false) + done({ type: "unf" }, false) } } else { - done({type: "unf"}, false) + done({ type: "unf" }, false) } })) //#endregion -passport.serializeUser(function(user, done) { +passport.serializeUser(function (user, done) { done(null, user._id); }); -passport.deserializeUser(async function(id, done) { +passport.deserializeUser(async function (id, done) { let query = await User.findById(id) if (query) { done(null, query) @@ -89,6 +84,7 @@ passport.deserializeUser(async function(id, done) { var server = app.listen(8080, async () => { await mongoose.connect(connectionString); + await dataMigration() if (process.send) process.send("ready") }) @@ -97,4 +93,24 @@ app.use('/', routes) process.on('SIGINT', () => { server.close() mongoose.disconnect().then(() => process.exit(0), () => process.exit(1)) -}) \ No newline at end of file +}) + +async function dataMigration() { + //#region User + var users = await User.find({ admin: { $type: "int" } }).lean() + users.forEach(async v => { + var oldFlags = v.admin as unknown as number + var newFlags: string[] | undefined = [] + if ((oldFlags & 1) == 1) newFlags.push("news") + if ((oldFlags & 2) == 2) newFlags.push("menu") + if ((oldFlags & 4) == 4) newFlags.push("notif") + if ((oldFlags & 8) == 8) newFlags.push("groups") + if ((oldFlags & 16) == 16) newFlags.push("accs") + if ((oldFlags & 32) == 32) newFlags.push("super") + if ((oldFlags & 64) == 64) newFlags.push("keys") + if ((oldFlags & 128) == 128) newFlags.push("grades") + if (newFlags.length == 0) newFlags = undefined + await User.findByIdAndUpdate(v._id, { $set: { admin: newFlags } }) + }) + //#endregion +} diff --git a/src/routes/api/admin/accs.ts b/src/routes/api/admin/accs.ts index 4fa7ad2..7ed6126 100644 --- a/src/routes/api/admin/accs.ts +++ b/src/routes/api/admin/accs.ts @@ -44,15 +44,15 @@ accsRouter.put('/:id', async (req, res)=> { res.status(404).send("User not found") return } - if (req.body.flags) { + if (req.body.admin) { if (adminCond(req.user.admin, Perms.Superadmin)) { if (adminCond(user.admin, Perms.Superadmin)) { res.status(400).send("Cannot edit other superadmins") } else { - if (adminCond(req.body.flags, Perms.Superadmin)) { + if (adminCond(req.body.admin, Perms.Superadmin)) { res.status(400).send("Cannot set superadmin") } else { - await user.set({uname: req.body.uname, room: req.body.room, admin: req.body.flags, fname: req.body.fname, surname: req.body.surname, groups: req.body.groups}).save() + await user.set({uname: req.body.uname, room: req.body.room, admin: req.body.admin, fname: req.body.fname, surname: req.body.surname, groups: req.body.groups}).save() res.send({status: 200}) } } diff --git a/src/schemas/User.ts b/src/schemas/User.ts index ecc482f..5bf880d 100644 --- a/src/schemas/User.ts +++ b/src/schemas/User.ts @@ -1,10 +1,11 @@ +import { Perms } from "@/utility"; import mongoose, { Types, Schema } from "mongoose" export interface IUser { uname: string; pass: string; room?: string; - admin?: number; + admin?: Perms[]; locked?: boolean; fname?: string; surname?: string; @@ -17,7 +18,7 @@ const userSchema = new Schema({ uname: {type: String, required: true}, pass: {type: String, required: true, default: "$2y$10$wxDhf.XiXkmdKrFqYUEa0.F4Bf.pDykZaMmgjvyLyeRP3E/Xy0hbC"}, room: {type: String, default: ""}, - admin: Number, + admin: [{type: String}], locked: {type: Boolean, default: false}, fname: {type: String, default: ""}, surname: {type: String, default: ""}, diff --git a/src/utility.ts b/src/utility.ts index 716e645..f378848 100644 --- a/src/utility.ts +++ b/src/utility.ts @@ -15,14 +15,14 @@ var isadmin = (req: Request, res: Response, next: NextFunction) => { } enum Perms { - News = 1, - Menu = 2, - Notif = 4, - Groups = 8, - Accs = 16, - Superadmin = 32, - Key = 64, - Clean = 128, + News = "news", + Menu = "menu", + Notif = "notif", + Groups = "groups", + Accs = "accs", + Superadmin = "super", + Key = "keys", + Clean = "grades", } var adminPerm = (perm: Perms) => { @@ -34,8 +34,8 @@ var adminPerm = (perm: Perms) => { } } -var adminCond = (adminInt = 0, perm: Perms) => { - return (adminInt & perm) == perm +var adminCond = (perms: Perms[], perm: Perms) => { + return perms.includes(perm) } export function project(obj: T | any, projection?: (keyof T)[] | { [key in keyof T]: any}): Partial {