notherbase-fs 3.5.1 → 4.0.0
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.
- package/controllers/creation.js +4 -3
- package/controllers/spirit-world.js +25 -22
- package/controllers/user.js +110 -126
- package/controllers/util.js +10 -1
- package/models/spirit.js +1 -1
- package/notherbase-fs.js +46 -33
- package/package.json +2 -2
- package/public/js/base.js +72 -30
- package/test/coast/tall-beach/nono-cove/index.ejs +3 -3
- package/test/public/drum.png +0 -0
- package/test/the-front/check/index.ejs +1 -1
- package/test/the-front/check/save-input.js +2 -2
- package/test/the-front/index.ejs +23 -33
- package/test-index.js +10 -2
- package/test2/pages/test-page/emailTime.js +9 -0
- package/test2/pages/test-page/index.ejs +105 -0
- package/test2/pages/void/index.ejs +36 -0
- package/test2/pages/void/void.css +3 -0
- package/test2/public/drum.png +0 -0
- package/test2/the-front/add-gold.js +14 -0
- package/test2/the-front/check/check.css +3 -0
- package/test2/the-front/check/emailTime.js +10 -0
- package/test2/the-front/check/flip.js +10 -0
- package/test2/the-front/check/index.ejs +55 -0
- package/test2/the-front/check/save-input.js +8 -0
- package/test2/the-front/index.ejs +100 -0
- package/test2/the-front/keeper/clipboards.js +134 -0
- package/test2/the-front/keeper/index.ejs +81 -0
- package/test2/the-front/keeper/keeper.css +158 -0
- package/test2/the-front/keeper/keeper.js +140 -0
- package/views/explorer.ejs +22 -22
- package/views/footer.ejs +2 -2
package/controllers/creation.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import express from "express";
|
|
2
2
|
import fs from 'fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Creation is all the renedered pages in a base.
|
|
6
7
|
*/
|
|
7
8
|
export default class Creation {
|
|
8
|
-
constructor(
|
|
9
|
-
this.
|
|
9
|
+
constructor(bases = {}) {
|
|
10
|
+
this.bases = bases;
|
|
10
11
|
this.router = express.Router();
|
|
11
12
|
|
|
12
13
|
//home
|
|
@@ -68,7 +69,7 @@ export default class Creation {
|
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
if (req.session.currentUser) {
|
|
71
|
-
context.user = await req.db.Spirit.recallOne("user", null, {
|
|
72
|
+
context.user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
res.render(req.toRender, context);
|
|
@@ -3,6 +3,9 @@ import { stripHtml } from "string-strip-html";
|
|
|
3
3
|
import { success, fail } from "./util.js";
|
|
4
4
|
import User from "./user.js";
|
|
5
5
|
import fs from 'fs';
|
|
6
|
+
import session from 'express-session';
|
|
7
|
+
import MongoStore from 'connect-mongo';
|
|
8
|
+
import subdomain from 'express-subdomain';
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* The spirit world is the API of a base.
|
|
@@ -15,49 +18,49 @@ export default class SpiritWorld {
|
|
|
15
18
|
constructor(io) {
|
|
16
19
|
this.io = io;
|
|
17
20
|
this.rooms = {};
|
|
21
|
+
this.io.on('connection', this.setupChat);
|
|
18
22
|
|
|
19
|
-
this.router = express.Router();
|
|
20
23
|
this.user = new User();
|
|
24
|
+
this.router = express.Router();
|
|
21
25
|
|
|
22
26
|
this.router.post("/loadAll", this.loadAll);
|
|
23
27
|
this.router.post("/load", this.load);
|
|
24
28
|
this.router.post("/serve", this.serve);
|
|
25
29
|
this.router.use("/user", this.user.router);
|
|
26
|
-
|
|
27
|
-
this.io.on('connection', this.#setupChat);
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* Sets up socket.io for instant messaging and etc.
|
|
32
34
|
* @param {*} socket
|
|
33
35
|
*/
|
|
34
|
-
|
|
35
|
-
socket.
|
|
36
|
-
|
|
36
|
+
setupChat = (socket) => {
|
|
37
|
+
let roomName = socket.handshake.query.room;
|
|
38
|
+
socket.join(roomName);
|
|
39
|
+
let room = this.rooms[roomName];
|
|
40
|
+
if (room) room.users.push(socket.handshake.query.name);
|
|
37
41
|
else {
|
|
38
|
-
this.rooms[
|
|
39
|
-
users: [
|
|
40
|
-
socket.handshake.query.name
|
|
41
|
-
]
|
|
42
|
+
this.rooms[roomName] = {
|
|
43
|
+
users: [ socket.handshake.query.name ]
|
|
42
44
|
}
|
|
45
|
+
room = this.rooms[roomName];
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
this.io.to(
|
|
48
|
+
this.io.to(roomName).emit("chat message", {
|
|
46
49
|
name: "Server",
|
|
47
50
|
time: Date.now(),
|
|
48
51
|
text: `${socket.handshake.query.name} has joined the room.`
|
|
49
52
|
});
|
|
50
53
|
|
|
51
|
-
this.io.to(
|
|
54
|
+
this.io.to(roomName).emit("chat info", {
|
|
52
55
|
name: socket.handshake.query.room,
|
|
53
56
|
time: Date.now(),
|
|
54
57
|
data: {
|
|
55
|
-
users:
|
|
58
|
+
users: room.users
|
|
56
59
|
}
|
|
57
60
|
});
|
|
58
61
|
|
|
59
62
|
socket.on("chat message", (msg) => {
|
|
60
|
-
this.io.to(
|
|
63
|
+
this.io.to(roomName).emit("chat message", {
|
|
61
64
|
name: msg.name,
|
|
62
65
|
time: msg.time,
|
|
63
66
|
text: stripHtml(msg.text).result
|
|
@@ -65,23 +68,23 @@ export default class SpiritWorld {
|
|
|
65
68
|
});
|
|
66
69
|
|
|
67
70
|
socket.on('disconnect', () => {
|
|
68
|
-
|
|
71
|
+
room.users.splice(room.users.indexOf(socket.handshake.query.name));
|
|
69
72
|
|
|
70
|
-
this.io.to(
|
|
73
|
+
this.io.to(roomName).emit("chat message", {
|
|
71
74
|
name: "Server",
|
|
72
75
|
time: Date.now(),
|
|
73
76
|
text: `${socket.handshake.query.name} has left the room.`
|
|
74
77
|
});
|
|
75
78
|
|
|
76
|
-
this.io.to(
|
|
79
|
+
this.io.to(roomName).emit("chat info", {
|
|
77
80
|
name: socket.handshake.query.room,
|
|
78
81
|
time: Date.now(),
|
|
79
82
|
data: {
|
|
80
|
-
users:
|
|
83
|
+
users: room.users
|
|
81
84
|
}
|
|
82
85
|
});
|
|
83
86
|
|
|
84
|
-
if (
|
|
87
|
+
if (room.users.length < 1) delete this.rooms[roomName];
|
|
85
88
|
});
|
|
86
89
|
}
|
|
87
90
|
|
|
@@ -99,7 +102,7 @@ export default class SpiritWorld {
|
|
|
99
102
|
|
|
100
103
|
// if the scope is local, the parent is the user's id
|
|
101
104
|
if (req.body.scope === "local") {
|
|
102
|
-
let user = await req.db.Spirit.recallOne("user", null, {
|
|
105
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
103
106
|
if (user?.memory?._id) parent = user.memory._id;
|
|
104
107
|
else {
|
|
105
108
|
fail(res, "User had no id on load()");
|
|
@@ -131,7 +134,7 @@ export default class SpiritWorld {
|
|
|
131
134
|
|
|
132
135
|
// if the scope is local, the parent is the user's id
|
|
133
136
|
if (req.body.scope === "local") {
|
|
134
|
-
let user = await req.db.Spirit.recallOne("user", null, {
|
|
137
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
135
138
|
if (user?.memory?._id) parent = user.memory._id;
|
|
136
139
|
else {
|
|
137
140
|
fail(res, "User had no id on load()");
|
|
@@ -161,7 +164,7 @@ export default class SpiritWorld {
|
|
|
161
164
|
let script, result = null;
|
|
162
165
|
|
|
163
166
|
if (fs.existsSync(scriptPath)) {
|
|
164
|
-
let user = await req.db.Spirit.recallOne("user", null, {
|
|
167
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
165
168
|
|
|
166
169
|
script = await import(scriptPath);
|
|
167
170
|
result = await script.default(req, user, this.io);
|
package/controllers/user.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import express from "express";
|
|
2
2
|
import bcrypt from "bcrypt";
|
|
3
|
-
import { check, success, fail, loginCheck } from "./util.js";
|
|
3
|
+
import { check, success, successJSON, fail, loginCheck } from "./util.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* API routes for user functions.
|
|
@@ -10,16 +10,16 @@ export default class User {
|
|
|
10
10
|
this.router = express.Router();
|
|
11
11
|
|
|
12
12
|
this.router.post("/logout", this.logout);
|
|
13
|
-
this.router.post("/sendPasswordReset", this.sendPasswordReset);
|
|
14
13
|
this.router.post("/changePassword", this.changePassword);
|
|
15
14
|
this.router.post("/register", this.register);
|
|
16
15
|
this.router.post("/login", this.login);
|
|
17
|
-
this.router.post("/changeEmail", this.changeEmail);
|
|
18
|
-
this.router.post("/changeUsername", this.changeUsername);
|
|
19
16
|
this.router.post("/deletePermanently", this.deletePermanently);
|
|
20
17
|
this.router.post("/getInfo", this.getInfo);
|
|
21
18
|
this.router.post("/getView", this.getView);
|
|
22
19
|
this.router.post("/setView", this.setView);
|
|
20
|
+
this.router.post("/downloadData", this.downloadData);
|
|
21
|
+
this.router.post("/deleteAlldata", this.deleteAlldata);
|
|
22
|
+
this.router.post("/importData", this.importData);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -33,57 +33,34 @@ export default class User {
|
|
|
33
33
|
success(res, "Logged out.");
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
/**
|
|
37
|
-
* Sends an email with a password reset code.
|
|
38
|
-
* @param {Object} req An Express.js request.
|
|
39
|
-
* @param {Object} res An Express.js response.
|
|
40
|
-
*/
|
|
41
|
-
sendPasswordReset = async (req, res) => {
|
|
42
|
-
let spirit = await req.db.Spirit.recallOne("user", null, { email: req.body.email });
|
|
43
|
-
|
|
44
|
-
if (spirit) {
|
|
45
|
-
let token = Math.floor(Math.random() * 9999);
|
|
46
|
-
|
|
47
|
-
spirit.memory.data.resetToken = token;
|
|
48
|
-
spirit.memory.data.resetExp = Date.now() + (1000 * 60 * 10);
|
|
49
|
-
await spirit.commit();
|
|
50
|
-
|
|
51
|
-
if (req.body.test) console.log("token: " + token);
|
|
52
|
-
else req.db.SendMail.passwordReset(req.body.email, token);
|
|
53
|
-
|
|
54
|
-
success(res, "Password reset token sent.");
|
|
55
|
-
}
|
|
56
|
-
else fail(res, "User not found.");
|
|
57
|
-
}
|
|
58
|
-
|
|
59
36
|
/**
|
|
60
37
|
* Change a user's password.
|
|
61
38
|
* @param {Object} req An Express.js request.
|
|
62
39
|
* @param {Object} res An Express.js response.
|
|
63
40
|
*/
|
|
64
41
|
changePassword = async (req, res) => {
|
|
65
|
-
if (
|
|
66
|
-
let spirit = await req.db.Spirit.recallOne("user", null, {
|
|
67
|
-
|
|
42
|
+
if (loginCheck(req, res)) {
|
|
43
|
+
let spirit = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
44
|
+
|
|
68
45
|
if (check(res, spirit, "User not found!") &&
|
|
69
|
-
check(res,
|
|
70
|
-
check(res,
|
|
71
|
-
check(res, req.body.password === req.body.confirmation, "Passwords must match!"))
|
|
46
|
+
check(res, req.body.newPassword === req.body.confirmation, "New password and confirmation must match!") &&
|
|
47
|
+
check(res, req.body.oldPassword != req.body.newPassword, "New password must be different from the old one."))
|
|
72
48
|
{
|
|
73
|
-
spirit.memory.data.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
49
|
+
let passResult = await bcrypt.compare(req.body.oldPassword, spirit.memory.data.password);
|
|
50
|
+
|
|
51
|
+
if (check(res, passResult, "Old password incorrect.")) {
|
|
52
|
+
const salt = await bcrypt.genSalt(10);
|
|
53
|
+
const hash = await bcrypt.hash(req.body.newPassword, salt);
|
|
54
|
+
|
|
55
|
+
spirit.addBackup({
|
|
56
|
+
...spirit.memory.data,
|
|
57
|
+
password: hash
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await spirit.commit();
|
|
61
|
+
|
|
62
|
+
success(res, "Password changed successfully!");
|
|
63
|
+
}
|
|
87
64
|
}
|
|
88
65
|
}
|
|
89
66
|
}
|
|
@@ -94,33 +71,20 @@ export default class User {
|
|
|
94
71
|
* @param {Object} res An Express.js response.
|
|
95
72
|
*/
|
|
96
73
|
register = async (req, res) => {
|
|
97
|
-
if (check(res, req.body.password.length >
|
|
98
|
-
check(res, req.body.email.length > 7, "Email too short.") &&
|
|
74
|
+
if (check(res, req.body.password.length > 10, "Password must be >10 characters long.") &&
|
|
99
75
|
check(res, req.body.username.length > 2, "Username too short."))
|
|
100
76
|
{
|
|
101
|
-
let spirit = await req.db.Spirit.recallOne("user", null, {
|
|
77
|
+
let spirit = await req.db.Spirit.recallOne("user", null, { username: req.body.username });
|
|
102
78
|
|
|
103
|
-
if (check(res, !spirit, "
|
|
79
|
+
if (check(res, !spirit, "Username already in use!")) {
|
|
104
80
|
const salt = await bcrypt.genSalt(10);
|
|
105
81
|
const hash = await bcrypt.hash(req.body.password, salt);
|
|
106
82
|
|
|
107
83
|
spirit = await req.db.Spirit.create("user", {
|
|
108
84
|
username: req.body.username,
|
|
109
|
-
email: req.body.email,
|
|
110
85
|
password: hash,
|
|
111
|
-
resetToken: null,
|
|
112
|
-
resetExp: null,
|
|
113
|
-
coin: 0,
|
|
114
|
-
home: "/",
|
|
115
86
|
authLevels: [ "Basic" ],
|
|
116
|
-
|
|
117
|
-
attributes: {
|
|
118
|
-
translation: 0,
|
|
119
|
-
strength: 0,
|
|
120
|
-
agility: 0,
|
|
121
|
-
defense: 0
|
|
122
|
-
},
|
|
123
|
-
inventory: []
|
|
87
|
+
view: "compact"
|
|
124
88
|
});
|
|
125
89
|
|
|
126
90
|
success(res, "Registration successful!");
|
|
@@ -134,61 +98,19 @@ export default class User {
|
|
|
134
98
|
* @param {Object} res An Express.js response.
|
|
135
99
|
*/
|
|
136
100
|
login = async (req, res) => {
|
|
137
|
-
let spirit = await req.db.Spirit.recallOne("user", null, {
|
|
101
|
+
let spirit = await req.db.Spirit.recallOne("user", null, { username: req.body.username });
|
|
138
102
|
|
|
139
103
|
if (check(res, spirit, "User not found.")) {
|
|
140
104
|
let passResult = await bcrypt.compare(req.body.password, spirit.memory.data.password);
|
|
141
105
|
|
|
142
|
-
if (check(res, passResult, "Password doesn't match the
|
|
143
|
-
req.session.currentUser = req.body.
|
|
144
|
-
|
|
106
|
+
if (check(res, passResult, "Password doesn't match the username.")) {
|
|
107
|
+
req.session.currentUser = req.body.username;
|
|
108
|
+
|
|
145
109
|
success(res, "Logged in.", spirit.memory.data.username);
|
|
146
110
|
}
|
|
147
111
|
}
|
|
148
112
|
}
|
|
149
113
|
|
|
150
|
-
/**
|
|
151
|
-
* Changes a user's email address on file.
|
|
152
|
-
* @param {Object} req An Express.js request.
|
|
153
|
-
* @param {Object} res An Express.js response.
|
|
154
|
-
*/
|
|
155
|
-
changeEmail = async (req, res) => {
|
|
156
|
-
if (loginCheck(req, res)) {
|
|
157
|
-
let spirit = await req.db.Spirit.recallOne("user", null, { email: req.body.email });
|
|
158
|
-
|
|
159
|
-
if (check(res, !spirit, "Email already in use!")) {
|
|
160
|
-
spirit = await req.db.Spirit.recallOne("user", null, { email: req.session.currentUser });
|
|
161
|
-
|
|
162
|
-
spirit.memory.data.email = req.body.email;
|
|
163
|
-
await spirit.commit();
|
|
164
|
-
|
|
165
|
-
req.session.currentUser = req.body.email;
|
|
166
|
-
|
|
167
|
-
success(res, "Email changed.");
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Changes a user's display name.
|
|
174
|
-
* @param {Object} req An Express.js request.
|
|
175
|
-
* @param {Object} res An Express.js response.
|
|
176
|
-
*/
|
|
177
|
-
changeUsername = async (req, res) => {
|
|
178
|
-
if (loginCheck(req, res)) {
|
|
179
|
-
let spirit = await req.db.Spirit.recallOne("user", null, { username: req.body.username });
|
|
180
|
-
|
|
181
|
-
if (check(res, !spirit, "Username already in use!")) {
|
|
182
|
-
spirit = await req.db.Spirit.recallOne("user", null, { email: req.session.currentUser });
|
|
183
|
-
|
|
184
|
-
spirit.memory.data.username = req.body.username;
|
|
185
|
-
await spirit.commit();
|
|
186
|
-
|
|
187
|
-
success(res, "Username changed");
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
114
|
/**
|
|
193
115
|
* Deletes a user account premanently.
|
|
194
116
|
* @param {Object} req An Express.js request.
|
|
@@ -196,12 +118,20 @@ export default class User {
|
|
|
196
118
|
*/
|
|
197
119
|
deletePermanently = async (req, res) => {
|
|
198
120
|
if (loginCheck(req, res)) {
|
|
199
|
-
let
|
|
200
|
-
|
|
201
|
-
if (check(res,
|
|
202
|
-
await req.
|
|
203
|
-
|
|
204
|
-
|
|
121
|
+
let spirit = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
122
|
+
|
|
123
|
+
if (check(res, spirit, "User not found.")) {
|
|
124
|
+
let passResult = await bcrypt.compare(req.body.password, spirit.memory.data.password);
|
|
125
|
+
|
|
126
|
+
if (check(res, passResult, "Password doesn't match the username.")) {
|
|
127
|
+
let deleted = await req.db.Spirit.delete("user", null, { username: req.session.currentUser });
|
|
128
|
+
|
|
129
|
+
if (check(res, deleted > 0, "No account deleted")) {
|
|
130
|
+
await req.session.destroy();
|
|
131
|
+
|
|
132
|
+
success(res, "Account deleted.");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
205
135
|
}
|
|
206
136
|
}
|
|
207
137
|
}
|
|
@@ -213,15 +143,12 @@ export default class User {
|
|
|
213
143
|
*/
|
|
214
144
|
getInfo = async (req, res) => {
|
|
215
145
|
if (loginCheck(req, res)) {
|
|
216
|
-
let user = await req.db.Spirit.recallOne("user", null, {
|
|
146
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
217
147
|
|
|
218
148
|
if (check(res, user, "Account not found!")) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
username: user.memory.data.username
|
|
223
|
-
});
|
|
224
|
-
}
|
|
149
|
+
success(res, "Info found", {
|
|
150
|
+
username: user.memory.data.username
|
|
151
|
+
});
|
|
225
152
|
}
|
|
226
153
|
}
|
|
227
154
|
}
|
|
@@ -231,7 +158,7 @@ export default class User {
|
|
|
231
158
|
*/
|
|
232
159
|
getView = async (req, res) => {
|
|
233
160
|
if (loginCheck(req, res)) {
|
|
234
|
-
let user = await req.db.Spirit.recallOne("user", null, {
|
|
161
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
235
162
|
|
|
236
163
|
if (check(res, user, "Account not found!")) {
|
|
237
164
|
success(res, "View found", user.memory.data.view);
|
|
@@ -244,14 +171,71 @@ export default class User {
|
|
|
244
171
|
*/
|
|
245
172
|
setView = async (req, res) => {
|
|
246
173
|
if (loginCheck(req, res)) {
|
|
247
|
-
let user = await req.db.Spirit.recallOne("user", null, {
|
|
174
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
248
175
|
|
|
249
176
|
if (check(res, user, "Account not found!")) {
|
|
250
|
-
user.memory.data.view = req.body.view;
|
|
177
|
+
user.memory.data.view = req.body.view == "compact" ? "compact" : "full";
|
|
251
178
|
await user.commit();
|
|
252
179
|
|
|
253
180
|
success(res, "View set");
|
|
254
181
|
}
|
|
255
182
|
}
|
|
256
183
|
}
|
|
184
|
+
|
|
185
|
+
//download all spirit data belonging to the user
|
|
186
|
+
downloadData = async (req, res) => {
|
|
187
|
+
if (loginCheck(req, res)) {
|
|
188
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
189
|
+
|
|
190
|
+
if (check(res, user, "Account not found!")) {
|
|
191
|
+
let data = await req.db.Spirit.recallAll(null, user.memory._id);
|
|
192
|
+
let dataToDownload = data.map(d => d.memory);
|
|
193
|
+
dataToDownload.unshift(user.memory.data);
|
|
194
|
+
|
|
195
|
+
successJSON(res, "Data Downloaded", dataToDownload);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
//delete all spirit data belonging to the user
|
|
201
|
+
deleteAlldata = async (req, res) => {
|
|
202
|
+
if (loginCheck(req, res)) {
|
|
203
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
204
|
+
|
|
205
|
+
if (check(res, user, "Account not found!")) {
|
|
206
|
+
let passResult = await bcrypt.compare(req.body.password, user.memory.data.password);
|
|
207
|
+
|
|
208
|
+
if (check(res, passResult, "Password doesn't match the username.")) {
|
|
209
|
+
let deleted = await req.db.Spirit.delete(null, user.memory._id);
|
|
210
|
+
if (check(res, deleted > 0, "No data deleted")) {
|
|
211
|
+
success(res, "Data Deleted", deleted);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// import spirit data from a JSON file
|
|
219
|
+
importData = async (req, res) => {
|
|
220
|
+
if (loginCheck(req, res)) {
|
|
221
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
222
|
+
|
|
223
|
+
if (check(res, user, "Account not found!")) {
|
|
224
|
+
let passResult = await bcrypt.compare(req.body.password, user.memory.data.password);
|
|
225
|
+
|
|
226
|
+
if (check(res, passResult, "Password doesn't match the username.")) {
|
|
227
|
+
let data = req.body.data;
|
|
228
|
+
let imported = 0;
|
|
229
|
+
for (let i = 0; i < data.length; i++) {
|
|
230
|
+
if (data[i].parent != null) {
|
|
231
|
+
let spirit = await req.db.Spirit.create(data[i].service, data[i].data, user.memory._id);
|
|
232
|
+
if (spirit) imported++;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
success(res, "Data Imported", imported);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
257
241
|
}
|
package/controllers/util.js
CHANGED
|
@@ -31,6 +31,15 @@ export const success = (res, msg = "Success!", data = null, lastUpdate = 0) => {
|
|
|
31
31
|
});
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
export const successJSON = (res, msg = "Success!", data = null, lastUpdate = 0) => {
|
|
35
|
+
res.json({
|
|
36
|
+
status: "success",
|
|
37
|
+
message: msg,
|
|
38
|
+
lastUpdate: lastUpdate,
|
|
39
|
+
data: data
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
34
43
|
/**
|
|
35
44
|
* Respond to the client with failure.
|
|
36
45
|
* @param {Object} res An Express.js response.
|
|
@@ -52,5 +61,5 @@ export const fail = (res, msg = "Failed!") => {
|
|
|
52
61
|
* @returns True if a user is logged in, else false.
|
|
53
62
|
*/
|
|
54
63
|
export const loginCheck = (req, res) => {
|
|
55
|
-
return check(res, req.session
|
|
64
|
+
return check(res, req.session?.currentUser, "Please login first.");
|
|
56
65
|
}
|
package/models/spirit.js
CHANGED
|
@@ -27,10 +27,10 @@ export default class Spirit {
|
|
|
27
27
|
*/
|
|
28
28
|
static buildQuery = (service, data = null, parent = null, id = null) => {
|
|
29
29
|
let query = {
|
|
30
|
-
service: service,
|
|
31
30
|
parent: parent
|
|
32
31
|
};
|
|
33
32
|
|
|
33
|
+
if (service) query.service = service;
|
|
34
34
|
if (id) query._id = id;
|
|
35
35
|
else if (data){
|
|
36
36
|
let keys = Object.keys(data);
|
package/notherbase-fs.js
CHANGED
|
@@ -3,72 +3,85 @@ dotenv.config();
|
|
|
3
3
|
import Models from "./models/index.js";
|
|
4
4
|
import { Server } from "socket.io";
|
|
5
5
|
import express from "express";
|
|
6
|
-
import session from 'express-session';
|
|
7
|
-
import methodOverride from 'method-override';
|
|
8
|
-
import MongoStore from 'connect-mongo';
|
|
9
|
-
import favicon from 'serve-favicon';
|
|
10
6
|
import http from 'http';
|
|
11
7
|
import { fileURLToPath } from 'node:url';
|
|
12
8
|
const __dirname = fileURLToPath(new URL('./', import.meta.url));
|
|
13
9
|
import Creation from "./controllers/creation.js";
|
|
14
10
|
import SpiritWorld from "./controllers/spirit-world.js";
|
|
11
|
+
import favicon from 'serve-favicon';
|
|
12
|
+
import session from 'express-session';
|
|
13
|
+
import MongoStore from 'connect-mongo';
|
|
14
|
+
import { log } from "console";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* The engine that runs a nother base.
|
|
18
18
|
*/
|
|
19
19
|
class NotherBaseFS {
|
|
20
|
-
constructor(
|
|
21
|
-
this.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
constructor(globals = {}, bases = {}) {
|
|
21
|
+
this.bases = bases;
|
|
22
|
+
let baseKeys = Object.keys(this.bases);
|
|
23
|
+
for (let i = 0; i < baseKeys.length; i++) {
|
|
24
|
+
this.bases[baseKeys[i]].static = express.static(this.bases[baseKeys[i]].directory + "/public");
|
|
25
|
+
this.bases[baseKeys[i]].favicon = favicon(this.bases[baseKeys[i]].directory + this.bases[baseKeys[i]].icon);
|
|
26
|
+
this.bases[baseKeys[i]].session = session({
|
|
27
|
+
store: MongoStore.create({ mongoUrl: process.env.MONGODB_URI }),
|
|
28
|
+
secret: process.env.SECRET,
|
|
29
|
+
name: baseKeys[i] + '-session-id',
|
|
30
|
+
resave: false,
|
|
31
|
+
saveUninitialized: false,
|
|
32
|
+
cookie: {
|
|
33
|
+
secure: process.env.PRODUCTION == "true",
|
|
34
|
+
maxAge: 1000 * 60 * 60 * 24 * 28 // 28 days
|
|
35
|
+
}
|
|
36
|
+
});
|
|
25
37
|
}
|
|
38
|
+
|
|
26
39
|
this.app = express();
|
|
27
40
|
this.server = http.createServer(this.app);
|
|
28
41
|
this.io = new Server(this.server);
|
|
29
|
-
this.creation = new Creation(this.settings.siteTitle);
|
|
30
42
|
this.spiritWorld = new SpiritWorld(this.io);
|
|
43
|
+
this.creation = new Creation(bases);
|
|
31
44
|
|
|
32
45
|
//set views path
|
|
33
46
|
this.app.set("view engine", "ejs");
|
|
34
47
|
this.app.set("views", `${__dirname}/views`);
|
|
35
48
|
|
|
36
|
-
// allows us to delete
|
|
37
|
-
this.app.use(methodOverride('_method'));
|
|
38
|
-
|
|
39
49
|
// allows us to use post body data
|
|
40
50
|
this.app.use(express.json({
|
|
41
51
|
extended: true,
|
|
42
52
|
inflate: true,
|
|
43
53
|
type: 'application/x-www-form-urlencoded'
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
//provide database access and etc to use in routes
|
|
57
|
+
this.app.use((req, res, next) => {
|
|
58
|
+
req.hosting = req.hostname.split(".")[0];
|
|
59
|
+
req.contentPath = this.bases[req.hosting].directory;
|
|
60
|
+
next();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.app.use((req, res, next) => {
|
|
64
|
+
this.bases[req.hosting].favicon(req, res, next);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
//enable cookies
|
|
68
|
+
this.app.use((req, res, next) => {
|
|
69
|
+
this.bases[req.hosting].session(req, res, next);
|
|
70
|
+
});
|
|
71
|
+
|
|
47
72
|
// allows us to get static files like css
|
|
48
73
|
this.app.use(express.static('public'));
|
|
49
|
-
this.app.use(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (this.settings.favicon) this.app.use(favicon(this.settings.favicon));
|
|
53
|
-
else this.app.use(favicon(__dirname + '/public/img/logo.png'));
|
|
74
|
+
this.app.use((req, res, next) => {
|
|
75
|
+
this.bases[req.hosting].static(req, res, next);
|
|
76
|
+
});
|
|
54
77
|
|
|
55
|
-
//
|
|
56
|
-
this.app.
|
|
57
|
-
store: MongoStore.create({ mongoUrl: process.env.MONGODB_URI }),
|
|
58
|
-
secret: process.env.SECRET,
|
|
59
|
-
resave: false,
|
|
60
|
-
saveUninitialized: false,
|
|
61
|
-
cookie: {
|
|
62
|
-
secure: process.env.PRODUCTION === "true",
|
|
63
|
-
maxAge: 1000 * 60 * 60 * 24 * 28 // 28 days
|
|
64
|
-
}
|
|
65
|
-
}));
|
|
78
|
+
//be safe
|
|
79
|
+
if (process.env.PRODUCTION == "true") this.app.set('trust proxy', 1);
|
|
66
80
|
|
|
67
81
|
//provide database access and etc to use in routes
|
|
68
82
|
this.app.use((req, res, next) => {
|
|
69
83
|
req.globals = globals;
|
|
70
84
|
req.db = Models;
|
|
71
|
-
req.contentPath = contentPath;
|
|
72
85
|
req.lock = false;
|
|
73
86
|
next();
|
|
74
87
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "notherbase-fs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Functions to help make developing for NotherBase easier.",
|
|
5
5
|
"exports": "./notherbase-fs.js",
|
|
6
6
|
"scripts": {
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"ejs": "^3.1.6",
|
|
26
26
|
"express": "^4.17.1",
|
|
27
27
|
"express-session": "^1.17.2",
|
|
28
|
+
"express-subdomain": "^1.0.6",
|
|
28
29
|
"googleapis": "^100.0.0",
|
|
29
|
-
"method-override": "^3.0.0",
|
|
30
30
|
"mongoose": "^6.1.7",
|
|
31
31
|
"nodemailer": "^6.9.14",
|
|
32
32
|
"serve-favicon": "^2.5.0",
|