Advance on client side
[vchess.git] / server / models / User.js
1 var db = require("../utils/database");
2 var maild = require("../utils/mailer.js");
3 var genToken = require("../utils/tokenGenerator");
4 var params = require("../config/parameters");
5
6 /*
7 * Structure:
8 * _id: integer
9 * name: varchar
10 * email: varchar
11 * loginToken: token on server only
12 * loginTime: datetime (validity)
13 * sessionToken: token in cookies for authentication
14 * notify: boolean (send email notifications for corr games)
15 */
16
17 const UserModel =
18 {
19 checkNameEmail: function(o)
20 {
21 if (typeof o.name === "string")
22 {
23 if (o.name.length == 0)
24 return "Empty name";
25 if (!o.name.match(/^[\w]+$/))
26 return "Bad characters in name";
27 }
28 if (typeof o.email === "string")
29 {
30 if (o.email.length == 0)
31 return "Empty email";
32 if (!o.email.match(/^[\w.+-]+@[\w.+-]+$/))
33 return "Bad characters in email";
34 }
35 },
36
37 // NOTE: parameters are already cleaned (in controller), thus no sanitization here
38 create: function(name, email, notify, callback)
39 {
40 db.serialize(function() {
41 const insertQuery =
42 "INSERT INTO Users " +
43 "(name, email, notify) VALUES " +
44 "('" + name + "', '" + email + "', " + notify + ")";
45 db.run(insertQuery, err => {
46 if (!!err)
47 return callback(err);
48 db.get("SELECT last_insert_rowid() AS rowid", callback);
49 });
50 });
51 },
52
53 // Find one user (by id, name, email, or token)
54 getOne: function(by, value, cb)
55 {
56 const delimiter = (typeof value === "string" ? "'" : "");
57 db.serialize(function() {
58 const query =
59 "SELECT * " +
60 "FROM Users " +
61 "WHERE " + by + " = " + delimiter + value + delimiter;
62 db.get(query, cb);
63 });
64 },
65
66 /////////
67 // MODIFY
68
69 setLoginToken: function(token, uid, cb)
70 {
71 db.serialize(function() {
72 const query =
73 "UPDATE Users " +
74 "SET loginToken = '" + token + "', loginTime = " + Date.now() + " " +
75 "WHERE id = " + uid;
76 db.run(query, cb);
77 });
78 },
79
80 // Set session token only if empty (first login)
81 // TODO: weaker security (but avoid to re-login everywhere after each logout)
82 trySetSessionToken: function(uid, cb)
83 {
84 // Also empty the login token to invalidate future attempts
85 db.serialize(function() {
86 const querySessionToken =
87 "SELECT sessionToken " +
88 "FROM Users " +
89 "WHERE id = " + uid;
90 db.get(querySessionToken, (err,ret) => {
91 if (!!err)
92 return cb(err);
93 const token = ret.sessionToken || genToken(params.token.length);
94 const queryUpdate =
95 "UPDATE Users " +
96 "SET loginToken = NULL" +
97 (!ret.sessionToken ? (", sessionToken = '" + token + "'") : "") + " " +
98 "WHERE id = " + uid;
99 db.run(queryUpdate);
100 cb(null, token);
101 });
102 });
103 },
104
105 updateSettings: function(user, cb)
106 {
107 db.serialize(function() {
108 const query =
109 "UPDATE Users " +
110 "SET name = '" + user.name + "'" +
111 ", email = '" + user.email + "'" +
112 ", notify = " + user.notify + " " +
113 "WHERE id = " + user.id;
114 db.run(query, cb);
115 });
116 },
117 }
118
119 module.exports = UserModel;