notherbase-fs 4.5.3 → 4.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server/user.js +232 -165
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notherbase-fs",
3
- "version": "4.5.3",
3
+ "version": "4.5.5",
4
4
  "description": "Functions to help make developing for NotherBase easier.",
5
5
  "exports": "./notherbase-fs.js",
6
6
  "scripts": {
package/server/user.js CHANGED
@@ -28,12 +28,17 @@ export default class User {
28
28
  * @param {Object} res An Express.js response.
29
29
  */
30
30
  logout = async (req, res) => {
31
- if (loginCheck(req, res)) {
32
- delete req.user?.data?.sessions[req.session.id];
33
- await req.user.commit();
34
- await req.session?.destroy();
31
+ try {
32
+ if (loginCheck(req, res)) {
33
+ delete req.user?.data?.sessions[req.session.id];
34
+ await req.user.commit();
35
+ await req.session?.destroy();
35
36
 
36
- success(res, "Logged out.");
37
+ success(res, "Logged out.");
38
+ }
39
+ } catch (error) {
40
+ console.log(error);
41
+ fail(res, "Server error");
37
42
  }
38
43
  }
39
44
 
@@ -43,49 +48,57 @@ export default class User {
43
48
  * @param {Object} res An Express.js response.
44
49
  */
45
50
  changePassword = async (req, res) => {
46
- if (loginCheck(req, res)) {
47
- let spirit = await req.Spirit.findOne({ service: "user", username: req.session.username });
51
+ try {
52
+ if (loginCheck(req, res)) {
53
+ let spirit = await req.Spirit.findOne({ service: "user", "data.username": req.session.currentUser });
54
+ console.log(spirit);
55
+
48
56
 
49
- if (check(res, spirit, "User not found!") &&
50
- check(res, req.body.newPassword === req.body.confirmation, "New password and confirmation must match!") &&
51
- check(res, req.body.oldPassword != req.body.newPassword, "New password must be different from the old one."))
52
- {
53
- let passResult = await bcrypt.compare(req.body.oldPassword, spirit.data.password);
57
+ if (check(res, spirit, "User not found!") &&
58
+ check(res, req.body.newPassword === req.body.confirmation, "New password and confirmation must match!") &&
59
+ check(res, req.body.oldPassword != req.body.newPassword, "New password must be different from the old one."))
60
+ {
61
+ let passResult = await bcrypt.compare(req.body.oldPassword, spirit.data.password);
54
62
 
55
- if (check(res, passResult, "Old password incorrect.")) {
56
- const salt = await bcrypt.genSalt(10);
57
- const hash = await bcrypt.hash(req.body.newPassword, salt);
58
-
59
- spirit.addBackup({
60
- ...spirit.data,
61
- password: hash
62
- });
63
-
64
- await spirit.commit();
65
-
66
- success(res, "Password changed successfully!");
63
+ if (check(res, passResult, "Old password incorrect.")) {
64
+ const salt = await bcrypt.genSalt(10);
65
+ const hash = await bcrypt.hash(req.body.newPassword, salt);
66
+
67
+ spirit.data.password = hash;
68
+ await spirit.commit();
69
+
70
+ success(res, "Password changed successfully!");
71
+ }
67
72
  }
68
73
  }
74
+ } catch (error) {
75
+ console.log(error);
76
+ fail(res, "Server error");
69
77
  }
70
78
  }
71
79
 
72
80
  validatePassword = async (req, password, user) => {
73
- if (password && user?.data?.otp) {
74
- if (password == user.data.otp.code) {
75
- if (Date.now() < user.data.otp.expires) {
76
- user.data.otp.expires = 0;
77
- await user.commit();
78
- return "Authenticated.";
81
+ try {
82
+ if (password && user?.data?.otp) {
83
+ if (password == user.data.otp.code) {
84
+ if (Date.now() < user.data.otp.expires) {
85
+ user.data.otp.expires = 0;
86
+ await user.commit();
87
+ return "Authenticated.";
88
+ }
89
+ else return "One-time password expired.";
90
+ }
91
+ else {
92
+ let passResult = await bcrypt.compare(req.body.password, user.data.password);
93
+ if (passResult) return "Authenticated.";
94
+ else return "Password doesn't match the username.";
79
95
  }
80
- else return "One-time password expired.";
81
- }
82
- else {
83
- let passResult = await bcrypt.compare(req.body.password, user.data.password);
84
- if (passResult) return "Authenticated.";
85
- else return "Password doesn't match the username.";
86
96
  }
97
+ else return "Password error.";
98
+ } catch (error) {
99
+ console.log(error);
100
+ fail(res, "Server error");
87
101
  }
88
- else return "Password error.";
89
102
  }
90
103
 
91
104
  /**
@@ -94,29 +107,30 @@ export default class User {
94
107
  * @param {Object} res An Express.js response.
95
108
  */
96
109
  changeEmail = async (req, res) => {
97
- if (loginCheck(req, res)) {
98
- let spirit = await req.Spirit.findOne({ service: "user", username: req.session.username });
110
+ try {
111
+ if (loginCheck(req, res)) {
112
+ let spirit = await req.Spirit.findOne({ service: "user", "data.username": req.session.currentUser });
99
113
 
100
- if (check(res, spirit, "User not found!") &&
101
- check(res, req.body.email, "New email must be provided."))
102
- {
103
- let result = await this.validatePassword(req, req.body.password, spirit);
104
- if (result == "Authenticated.") {
105
- let other = await req.Spirit.recallOne("user", null, { email: req.body.email });
106
-
107
- if (check(res, !other, "Email already in use!")) {
108
- spirit.addBackup({
109
- ...spirit.data,
110
- email: req.body.email
111
- });
112
-
113
- await spirit.commit();
114
-
115
- success(res, "Email changed successfully!");
114
+ if (check(res, spirit, "User not found!") &&
115
+ check(res, req.body.email, "New email must be provided."))
116
+ {
117
+ let result = await this.validatePassword(req, req.body.password, spirit);
118
+ if (result == "Authenticated.") {
119
+ let other = await req.Spirit.findOne({ service: "user", "data.email": req.body.email });
120
+
121
+ if (check(res, !other, "Email already in use!")) {
122
+ spirit.data.email = req.body.email;
123
+ await spirit.commit();
124
+
125
+ success(res, "Email changed successfully!");
126
+ }
116
127
  }
128
+ else fail(res, result);
117
129
  }
118
- else fail(res, result);
119
130
  }
131
+ } catch (error) {
132
+ console.log(error);
133
+ fail(res, "Server error");
120
134
  }
121
135
  }
122
136
 
@@ -126,26 +140,31 @@ export default class User {
126
140
  * @param {Object} res An Express.js response.
127
141
  */
128
142
  sendOneTimePassword = async (req, res) => {
129
- if (loginCheck(req, res)) {
130
- let spirit = await req.Spirit.findOne({ service: "user", username: req.session.username });
143
+ try {
144
+ if (loginCheck(req, res)) {
145
+ let spirit = await req.Spirit.findOne({ service: "user", "data.username": req.session.currentUser });
131
146
 
132
- if (check(res, spirit, "User not found!")) {
133
- let otp = Math.floor(100000 + Math.random() * 900000);
134
- spirit.data.otp = {
135
- code: otp,
136
- expires: Date.now() + 1000 * 60 * 15
137
- }
138
-
139
- await spirit.commit();
147
+ if (check(res, spirit, "User not found!")) {
148
+ let otp = Math.floor(100000 + Math.random() * 900000);
149
+ spirit.data.otp = {
150
+ code: otp,
151
+ expires: Date.now() + 1000 * 60 * 15
152
+ }
153
+
154
+ await spirit.commit();
140
155
 
141
- await req.SendMail.send(spirit.data.email, 'One Time Password for NotherBase',
142
- `<h1>Your One-Time Password:<h1>
143
- <h2>${otp}<h2>
144
- <p>Visit <a href="https://www.notherbase.com/the-front/keeper">notherbase.com/the-front/keeper</a> to use your one-time password.</p>
145
- <p>This one-time password expires in 15 minutes.<p>`);
146
-
147
- success(res, "One-time password sent.");
156
+ await req.SendMail.send(spirit.data.email, 'One Time Password for NotherBase',
157
+ `<h1>Your One-Time Password:<h1>
158
+ <h2>${otp}<h2>
159
+ <p>Visit <a href="https://www.notherbase.com/the-front/keeper">notherbase.com/the-front/keeper</a> to use your one-time password.</p>
160
+ <p>This one-time password expires in 15 minutes.<p>`);
161
+
162
+ success(res, "One-time password sent.");
163
+ }
148
164
  }
165
+ } catch (error) {
166
+ console.log(error);
167
+ fail(res, "Server error");
149
168
  }
150
169
  }
151
170
 
@@ -155,30 +174,41 @@ export default class User {
155
174
  * @param {Object} res An Express.js response.
156
175
  */
157
176
  register = async (req, res) => {
158
- if (check(res, req.body.password.length > 10, "Password must be >10 characters long.") &&
159
- check(res, req.body.username.length > 2, "Username too short."))
160
- {
161
- let spirit = await req.Spirit.findOne({ service: "user", username: req.body.username });
162
-
163
- if (check(res, !spirit, "Username already in use!")) {
164
- const salt = await bcrypt.genSalt(10);
165
- const hash = await bcrypt.hash(req.body.password, salt);
166
-
167
- spirit = await req.Spirit.create("user", {
168
- username: req.body.username,
169
- password: hash,
170
- authLevels: [ "Basic" ],
171
- view: "compact",
172
- email: "",
173
- otp: {
174
- code: "",
175
- expires: 0
176
- },
177
- sessions: {}
178
- });
177
+ try {
178
+ if (check(res, req.body.password.length > 10, "Password must be >10 characters long.") &&
179
+ check(res, req.body.username.length > 2, "Username too short."))
180
+ {
181
+ let spirit = await req.Spirit.findOne({ service: "user", "data.username": req.body.username });
179
182
 
180
- success(res, "Registration successful!");
183
+ if (check(res, !spirit, "Username already in use!")) {
184
+ const salt = await bcrypt.genSalt(10);
185
+ const hash = await bcrypt.hash(req.body.password, salt);
186
+
187
+ spirit = new req.Spirit({
188
+ service:"user",
189
+ _lastUpdate: Date.now(),
190
+ data: {
191
+ username: req.body.username,
192
+ password: hash,
193
+ authLevels: [ "Basic" ],
194
+ view: "compact",
195
+ email: "",
196
+ otp: {
197
+ code: "",
198
+ expires: 0
199
+ },
200
+ sessions: {}
201
+ },
202
+ backups: []
203
+ });
204
+ await spirit.save();
205
+
206
+ success(res, "Registration successful!");
207
+ }
181
208
  }
209
+ } catch (error) {
210
+ console.log(error);
211
+ fail(res, "Server error");
182
212
  }
183
213
  }
184
214
 
@@ -188,32 +218,37 @@ export default class User {
188
218
  * @param {Object} res An Express.js response.
189
219
  */
190
220
  login = async (req, res) => {
191
- let spirit = await req.Spirit.findOne({ service: "user", username: req.body.username });
192
- if (check(res, spirit, "User not found.")) {
193
- spirit.data = {
194
- username: "",
195
- password: "",
196
- authLevels: [ "Basic" ],
197
- view: "compact",
198
- email: "",
199
- otp: {
200
- code: "",
201
- expires: 0
202
- },
203
- sessions: {},
204
- ...spirit.data
205
- }
206
- await spirit.commit();
207
-
208
- let result = await this.validatePassword(req, req.body.password, spirit);
209
- if (result === "Authenticated.") {
210
- req.session.currentUser = req.body.username;
211
- if (typeof spirit.data.sessions !== "object" || Array.isArray(spirit.data.sessions)) spirit.data.sessions = {};
212
- spirit.data.sessions[req.session.id] = Date.now() + 1000 * 60 * 60 * 24 * 28; // 28 days
221
+ try {
222
+ let spirit = await req.Spirit.findOne({ service: "user", "data.username": req.body.username });
223
+ if (check(res, spirit, "User not found.")) {
224
+ spirit.data = {
225
+ username: "",
226
+ password: "",
227
+ authLevels: [ "Basic" ],
228
+ view: "compact",
229
+ email: "",
230
+ otp: {
231
+ code: "",
232
+ expires: 0
233
+ },
234
+ sessions: {},
235
+ ...spirit.data
236
+ }
213
237
  await spirit.commit();
214
- success(res, "Login successful!", req.body.username);
238
+
239
+ let result = await this.validatePassword(req, req.body.password, spirit);
240
+ if (result === "Authenticated.") {
241
+ req.session.currentUser = req.body.username;
242
+ if (typeof spirit.data.sessions !== "object" || Array.isArray(spirit.data.sessions)) spirit.data.sessions = {};
243
+ spirit.data.sessions[req.session.id] = Date.now() + 1000 * 60 * 60 * 24 * 28; // 28 days
244
+ await spirit.commit();
245
+ success(res, "Login successful!", req.body.username);
246
+ }
247
+ else fail(res, result);
215
248
  }
216
- else fail(res, result);
249
+ } catch (error) {
250
+ console.log(error);
251
+ fail(res, "Server error");
217
252
  }
218
253
  }
219
254
 
@@ -223,22 +258,27 @@ export default class User {
223
258
  * @param {Object} res An Express.js response.
224
259
  */
225
260
  deletePermanently = async (req, res) => {
226
- if (loginCheck(req, res)) {
227
- let spirit = await req.Spirit.findOne({ service: "user", username: req.session.username });
261
+ try {
262
+ if (loginCheck(req, res)) {
263
+ let spirit = await req.Spirit.findOne({ service: "user", "data.username": req.session.currentUser });
228
264
 
229
- if (check(res, spirit, "User not found.")) {
230
- let passResult = await bcrypt.compare(req.body.password, spirit.data.password);
265
+ if (check(res, spirit, "User not found.")) {
266
+ let passResult = await bcrypt.compare(req.body.password, spirit.data.password);
231
267
 
232
- if (check(res, passResult, "Password doesn't match the username.")) {
233
- let deleted = await req.Spirit.deleteMany({ service: "user", username: req.session.username });
234
-
235
- if (check(res, deleted > 0, "No account deleted")) {
236
- await req.session.destroy();
268
+ if (check(res, passResult, "Password doesn't match the username.")) {
269
+ let deleted = await req.Spirit.deleteMany({ service: "user", "data.username": req.session.currentUser });
237
270
 
238
- success(res, "Account deleted.");
271
+ if (check(res, deleted > 0, "No account deleted")) {
272
+ await req.session.destroy();
273
+
274
+ success(res, "Account deleted.");
275
+ }
239
276
  }
240
277
  }
241
278
  }
279
+ } catch (error) {
280
+ console.log(error);
281
+ fail(res, "Server error");
242
282
  }
243
283
  }
244
284
 
@@ -248,74 +288,101 @@ export default class User {
248
288
  * @param {Object} res An Express.js response.
249
289
  */
250
290
  getInfo = async (req, res) => {
251
- if (loginCheck(req, res)) {
252
- let user = await req.Spirit.findOne({ service: "user", username: req.session.username });
253
-
254
- if (check(res, user, "Account not found!")) {
255
- success(res, "Info found", {
256
- username: user.data.username
257
- });
291
+ try {
292
+ if (loginCheck(req, res)) {
293
+ let user = await req.Spirit.findOne({ service: "user", "data.username": req.session.currentUser });
294
+
295
+ if (check(res, user, "Account not found!")) {
296
+ success(res, "Info found", {
297
+ username: user.data.username
298
+ });
299
+ }
258
300
  }
301
+ } catch (error) {
302
+ console.log(error);
303
+ fail(res, "Server error");
259
304
  }
260
305
  }
261
306
 
262
307
  //download all spirit data belonging to the user
263
308
  downloadData = async (req, res) => {
264
- if (loginCheck(req, res)) {
265
- let user = await req.Spirit.findOne({ service: "user", username: req.session.username });
309
+ try {
310
+ if (loginCheck(req, res)) {
311
+ let user = await req.Spirit.findOne({ service: "user", "data.username": req.session.currentUser });
266
312
 
267
- if (check(res, user, "Account not found!")) {
268
- let data = await req.Spirit.recallAll(null, user._id);
269
- let dataToDownload = data.map(d => d);
313
+ if (check(res, user, "Account not found!")) {
314
+ let data = await req.Spirit.find({ parent: user._id });
315
+ let dataToDownload = data.map(d => d);
270
316
 
271
- successJSON(res, "Data Downloaded", dataToDownload);
317
+ successJSON(res, "Data Downloaded", dataToDownload);
318
+ }
272
319
  }
320
+ } catch (error) {
321
+ console.log(error);
322
+ fail(res, "Server error");
273
323
  }
274
324
  }
275
325
 
276
326
  //delete all spirit data belonging to the user
277
327
  deleteAlldata = async (req, res) => {
278
- if (loginCheck(req, res)) {
279
- let user = await req.Spirit.findOne({ service: "user", username: req.session.username });
328
+ try {
329
+ if (loginCheck(req, res)) {
330
+ let user = await req.Spirit.findOne({ service: "user", "data.username": req.session.currentUser });
280
331
 
281
- if (check(res, user, "Account not found!")) {
282
- if (check(res, req.body.password, "Password error.")) {
283
- let passResult = await bcrypt.compare(req.body.password, user.data.password);
332
+ if (check(res, user, "Account not found!")) {
333
+ if (check(res, req.body.password, "Password error.")) {
334
+ let passResult = await bcrypt.compare(req.body.password, user.data.password);
284
335
 
285
- if (check(res, passResult, "Password doesn't match the username.")) {
286
- let deleted = await req.Spirit.deleteMany({ parent: user._id });
287
- if (check(res, deleted > 0, "No data deleted")) {
288
- success(res, "Data Deleted", deleted);
336
+ if (check(res, passResult, "Password doesn't match the username.")) {
337
+ let deleted = await req.Spirit.deleteMany({ parent: user._id });
338
+ if (check(res, deleted > 0, "No data deleted")) {
339
+ success(res, "Data Deleted", deleted);
340
+ }
289
341
  }
290
342
  }
291
343
  }
292
344
  }
345
+ } catch (error) {
346
+ console.log(error);
347
+ fail(res, "Server error");
293
348
  }
294
349
  }
295
350
 
296
351
  // import spirit data from a JSON file
297
352
  importData = async (req, res) => {
298
- if (loginCheck(req, res)) {
299
- let user = await req.Spirit.findOne({ service: "user", username: req.session.username });
353
+ try {
354
+ if (loginCheck(req, res)) {
355
+ let user = await req.Spirit.findOne({ service: "user", "data.username": req.session.currentUser });
300
356
 
301
- if (check(res, user, "Account not found!")) {
302
- if (check(res, req.body.password, "Password error.")) {
303
- let passResult = await bcrypt.compare(req.body.password, user.data.password);
357
+ if (check(res, user, "Account not found!")) {
358
+ if (check(res, req.body.password, "Password error.")) {
359
+ let passResult = await bcrypt.compare(req.body.password, user.data.password);
304
360
 
305
- if (check(res, passResult, "Password doesn't match the username.")) {
306
- let data = JSON.parse(req.body.data);
307
- let imported = 0;
308
- for (let i = 0; i < data.length; i++) {
309
- if (data[i].parent != null) {
310
- let spirit = await req.Spirit.create(data[i].service, data[i].data, user._id);
311
- if (spirit) imported++;
361
+ if (check(res, passResult, "Password doesn't match the username.")) {
362
+ let data = JSON.parse(req.body.data);
363
+ let imported = 0;
364
+ for (let i = 0; i < data.length; i++) {
365
+ if (data[i].parent != null) {
366
+ let spirit = new req.Spirit({
367
+ service: data[i].service,
368
+ _lastUpdate: data[i]._lastUpdate,
369
+ data: data[i].data,
370
+ parent: user._id,
371
+ backups: data[i].backups || []
372
+ });
373
+ await spirit.save();
374
+ if (spirit) imported++;
375
+ }
312
376
  }
313
- }
314
377
 
315
- success(res, "Data Imported", imported);
378
+ success(res, "Data Imported", imported);
379
+ }
316
380
  }
317
381
  }
318
382
  }
383
+ } catch (error) {
384
+ console.log(error);
385
+ fail(res, "Server error");
319
386
  }
320
387
  }
321
388
  }