83 lines
5 KiB
JavaScript
83 lines
5 KiB
JavaScript
const crypto = require("crypto");
|
|
const qs = require("qs");
|
|
const databaseHandler = require("../../lib/database-handler");
|
|
const input_validate = require("../../lib/input_validate");
|
|
|
|
module.exports = {
|
|
route: (routeObj) => {
|
|
routeObj.get((req, res) => {
|
|
const validation_result = input_validate.validate_exists(req.query, ["response_type", "client_id", "redirect_uri"]);
|
|
if (validation_result !== true) {
|
|
res.status(422);
|
|
res.send(`<html><body>Someone done goof'ed with your oauth request.<br />${validation_result.error}</body></html>`);
|
|
res.end();
|
|
return;
|
|
}
|
|
if (!req.cookies || !req.cookies.auth) {
|
|
const new_redirect_url = new URL("https://example.com");
|
|
new_redirect_url.host = req.headers.host;
|
|
new_redirect_url.pathname = req.path;
|
|
new_redirect_url.search = qs.stringify(req.query);
|
|
const redirecting_to = new URL("https://example.com");
|
|
redirecting_to.host = req.headers.host;
|
|
redirecting_to.pathname = "/login";
|
|
redirecting_to.searchParams.set("redirect_to", new_redirect_url.toString());
|
|
res.status(302);
|
|
res.redirect(redirecting_to.toString());
|
|
res.end();
|
|
} else {
|
|
const cookie_db = databaseHandler.checkAuthCookie(req.cookies.auth);
|
|
if (cookie_db != null && !cookie_db.revoked && (cookie_db.created_at + 86400) > Math.floor(Date.now() / 1000)) {
|
|
const new_cookie_value = crypto.randomBytes(32).toString("base64");
|
|
databaseHandler.revokeAuthCookie(req.cookies.auth);
|
|
databaseHandler.createAuthCookie(new_cookie_value, Math.floor(Date.now() / 1000), cookie_db.user_id);
|
|
const application_obj = databaseHandler.application[req.query.client_id];
|
|
let scope = "read";
|
|
if (req.query.scope) {
|
|
scope = req.query.scope;
|
|
}
|
|
if (!input_validate.validate_appropriate_scopes(application_obj.scopes, scope)) {
|
|
res.status(422);
|
|
res.cookie("auth", new_cookie_value);
|
|
// TODO: XSS
|
|
res.send(`<html><body>Error: invalid scopes requested. Contact the author of ${application_obj.client_name} to correct their scope request.</body></html>`);
|
|
res.end();
|
|
return;
|
|
}
|
|
res.status(200);
|
|
res.cookie("auth", new_cookie_value);
|
|
const approve_url = new URL("https://example.com");
|
|
approve_url.host = req.headers.host;
|
|
approve_url.pathname = "/oauth/authorize/yes";
|
|
approve_url.searchParams.set("response_type", req.query.response_type);
|
|
approve_url.searchParams.set("client_id", req.query.client_id);
|
|
approve_url.searchParams.set("redirect_uri", req.query.redirect_uri);
|
|
approve_url.searchParams.set("scope", scope);
|
|
const approve_csrf = crypto.randomBytes(32).toString("base64");
|
|
approve_url.searchParams.set("csrf_token", approve_csrf);
|
|
const deny_url = new URL(approve_url);
|
|
deny_url.pathname = "/oauth/authorize/no";
|
|
const deny_csrf = crypto.randomBytes(32).toString("base64");
|
|
deny_url.searchParams.set("csrf_token", deny_csrf);
|
|
const approve_csrf_id = databaseHandler.createCsrfToken(approve_url.toString(), Math.floor(Date.now() / 1000), new_cookie_value);
|
|
const deny_csrf_id = databaseHandler.createCsrfToken(deny_url.toString(), Math.floor(Date.now() / 1000), new_cookie_value);
|
|
databaseHandler.createCsrfTokenAssociation(approve_csrf_id, deny_csrf_id);
|
|
res.send(`<html><body>The ${application_obj.client_name} application has requested the following scopes:<br /><ul><li>${scope.split(/(\s|\+)+/).join("</li><li>")}</li></ul><br /><a href="${approve_url.toString()}" >Approve</a><br /><a href="${deny_url.toString()}" >Deny</a></body></html>`);
|
|
res.end();
|
|
return;
|
|
}
|
|
const new_redirect_url = new URL("https://example.com");
|
|
new_redirect_url.host = req.headers.host;
|
|
new_redirect_url.pathname = req.path;
|
|
new_redirect_url.search = qs.stringify(req.query);
|
|
const redirecting_to = new URL("https://example.com");
|
|
redirecting_to.host = req.headers.host;
|
|
redirecting_to.pathname = "/login";
|
|
redirecting_to.searchParams.set("redirect_to", new_redirect_url.toString());
|
|
res.status(302);
|
|
res.redirect(redirecting_to.toString());
|
|
res.end();
|
|
}
|
|
});
|
|
},
|
|
};
|