import fs from "fs"; import { SHA256 } from "../../extra_modules/SHA.js"; import { unsign } from "../../extra_modules/unsign.js"; const config = JSON.parse(fs.readFileSync("server_config.json")); const HASHES_DB = config.cookies.server_hashes; const HASHES_COOKIE = config.cookies.client_hashes; const HASHES_DIFF = HASHES_DB - HASHES_COOKIE; export const setup = function (router, con, server) { router.use("/*path", (req, res, next) => { res.set("Access-Control-Allow-Origin", "*"); //we'll allow it for now let unsigned; req.body = req.body || {}; if (typeof req.get("ipost-auth-token") === "string") { try { req.body.auth = JSON.parse(req.get("ipost-auth-token")) } catch (err) { console.log("error parsing header", err) } } if (req.body.auth !== undefined && req.originalUrl !== "/redeemauthcode") { if (typeof req.body.auth === "string") { try { req.body.auth = JSON.parse(req.body.auth) } catch (err) { console.log("error parsing", err) } } else if ( typeof req.body.auth !== "object" || typeof req.body.auth.secret !== "string" || typeof req.body.auth.appid !== "number" || typeof req.body.auth.auth_token !== "string" || req.body.auth.secret.length !== 200 || req.body.auth.auth_token.length !== 200 || Buffer.from(req.body.auth.secret, "base64").length !== 150 ) { res.status(420).send("invalid authentication object") return; } else { //secret : string(200 chars) //appid : number //auth_token: string(200 chars) let sql = "select User_ID,User_Name,User_Bio,User_Avatar,User_Settings from ipost.auth_tokens inner join ipost.application on auth_token_isfrom_application_id=application_id inner join ipost.users on auth_token_u_id=User_ID where auth_token=? and application_secret=? and application_id=?" con.query(sql, [SHA256(req.body.auth.auth_token, req.body.auth.appid, HASHES_DB), SHA256(req.body.auth.secret, req.body.auth.appid, HASHES_DB), req.body.auth.appid], (err, result) => { if (err) throw err; if (result.length !== 1) { res.status(420).send("invalid authentication object (or server error?)") return; } res.locals.userid = result[0].User_ID; res.locals.username = result[0].User_Name; res.locals.bio = result[0].User_Bio || ""; res.locals.avatar = result[0].User_Avatar || ""; res.locals.settings = result[0].User_Settings || {}; res.locals.isbot = true; //only apps/bots use auth tokens next() }) return; } } else { if (!req.cookies.AUTH_COOKIE) { next() return } unsigned = unsign(req.cookies.AUTH_COOKIE, req, res); if (!unsigned) { next() return } } let sql = `select User_ID,User_Name,User_Bio,User_Avatar,User_Settings from ipost.users where User_Name=? and User_PW=?;`; let values = unsigned.split(" "); values[1] = SHA256(values[1], values[0], HASHES_DIFF); res.locals.bio = ""; res.locals.avatar = ""; res.locals.settings = {}; con.query(sql, values, function (err, result) { if (err) throw err; if (result[0] && result[0].User_Name && result[0].User_Name === values[0]) { res.locals.userid = result[0].User_ID; res.locals.username = result[0].User_Name; res.locals.bio = result[0].User_Bio || ""; res.locals.avatar = result[0].User_Avatar || ""; res.locals.settings = result[0].User_Settings || {}; } next() }); }); router.use("/api/*path", (req, res, next) => { res.set("Access-Control-Allow-Origin", "*"); //we'll allow it for now if (config["allow_getotheruser_without_cookie"] && req.originalUrl.split("\?")[0] === "/api/getotheruser") { next(); return; } if (!server.increaseAPICall(req, res)) return; if (res.locals.username !== undefined) { next(); } else { res.status(402); res.json({ "error": "you cannot access the api without being logged in" }); } /* #swagger.security = [{ "appTokenAuthHeader": [] }] */ }); }; export default { setup };