contract-notifier/api/controller.js

182 lines
4.5 KiB
JavaScript
Raw Normal View History

2019-11-15 10:42:59 -04:00
const { validationResult } = require("express-validator");
const { isSignatureValid, getToken } = require("./utils");
const Subscribers = require("../models/subscribers");
const Verifications = require("../models/verifications");
2019-11-18 09:57:03 -04:00
const BadRequest = require("./bad-request");
2019-11-15 10:42:59 -04:00
class Controller {
static subscribe(dappConfig, mailer) {
2019-11-18 09:57:03 -04:00
return async (req, res, next) => {
2019-11-15 10:42:59 -04:00
const {
params: { dappId },
body: { address, email, signature }
} = req;
const errors = validationResult(req);
if (!errors.isEmpty()) {
2019-11-18 09:57:03 -04:00
return next(new BadRequest(errors.array()));
2019-11-15 10:42:59 -04:00
}
if (!dappConfig.isDapp(dappId)) {
2019-11-18 09:57:03 -04:00
return next(new BadRequest("DApp not found"));
2019-11-15 10:42:59 -04:00
}
if (!isSignatureValid(address, email, signature)) {
2019-11-18 09:57:03 -04:00
return next(new BadRequest("Invalid signature"));
2019-11-15 10:42:59 -04:00
}
// TODO: handle subscriptions to particular events
2019-11-18 10:05:18 -04:00
try {
const subscriber = await Subscribers.findOne({
2019-11-15 10:42:59 -04:00
dappId,
address
});
2019-11-18 10:05:18 -04:00
const t = getToken();
if (!subscriber) {
const s = await Subscribers.create({
dappId,
email,
address
});
await Verifications.create({
...t,
subscriber: s._id
});
} else if (!subscriber.isVerified) {
const d = new Date(subscriber.lastSignUpAttempt);
d.setMinutes(d.getMinutes() + 5);
if (d > new Date()) {
return next(new BadRequest("You need to wait at least 5 minutes between sign up attempts"));
}
subscriber.lastSignUpAttempt = d;
await subscriber.save();
await Verifications.create({
...t,
subscriber: subscriber._id
});
2019-11-15 10:42:59 -04:00
}
2019-11-18 10:05:18 -04:00
if (!subscriber || !subscriber.isVerified) {
const template = dappConfig.template(dappId, "sign-up");
mailer.send(dappConfig.getEmailTemplate(dappId, template), dappConfig.config(dappId).from, {
email,
token: t.token
});
}
} catch (err) {
return next(err);
2019-11-15 10:42:59 -04:00
}
return res.status(200).send("OK");
};
}
static unsubscribe(dappConfig) {
return async (req, res) => {
// TODO:
const {
params: { dappId },
body: { address, signature }
} = req;
2019-11-15 14:18:47 -04:00
const errors = validationResult(req);
if (!errors.isEmpty()) {
2019-11-18 09:57:03 -04:00
return next(new BadRequest(errors.array()));
2019-11-15 14:18:47 -04:00
}
2019-11-15 10:42:59 -04:00
if (!dappConfig.isDapp(dappId)) {
2019-11-18 09:57:03 -04:00
return next(new BadRequest("DApp not found"));
2019-11-15 10:42:59 -04:00
}
if (!isSignatureValid(address, dappId, signature)) {
2019-11-18 09:57:03 -04:00
return next(new BadRequest("Invalid signature"));
2019-11-15 10:42:59 -04:00
}
// TODO: handle unsubscribe to particular events
2019-11-18 10:05:18 -04:00
try {
await Subscribers.deleteOne({
dappId,
address
});
} catch (err) {
return next(err);
}
2019-11-15 10:42:59 -04:00
return res.status(200).send("OK");
};
}
static confirm() {
return async (req, res) => {
const {
params: { token }
} = req;
2019-11-15 14:18:47 -04:00
const errors = validationResult(req);
if (!errors.isEmpty()) {
2019-11-18 09:57:03 -04:00
return next(new BadRequest(errors.array()));
2019-11-15 14:18:47 -04:00
}
2019-11-18 10:05:18 -04:00
try {
const verification = await Verifications.findOne({
token
}).populate("subscriber");
if (verification) {
if (verification.expirationTime < new Date()) {
return next(new BadRequest("Verification token already expired"));
}
if (!verification.subscriber.isVerified) {
verification.subscriber.isVerified = true;
await verification.subscriber.save();
}
await Verifications.deleteMany({
subscriber: verification.subscriber._id
});
} else {
return next(new BadRequest("Invalid verification token"));
2019-11-15 10:42:59 -04:00
}
2019-11-18 10:05:18 -04:00
} catch (err) {
return next(err);
2019-11-15 10:42:59 -04:00
}
return res.status(200).send("OK");
};
}
2019-11-15 14:18:47 -04:00
static userExists() {
return async (req, res) => {
const {
params: { dappId, address }
} = req;
const errors = validationResult(req);
if (!errors.isEmpty()) {
2019-11-18 09:57:03 -04:00
return next(new BadRequest(errors.array()));
2019-11-15 14:18:47 -04:00
}
2019-11-18 10:05:18 -04:00
try {
const subscriber = await Subscribers.findOne({
dappId,
address,
isVerified: true
});
2019-11-15 14:18:47 -04:00
2019-11-18 10:05:18 -04:00
return res.status(200).json({ isUser: subscriber ? true : false });
} catch (err) {
return next(err);
}
2019-11-15 14:18:47 -04:00
};
}
2019-11-15 10:42:59 -04:00
}
module.exports = Controller;