summaryrefslogtreecommitdiff
path: root/src/routers/vault/middlewares/identity.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/routers/vault/middlewares/identity.js')
-rw-r--r--src/routers/vault/middlewares/identity.js116
1 files changed, 24 insertions, 92 deletions
diff --git a/src/routers/vault/middlewares/identity.js b/src/routers/vault/middlewares/identity.js
index 158e5df..f65d757 100644
--- a/src/routers/vault/middlewares/identity.js
+++ b/src/routers/vault/middlewares/identity.js
@@ -2,6 +2,7 @@
const uuidv4 = require("uuid/v4");
const nodemailer = require("nodemailer");
const Claim = require("../utils/claim.js");
+const validate = require("../utils/validate.js");
let transporter = nodemailer.createTransport({
sendmail: true,
@@ -10,38 +11,11 @@ let transporter = nodemailer.createTransport({
});
const get_identities = async (req, res, next) => {
- const token = String(req.get("X-VAULT-SESSION") || "");
-
- if (!token.match(/^[a-zA-Z0-9-_]{6,128}$/)) {
- res.status(400).json({
- status: "error",
- error: "missing session key",
- });
- req.app.locals.logger.warn(`Vault.identity: blocked an attempt to bypass authentication [${req.ip}]`);
- req.app.locals.cooldown(req, 3e5);
- return;
- }
-
- const session = req.app.locals.session.get(token);
-
- if (session === null || session === undefined) {
- res.status(410).json({
- status: "error",
- error: "session expired",
- });
- req.app.locals.cooldown(req, 5e3);
- return;
- }
+ let session;
- if (session.authenticated !== true) {
- res.status(401).json({
- status: "error",
- error: "not authenticated",
- });
- req.app.locals.logger.warn(`Vault.identity: blocked an attempt to bypass authentication [${req.ip}]`);
- req.app.locals.cooldown(req, 3e5);
- return;
- }
+ try {
+ [, session] = validate.get_session(req, res);
+ } catch { return } // already handled
if (session.identities.length === 0) {
console.info(`Vault.identity: fetching identities <${session.vault}@vault> [${req.ip}]`);
@@ -69,19 +43,19 @@ const get_identities = async (req, res, next) => {
const add_identity = async (req, res, next) => {
const token = String(req.get("X-VAULT-SESSION") || "");
- const validate = String(req.get("X-VAULT-TOKEN") || "");
+ const secret = String(req.get("X-VAULT-TOKEN") || "");
- if (token === "" && validate !== "") {
- if (!validate.match(/^[a-zA-Z0-9-_]{6,128}$/)) {
+ if (token === "" && secret !== "") {
+ if (!secret.match(validate.regexes.uuid)) {
res.status(400).json({
status: "error",
- error: "missing token",
+ error: "missing secret",
});
req.app.locals.cooldown(req, 5e3);
return;
}
- const ident = req.app.locals.identity_pending.get(validate);
+ const ident = req.app.locals.identity_pending.get(secret);
if (ident === null || ident === undefined) {
res.status(410).json({
@@ -128,7 +102,7 @@ const add_identity = async (req, res, next) => {
}
}
- req.app.locals.identity_pending.delete(validate);
+ req.app.locals.identity_pending.delete(secret);
if (session !== null) {
console.info(`Vault.identity: added a new identity <${session.vault}@vault> [${req.ip}]`);
@@ -145,50 +119,19 @@ const add_identity = async (req, res, next) => {
// request to add
- if (!token.match(/^[a-zA-Z0-9-_]{6,128}$/)) {
- res.status(400).json({
- status: "error",
- error: "missing session key",
- });
- req.app.locals.logger.warn(`Vault.identity: blocked an attempt to bypass authentication [${req.ip}]`);
- req.app.locals.cooldown(req, 3e5);
- return;
- }
-
- if (!req.body || !Reflect.has(req.body, "email") ||
- !req.body.email.match(/^(?:[a-zA-Z0-9.$&+=_~-]{1,255}@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,255}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,255}[a-zA-Z0-9])?){1,9})$/) ||
- req.body.email.length >= 320) {
- res.status(400).json({
- status: "error",
- error: "invalid email address",
- });
- req.app.locals.cooldown(req, 1e3);
- return;
- }
-
- const session = req.app.locals.session.get(token);
+ let session;
- if (session === null || session === undefined) {
- res.status(410).json({
- status: "error",
- error: "session expired",
- });
- req.app.locals.cooldown(req, 5e3);
- return;
- }
+ try {
+ [, session] = validate.get_session(req, res);
+ } catch { return } // already handled
- if (session.authenticated !== true) {
- res.status(401).json({
- status: "error",
- error: "not authenticated",
- });
- req.app.locals.logger.warn(`Vault.identity: blocked an attempt to bypass authentication [${req.ip}]`);
- req.app.locals.cooldown(req, 3e5);
- return;
- }
+ let email;
+ try {
+ email = validate.get_email(req, res);
+ } catch { return } // already handled
for (const [key, pending] of req.app.locals.identity_pending) {
- if (pending.vault === session.vault && pending.email === req.body.email) {
+ if (pending.vault === session.vault && pending.email === email) {
res.status(425).json({
status: "error",
error: "already pending",
@@ -199,7 +142,7 @@ const add_identity = async (req, res, next) => {
}
const find = await req.app.locals.vault.identity.findOne({
- where: {email: req.body.email}
+ where: {email}
});
if (find !== null) {
@@ -232,7 +175,7 @@ const add_identity = async (req, res, next) => {
req.app.locals.identity_pending.set(uuid, {
ip: req.ip,
vault: session.vault,
- email: req.body.email,
+ email: email,
});
console.log(`Vault.session: starting identity validation <${session.vault}@vault> [${req.ip}]`);
@@ -243,7 +186,7 @@ const add_identity = async (req, res, next) => {
// TODO: limit total number of emails that can be dispatched by a single ip in an hour
transporter.sendMail({
from: process.env.VAULT__MAILER__FROM,
- to: req.body.email,
+ to: email,
subject: "The Mana World identity validation",
text: "You are receiving this email because someone (you?) has requested to link your email address "+
"to a TMW Vault account.\nIf you did not initiate this process, please ignore this email.\n\n"+
@@ -258,14 +201,6 @@ const add_identity = async (req, res, next) => {
req.app.locals.cooldown(req, 5e3);
};
-const update_identity = async (req, res, next) => {
- // TODO
-};
-
-const drop_identity = async (req, res, next) => {
- // TODO
-};
-
module.exports = exports = async (req, res, next) => {
switch(req.method) {
case "GET":
@@ -274,11 +209,8 @@ module.exports = exports = async (req, res, next) => {
case "POST":
// add identity
return await add_identity(req, res, next);
- case "PATCH":
- // set as primary
- //return await update_identity(req, res, next);
case "DELETE":
- // remove an identity
+ // TODO: remove an identity
//return await drop_identity(req, res, next);
default:
next(); // fallthrough to default endpoint (404)