const fastify = require('fastify')({ logger: true }) const fs = require('fs'); const path = require('path') var LdapAuth = require('ldapauth-fork'); var prankPath = "prankdata.txt"; if (!fs.existsSync(prankPath)) { fs.writeFileSync(prankPath, "{}"); } let PrankData = JSON.parse(fs.readFileSync(prankPath)); let AdminUsersUid = ["asyncnomi", "johan", "enthalpine", "fas", "arina", "billy", "remi", "pierre", "", "", "", ""]; let UsersToken = {}; let TokenDurationSecond = 3600; var ldapConf = JSON.parse(fs.readFileSync("ldap-conf.json")); var LDAP = new LdapAuth({ url: 'ldap://10.5.0.44', bindDN: 'cn='+ ldapConf.bindUser +',ou=service-users,dc=ldap,dc=rezo-rm,dc=fr', bindCredentials: ldapConf.bindPassword, searchBase: 'dc=ldap,dc=rezo-rm,dc=fr', searchFilter: '(uid={{username}})', reconnect: true, }); LDAP.on('error', function (err) { console.error('LdapAuth: ', err); }); ldapConf = null; fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function(req, body, done) { try { var json = JSON.parse(body) done(null, json) } catch (err) { err.statusCode = 400 done(err, undefined) } }) fastify.register(require('@fastify/static'), { root: path.join(__dirname, 'static'), decorateReply: false }) fastify.get('/', async (request, reply) => { reply.redirect('/index.html') }) fastify.post('/login', async (request, reply) => { let content = request.body; if (content.hasOwnProperty("user") && content.hasOwnProperty("password")) { let res = await authenticate(content.user, content.password); if (res.authState) { let now = new Date(); UsersToken[res.authUser.uid] = { token: makeid(64), expire: now.setSeconds(now.getSeconds() + TokenDurationSecond) } return { success: true, user: { uid: res.authUser.uid, givenName: res.authUser.givenName }, token: UsersToken[res.authUser.uid].token } } else { return { success: false, why: "Wrong username or password" } } } else { return { success: false, why: "The username or password is missing" } } }) fastify.post('/addPrank', async (request, reply) => { let content = request.body; let auth = checkAuthetification(content); if (auth.success) { if ("type" in content) { let note = ("note" in content) ? content.note : "N/A"; switch (content.type) { case "crêpe": if ("where" in content && "amount" in content) { let prankUid = makeid(16); PrankData[prankUid] = { creator: content.uid, type: content.type, where: content.where, amount: content.amount, note: content.note, state: "Pending", manageBy: null } saveData(); return { sucess: true, uid: prankUid, newPrank: PrankData[prankUid] } } else { return { success: false, why: "Missing amount or where" } } break; case "kidnap": if ("targetUid" in content && "when" in content) { let prankUid = makeid(16); PrankData[prankUid] = { creator: content.uid, type: content.type, targetUid: content.targetUid, when: content.when, note: content.note, state: "Pending", manageBy: null } saveData(); return { sucess: true, uid: prankUid, newPrank: PrankData[prankUid] } } else { return { success: false, why: "Missing amount or where" } } break; default: return { success: false, why: "Unknow type" } } } else { return { success: false, why: "Missing type" } } } else { return auth } }) fastify.post('/delPrank', async (request, reply) => { let content = request.body; let auth = checkAuthetification(content); if (auth.success) { let prankExists = checkPrank(content) if (prankExists.success) { if (PrankData[content.prankUid].creator === content.uid) { delete PrankData[content.prankUid]; return { success: true, } } else { return { success: false, why: "Not allowed" } } } else { return prankExists } } else { return auth } }) fastify.post('/acceptPrank', async (request, reply) => { let content = request.body; let prankExists = checkManagePrank(content) if (prankExists.success) { PrankData[content.prankUid].state = "Accepted"; PrankData[content.prankUid].manageBy = content.uid; return { success: true, } } else { return prankExists } }) fastify.post('/donePrank', async (request, reply) => { let content = request.body; let prankExists = checkManagePrank(content) if (prankExists.success) { if (PrankData[content.prankUid].manageBy == content.uid) { PrankData[content.prankUid].state = "Done"; return { success: true, } } else { return { success: false, why: "Not allowed" } } } else { return prankExists } }) fastify.post('/refusePrank', async (request, reply) => { let content = request.body; let prankExists = checkManagePrank(content) if (prankExists.success) { PrankData[content.prankUid].state = "Refused"; PrankData[content.prankUid].manageBy = content.uid; return { success: true, } } else { return prankExists } }) fastify.post('/getPrank', async (request, reply) => { let content = request.body; let auth = checkAuthetification(content); if (auth.success) { if (AdminUsersUid.includes(content.uid)) { return { sucess: true, prankData: PrankData } } else { return { success: false, why: "Not Allowed" } } } else { return auth } }) function saveData() { fs.writeFileSync(prankPath, JSON.stringify(PrankData)); } function authenticate(user, pwd) { return new Promise((resolve, reject) => { LDAP.authenticate(user, pwd, function(err, user) { if (user && err == null) { resolve({ authState: true, authUser: user }); } else { resolve({ authState: false, authUser: null }); } }); }) } function checkAuthetification(content) { if (content.hasOwnProperty("uid") && content.hasOwnProperty("token")) { if (UsersToken.hasOwnProperty(content.uid) && UsersToken[content.uid].token === content.token) { if (UsersToken[content.uid].expire > new Date()) { return { success: true } } else { delete UsersToken[content.uid]; return { success: false, why: "Token expired" } } } else { return { success: false, why: "Not authenticated" } } } } function checkPrank(content) { if ("prankUid" in content) { if (content.prankUid in PrankData) { return { success: true, } } else { return { success: false, why: "Unknow prankUid" } } } else { return { success: false, why: "Missing prankUid" } } } function checkManagePrank(content) { let auth = checkAuthetification(content); if (auth.success) { if (AdminUsersUid.includes(content.uid)) { let prankExists = checkPrank(content) if (prankExists.success) { return { success: true } } else { return prankExists } } else { return { success: false, why: "Not Allowed" } } } else { return auth } } function makeid(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = characters.length; for ( var i = 0; i < length; i++ ) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } const start = async () => { try { await fastify.listen({ port: 3000 , host: '127.0.0.1',}) } catch (err) { fastify.log.error(err) LDAP.close(function(err) { console.log(err); }) process.exit(1) } } start()