1 let router
= require("express").Router();
2 const UserModel
= require('../models/User');
3 const sendEmail
= require('../utils/mailer');
4 const genToken
= require("../utils/tokenGenerator");
5 const access
= require("../utils/access");
6 const params
= require("../config/parameters");
8 router
.post('/register', access
.unlogged
, access
.ajax
, (req
,res
) => {
9 const name
= req
.body
.name
;
10 const email
= req
.body
.email
;
11 const notify
= !!req
.body
.notify
;
12 if (UserModel
.checkNameEmail({name: name
, email: email
})) {
13 UserModel
.create(name
, email
, notify
, (err
, ret
) => {
15 const msg
= err
.code
== "SQLITE_CONSTRAINT"
16 ? "User name or email already in use"
17 : "User creation failed. Try again";
18 res
.json({errmsg: msg
});
25 setAndSendLoginToken("Welcome to " + params
.siteURL
, user
, res
);
32 // NOTE: this method is safe because the sessionToken must be guessed
33 router
.get("/whoami", access
.ajax
, (req
,res
) => {
34 const callback
= (user
) => {
40 newsRead: user
.newsRead
50 if (!req
.cookies
.token
) callback(anonymous
);
51 else if (req
.cookies
.token
.match(/^[a-z0-9]+$/)) {
52 UserModel
.getOne("sessionToken", req
.cookies
.token
, (err
, user
) => {
53 callback(user
|| anonymous
);
58 // NOTE: this method is safe because only IDs and names are returned
59 router
.get("/users", access
.ajax
, (req
,res
) => {
60 const ids
= req
.query
["ids"];
61 // NOTE: slightly too permissive RegExp
62 if (ids
.match(/^([0-9]+,?)+$/)) {
63 UserModel
.getByIds(ids
, (err
,users
) => {
64 res
.json({users:users
});
69 router
.put('/update', access
.logged
, access
.ajax
, (req
,res
) => {
70 const name
= req
.body
.name
;
71 const email
= req
.body
.email
;
72 if (UserModel
.checkNameEmail({name: name
, email: email
})) {
77 notify: !!req
.body
.notify
,
79 UserModel
.updateSettings(user
);
84 // Special route to update newsRead timestamp:
85 router
.put('/newsread', access
.logged
, access
.ajax
, (req
,res
) => {
86 UserModel
.setNewsRead(req
.userId
);
90 // Authentication-related methods:
92 // to: object user (to who we send an email)
93 function setAndSendLoginToken(subject
, to
, res
) {
94 // Set login token and send welcome(back) email with auth link
95 const token
= genToken(params
.token
.length
);
96 UserModel
.setLoginToken(token
, to
.id
);
98 "Hello " + to
.name
+ " !" + `
100 "Access your account here: " +
101 params
.siteURL
+ "/#/authenticate/" + token
+ `
103 "Token will expire in " + params
.token
.expire
/(1000*60) + " minutes."
104 sendEmail(params
.mail
.noreply
, to
.email
, subject
, body
);
107 router
.get('/sendtoken', access
.unlogged
, access
.ajax
, (req
,res
) => {
108 const nameOrEmail
= decodeURIComponent(req
.query
.nameOrEmail
);
109 const type
= (nameOrEmail
.indexOf('@') >= 0 ? "email" : "name");
110 if (UserModel
.checkNameEmail({[type
]: nameOrEmail
})) {
111 UserModel
.getOne(type
, nameOrEmail
, (err
,user
) => {
112 access
.checkRequest(res
, err
, user
, "Unknown user", () => {
113 setAndSendLoginToken("Token for " + params
.siteURL
, user
, res
);
120 router
.get('/authenticate', access
.unlogged
, access
.ajax
, (req
,res
) => {
121 if (!req
.query
.token
.match(/^[a-z0-9]+$/))
122 return res
.json({errmsg: "Bad token"});
123 UserModel
.getOne("loginToken", req
.query
.token
, (err
,user
) => {
124 access
.checkRequest(res
, err
, user
, "Invalid token", () => {
125 // If token older than params.tokenExpire, do nothing
126 if (Date
.now() > user
.loginTime
+ params
.token
.expire
)
127 res
.json({errmsg: "Token expired"});
129 // Generate session token (if not exists) + destroy login token
130 UserModel
.trySetSessionToken(user
.id
, (token
) => {
131 res
.cookie("token", token
, {
133 secure: !!params
.siteURL
.match(/^https/),
134 maxAge: params
.cookieExpire
,
148 router
.get('/logout', access
.logged
, access
.ajax
, (req
,res
) => {
149 res
.clearCookie("token");
153 module
.exports
= router
;