Draft game update. TODO: debug, finish view/Game.vue
[vchess.git] / server / models / User.js
CommitLineData
8d7e2786 1var db = require("../utils/database");
badeb466 2var genToken = require("../utils/tokenGenerator");
c018b304 3var params = require("../config/parameters");
2be5d614 4var sendEmail = require('../utils/mailer');
8d7e2786
BA
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
ab4f4bf2 17const UserModel =
8d7e2786 18{
98db2082
BA
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
ab4f4bf2
BA
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 });
c018b304 50 });
ab4f4bf2 51 },
8d7e2786 52
ab4f4bf2
BA
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 },
8d7e2786 65
ed9c9c37
BA
66 getByIds: function(ids, cb) {
67 db.serialize(function() {
68 const query =
69 "SELECT id, name " +
1f49533d 70 "FROM Users " +
ed9c9c37
BA
71 "WHERE id IN (" + ids + ")";
72 db.all(query, cb);
73 });
1f49533d
BA
74 },
75
ab4f4bf2
BA
76 /////////
77 // MODIFY
8d7e2786 78
ab4f4bf2
BA
79 setLoginToken: function(token, uid, cb)
80 {
81 db.serialize(function() {
82 const query =
8a477a7e 83 "UPDATE Users " +
ab4f4bf2 84 "SET loginToken = '" + token + "', loginTime = " + Date.now() + " " +
8a477a7e 85 "WHERE id = " + uid;
ab4f4bf2 86 db.run(query, cb);
0bd5933d 87 });
ab4f4bf2 88 },
8d7e2786 89
ab4f4bf2
BA
90 // Set session token only if empty (first login)
91 // TODO: weaker security (but avoid to re-login everywhere after each logout)
92 trySetSessionToken: function(uid, cb)
93 {
94 // Also empty the login token to invalidate future attempts
95 db.serialize(function() {
96 const querySessionToken =
97 "SELECT sessionToken " +
98 "FROM Users " +
99 "WHERE id = " + uid;
100 db.get(querySessionToken, (err,ret) => {
101 if (!!err)
102 return cb(err);
103 const token = ret.sessionToken || genToken(params.token.length);
104 const queryUpdate =
105 "UPDATE Users " +
106 "SET loginToken = NULL" +
107 (!ret.sessionToken ? (", sessionToken = '" + token + "'") : "") + " " +
108 "WHERE id = " + uid;
109 db.run(queryUpdate);
110 cb(null, token);
111 });
112 });
113 },
114
115 updateSettings: function(user, cb)
116 {
117 db.serialize(function() {
118 const query =
119 "UPDATE Users " +
120 "SET name = '" + user.name + "'" +
121 ", email = '" + user.email + "'" +
122 ", notify = " + user.notify + " " +
123 "WHERE id = " + user.id;
124 db.run(query, cb);
125 });
126 },
5d04793e
BA
127
128 /////////////////
129 // NOTIFICATIONS
130
2be5d614 131 tryNotify: function(oppId, message)
5d04793e 132 {
2be5d614
BA
133 UserModel.getOne("id", oppId, (err,opp) => {
134 if (!err || !opp.notify)
135 return; //error is ignored here (TODO: should be logged)
136 const subject = "vchess.club - notification";
137 const body = "Hello " + opp.name + "!\n" + message;
138 sendEmail(params.mail.noreply, opp.email, subject, body, err => {
139 res.json(err || {});
140 });
141 });
5d04793e 142 }
8d7e2786 143}
ab4f4bf2
BA
144
145module.exports = UserModel;