notherbase-fs 4.0.21 → 4.0.23
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/README.md +6 -6
- package/controllers/creation.js +147 -147
- package/controllers/spirit-world.js +174 -174
- package/controllers/user.js +240 -240
- package/controllers/util.js +64 -64
- package/models/index.js +33 -33
- package/models/send-mail.js +58 -58
- package/models/spirit.js +234 -234
- package/notherbase-fs.js +112 -111
- package/package.json +40 -40
- package/public/js/base.js +222 -227
- package/public/js/chat-box.js +120 -120
- package/test/coast/tall-beach/nono-cove/index.css +17 -17
- package/test/coast/tall-beach/nono-cove/index.ejs +29 -29
- package/test/coast/tall-beach/nono-cove/nono-og/add-gold.js +15 -15
- package/test/coast/tall-beach/nono-cove/nono-og/index.ejs +46 -46
- package/test/coast/tall-beach/nono-cove/nono-og/nono.css +88 -88
- package/test/coast/tall-beach/nono-cove/nono-og/nono.js +207 -207
- package/test/pages/test-page/emailTime.js +8 -8
- package/test/pages/test-page/index.ejs +104 -104
- package/test/pages/void/index.ejs +35 -35
- package/test/pages/void/void.css +2 -2
- package/test/public/styles/main.css +792 -792
- package/test/the-front/add-gold.js +13 -13
- package/test/the-front/check/check.css +2 -2
- package/test/the-front/check/emailTime.js +9 -9
- package/test/the-front/check/flip.js +9 -9
- package/test/the-front/check/index.ejs +54 -54
- package/test/the-front/check/save-input.js +7 -7
- package/test/the-front/index.ejs +116 -99
- package/test/the-front/keeper/clipboards.js +133 -133
- package/test/the-front/keeper/index.ejs +80 -80
- package/test/the-front/keeper/keeper.css +157 -157
- package/test/the-front/keeper/keeper.js +140 -140
- package/test-index.js +19 -19
- package/test2/pages/test-page/emailTime.js +8 -8
- package/test2/pages/test-page/index.ejs +104 -104
- package/test2/pages/void/index.ejs +35 -35
- package/test2/pages/void/void.css +2 -2
- package/test2/public/styles/main.css +792 -792
- package/test2/the-front/add-gold.js +13 -13
- package/test2/the-front/check/check.css +2 -2
- package/test2/the-front/check/emailTime.js +9 -9
- package/test2/the-front/check/flip.js +9 -9
- package/test2/the-front/check/index.ejs +54 -54
- package/test2/the-front/check/save-input.js +7 -7
- package/test2/the-front/index.ejs +99 -99
- package/test2/the-front/keeper/clipboards.js +133 -133
- package/test2/the-front/keeper/index.ejs +80 -80
- package/test2/the-front/keeper/keeper.css +157 -157
- package/test2/the-front/keeper/keeper.js +140 -140
- package/views/explorer.ejs +82 -82
- package/views/footer.ejs +9 -9
- package/views/head.ejs +17 -17
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# notherbase-fs
|
|
2
|
-
A package to help one develop a base.
|
|
3
|
-
|
|
4
|
-
A base is an Express.js server that will render EJS web pages with automatic route creation. It also has a spirit world, a MongoDB-connected API to provide those pages with dynamic data and multiplayer interaction. A little bit of socket.io is sprinkled for good measure.
|
|
5
|
-
|
|
6
|
-
Visit www.notherbase.com/docs for documentation on notherbase-fs.
|
|
1
|
+
# notherbase-fs
|
|
2
|
+
A package to help one develop a base.
|
|
3
|
+
|
|
4
|
+
A base is an Express.js server that will render EJS web pages with automatic route creation. It also has a spirit world, a MongoDB-connected API to provide those pages with dynamic data and multiplayer interaction. A little bit of socket.io is sprinkled for good measure.
|
|
5
|
+
|
|
6
|
+
Visit www.notherbase.com/docs for documentation on notherbase-fs.
|
package/controllers/creation.js
CHANGED
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
import express from "express";
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Creation is all the renedered pages in a base.
|
|
6
|
-
*/
|
|
7
|
-
export default class Creation {
|
|
8
|
-
constructor(bases = {}) {
|
|
9
|
-
this.bases = bases;
|
|
10
|
-
this.router = express.Router();
|
|
11
|
-
|
|
12
|
-
//home
|
|
13
|
-
this.router.get("/", this.front, this.explore);
|
|
14
|
-
|
|
15
|
-
//the-front
|
|
16
|
-
this.router.get(`/the-front`, this.front, this.explore);
|
|
17
|
-
this.router.get(`/the-front/:frontDetail`, this.frontDetail, this.explore);
|
|
18
|
-
|
|
19
|
-
//pages
|
|
20
|
-
this.router.get(`/:page`, this.page, this.explore);
|
|
21
|
-
|
|
22
|
-
//the-front optional shortcuts
|
|
23
|
-
this.router.get(`/:frontDetail`, this.frontDetail, this.explore);
|
|
24
|
-
|
|
25
|
-
//explorer
|
|
26
|
-
this.router.get(`/:region/:area/:poi`, this.lock, this.poi, this.explore);
|
|
27
|
-
this.router.get(`/:region/:area/:poi/:detail`, this.lock, this.detail, this.explore);
|
|
28
|
-
|
|
29
|
-
//void
|
|
30
|
-
this.router.use(function(req, res) {
|
|
31
|
-
res.redirect("/void");
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* This middleware requires a user to login to access affected routes.
|
|
37
|
-
* @param {Object} req An Express.js request.
|
|
38
|
-
* @param {Object} res An Express.js response.
|
|
39
|
-
* @param {Function} next next()
|
|
40
|
-
*/
|
|
41
|
-
lock = (req, res, next) => {
|
|
42
|
-
req.lock = true;
|
|
43
|
-
next();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* This route renders a page and sends it to the client.
|
|
48
|
-
* @param {Object} req An Express.js request.
|
|
49
|
-
* @param {Object} res An Express.js response.
|
|
50
|
-
* @param {Function} next next()
|
|
51
|
-
*/
|
|
52
|
-
explore = async (req, res, next) => {
|
|
53
|
-
try {
|
|
54
|
-
if (fs.existsSync(req.main + ".ejs")) {
|
|
55
|
-
let stats = await req.db.Spirit.recallOrCreateOne("stats", null, { route: req.path });
|
|
56
|
-
if (stats.memory.data.visits) stats.memory.data.visits++;
|
|
57
|
-
else stats.memory.data.visits = 1;
|
|
58
|
-
await stats.commit();
|
|
59
|
-
|
|
60
|
-
let context = {
|
|
61
|
-
userID: null,
|
|
62
|
-
user: null,
|
|
63
|
-
siteTitle: req.siteTitle,
|
|
64
|
-
main: req.main,
|
|
65
|
-
query: req.query,
|
|
66
|
-
route: req.path,
|
|
67
|
-
requireUser: req.lock
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (req.session.currentUser) {
|
|
71
|
-
context.user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
res.render(req.toRender, context);
|
|
75
|
-
}
|
|
76
|
-
else next();
|
|
77
|
-
}
|
|
78
|
-
catch(err) {
|
|
79
|
-
console.log(err);
|
|
80
|
-
res.status(500).send("Server Error");
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* This middleware directs exploration to the front.
|
|
86
|
-
* @param {Object} req An Express.js request.
|
|
87
|
-
* @param {Object} res An Express.js response.
|
|
88
|
-
* @param {Function} next next()
|
|
89
|
-
*/
|
|
90
|
-
front = async (req, res, next) => {
|
|
91
|
-
req.main = req.contentPath + "/the-front/index";
|
|
92
|
-
req.siteTitle = this.bases[req.hosting].title;
|
|
93
|
-
req.toRender = "explorer";
|
|
94
|
-
next();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* This middleware directs exploration to a detail in the front.
|
|
99
|
-
* @param {Object} req An Express.js request.
|
|
100
|
-
* @param {Object} res An Express.js response.
|
|
101
|
-
* @param {Function} next next()
|
|
102
|
-
*/
|
|
103
|
-
frontDetail = async (req, res, next) => {
|
|
104
|
-
req.main = `${req.contentPath}/the-front/${req.params.frontDetail}/index`;
|
|
105
|
-
req.siteTitle = `${this.bases[req.hosting].title} - ${req.params.frontDetail}`;
|
|
106
|
-
req.toRender = "explorer";
|
|
107
|
-
next();
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* This middleware directs exploration to a point of interest.
|
|
112
|
-
* @param {Object} req An Express.js request.
|
|
113
|
-
* @param {Object} res An Express.js response.
|
|
114
|
-
* @param {Function} next next()
|
|
115
|
-
*/
|
|
116
|
-
poi = async (req, res, next) => {
|
|
117
|
-
req.main = `${req.contentPath}/${req.params.region}/${req.params.area}/${req.params.poi}/index`;
|
|
118
|
-
req.siteTitle = `${this.bases[req.hosting].title} - ${req.params.poi}`;
|
|
119
|
-
req.toRender = "explorer";
|
|
120
|
-
next();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* This middleware directs exploration to a detail.
|
|
125
|
-
* @param {Object} req An Express.js request.
|
|
126
|
-
* @param {Object} res An Express.js response.
|
|
127
|
-
* @param {Function} next next()
|
|
128
|
-
*/
|
|
129
|
-
detail = async (req, res, next) => {
|
|
130
|
-
req.main = `${req.contentPath}/${req.params.region}/${req.params.area}/${req.params.poi}/${req.params.detail}/index`;
|
|
131
|
-
req.siteTitle = `${this.bases[req.hosting].title} - ${req.params.detail}`;
|
|
132
|
-
req.toRender = "explorer";
|
|
133
|
-
next();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* This middleware directs exploration to a one-off page.
|
|
138
|
-
* @param {Object} req An Express.js request.
|
|
139
|
-
* @param {Object} res An Express.js response.
|
|
140
|
-
* @param {Function} next next()
|
|
141
|
-
*/
|
|
142
|
-
page = async (req, res, next) => {
|
|
143
|
-
req.main = `${req.contentPath}/pages/${req.params.page}/index`;
|
|
144
|
-
req.siteTitle = `${req.params.page}`;
|
|
145
|
-
req.toRender = req.main;
|
|
146
|
-
next();
|
|
147
|
-
}
|
|
1
|
+
import express from "express";
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creation is all the renedered pages in a base.
|
|
6
|
+
*/
|
|
7
|
+
export default class Creation {
|
|
8
|
+
constructor(bases = {}) {
|
|
9
|
+
this.bases = bases;
|
|
10
|
+
this.router = express.Router();
|
|
11
|
+
|
|
12
|
+
//home
|
|
13
|
+
this.router.get("/", this.front, this.explore);
|
|
14
|
+
|
|
15
|
+
//the-front
|
|
16
|
+
this.router.get(`/the-front`, this.front, this.explore);
|
|
17
|
+
this.router.get(`/the-front/:frontDetail`, this.frontDetail, this.explore);
|
|
18
|
+
|
|
19
|
+
//pages
|
|
20
|
+
this.router.get(`/:page`, this.page, this.explore);
|
|
21
|
+
|
|
22
|
+
//the-front optional shortcuts
|
|
23
|
+
this.router.get(`/:frontDetail`, this.frontDetail, this.explore);
|
|
24
|
+
|
|
25
|
+
//explorer
|
|
26
|
+
this.router.get(`/:region/:area/:poi`, this.lock, this.poi, this.explore);
|
|
27
|
+
this.router.get(`/:region/:area/:poi/:detail`, this.lock, this.detail, this.explore);
|
|
28
|
+
|
|
29
|
+
//void
|
|
30
|
+
this.router.use(function(req, res) {
|
|
31
|
+
res.redirect("/void");
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* This middleware requires a user to login to access affected routes.
|
|
37
|
+
* @param {Object} req An Express.js request.
|
|
38
|
+
* @param {Object} res An Express.js response.
|
|
39
|
+
* @param {Function} next next()
|
|
40
|
+
*/
|
|
41
|
+
lock = (req, res, next) => {
|
|
42
|
+
req.lock = true;
|
|
43
|
+
next();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* This route renders a page and sends it to the client.
|
|
48
|
+
* @param {Object} req An Express.js request.
|
|
49
|
+
* @param {Object} res An Express.js response.
|
|
50
|
+
* @param {Function} next next()
|
|
51
|
+
*/
|
|
52
|
+
explore = async (req, res, next) => {
|
|
53
|
+
try {
|
|
54
|
+
if (fs.existsSync(req.main + ".ejs")) {
|
|
55
|
+
let stats = await req.db.Spirit.recallOrCreateOne("stats", null, { route: req.path });
|
|
56
|
+
if (stats.memory.data.visits) stats.memory.data.visits++;
|
|
57
|
+
else stats.memory.data.visits = 1;
|
|
58
|
+
await stats.commit();
|
|
59
|
+
|
|
60
|
+
let context = {
|
|
61
|
+
userID: null,
|
|
62
|
+
user: null,
|
|
63
|
+
siteTitle: req.siteTitle,
|
|
64
|
+
main: req.main,
|
|
65
|
+
query: req.query,
|
|
66
|
+
route: req.path,
|
|
67
|
+
requireUser: req.lock
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (req.session.currentUser) {
|
|
71
|
+
context.user = await req.db.Spirit.recallOne("user", null, { username: req.session.currentUser });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
res.render(req.toRender, context);
|
|
75
|
+
}
|
|
76
|
+
else next();
|
|
77
|
+
}
|
|
78
|
+
catch(err) {
|
|
79
|
+
console.log(err);
|
|
80
|
+
res.status(500).send("Server Error");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* This middleware directs exploration to the front.
|
|
86
|
+
* @param {Object} req An Express.js request.
|
|
87
|
+
* @param {Object} res An Express.js response.
|
|
88
|
+
* @param {Function} next next()
|
|
89
|
+
*/
|
|
90
|
+
front = async (req, res, next) => {
|
|
91
|
+
req.main = req.contentPath + "/the-front/index";
|
|
92
|
+
req.siteTitle = this.bases[req.hosting].title;
|
|
93
|
+
req.toRender = "explorer";
|
|
94
|
+
next();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* This middleware directs exploration to a detail in the front.
|
|
99
|
+
* @param {Object} req An Express.js request.
|
|
100
|
+
* @param {Object} res An Express.js response.
|
|
101
|
+
* @param {Function} next next()
|
|
102
|
+
*/
|
|
103
|
+
frontDetail = async (req, res, next) => {
|
|
104
|
+
req.main = `${req.contentPath}/the-front/${req.params.frontDetail}/index`;
|
|
105
|
+
req.siteTitle = `${this.bases[req.hosting].title} - ${req.params.frontDetail}`;
|
|
106
|
+
req.toRender = "explorer";
|
|
107
|
+
next();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* This middleware directs exploration to a point of interest.
|
|
112
|
+
* @param {Object} req An Express.js request.
|
|
113
|
+
* @param {Object} res An Express.js response.
|
|
114
|
+
* @param {Function} next next()
|
|
115
|
+
*/
|
|
116
|
+
poi = async (req, res, next) => {
|
|
117
|
+
req.main = `${req.contentPath}/${req.params.region}/${req.params.area}/${req.params.poi}/index`;
|
|
118
|
+
req.siteTitle = `${this.bases[req.hosting].title} - ${req.params.poi}`;
|
|
119
|
+
req.toRender = "explorer";
|
|
120
|
+
next();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* This middleware directs exploration to a detail.
|
|
125
|
+
* @param {Object} req An Express.js request.
|
|
126
|
+
* @param {Object} res An Express.js response.
|
|
127
|
+
* @param {Function} next next()
|
|
128
|
+
*/
|
|
129
|
+
detail = async (req, res, next) => {
|
|
130
|
+
req.main = `${req.contentPath}/${req.params.region}/${req.params.area}/${req.params.poi}/${req.params.detail}/index`;
|
|
131
|
+
req.siteTitle = `${this.bases[req.hosting].title} - ${req.params.detail}`;
|
|
132
|
+
req.toRender = "explorer";
|
|
133
|
+
next();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* This middleware directs exploration to a one-off page.
|
|
138
|
+
* @param {Object} req An Express.js request.
|
|
139
|
+
* @param {Object} res An Express.js response.
|
|
140
|
+
* @param {Function} next next()
|
|
141
|
+
*/
|
|
142
|
+
page = async (req, res, next) => {
|
|
143
|
+
req.main = `${req.contentPath}/pages/${req.params.page}/index`;
|
|
144
|
+
req.siteTitle = `${req.params.page}`;
|
|
145
|
+
req.toRender = req.main;
|
|
146
|
+
next();
|
|
147
|
+
}
|
|
148
148
|
}
|
|
@@ -1,175 +1,175 @@
|
|
|
1
|
-
import express from "express";
|
|
2
|
-
import { stripHtml } from "string-strip-html";
|
|
3
|
-
import { success, fail } from "./util.js";
|
|
4
|
-
import User from "./user.js";
|
|
5
|
-
import fs from 'fs';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* The spirit world is the API of a base.
|
|
9
|
-
*/
|
|
10
|
-
export default class SpiritWorld {
|
|
11
|
-
/**
|
|
12
|
-
* Sets up the spirit world.
|
|
13
|
-
* @param {Server} io
|
|
14
|
-
*/
|
|
15
|
-
constructor(io) {
|
|
16
|
-
this.io = io;
|
|
17
|
-
this.rooms = {};
|
|
18
|
-
this.io.on('connection', this.setupChat);
|
|
19
|
-
|
|
20
|
-
this.user = new User();
|
|
21
|
-
this.router = express.Router();
|
|
22
|
-
this.router.post("/loadAll", this.loadAll);
|
|
23
|
-
this.router.post("/load", this.load);
|
|
24
|
-
this.router.post("/serve", this.serve);
|
|
25
|
-
this.router.use("/user", this.user.router);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Sets up socket.io for instant messaging and etc.
|
|
30
|
-
* @param {*} socket
|
|
31
|
-
*/
|
|
32
|
-
setupChat = (socket) => {
|
|
33
|
-
let roomName = socket.handshake.query.room;
|
|
34
|
-
socket.join(roomName);
|
|
35
|
-
let room = this.rooms[roomName];
|
|
36
|
-
if (room) room.users.push(socket.handshake.query.name);
|
|
37
|
-
else {
|
|
38
|
-
this.rooms[roomName] = {
|
|
39
|
-
users: [ socket.handshake.query.name ]
|
|
40
|
-
}
|
|
41
|
-
room = this.rooms[roomName];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
this.io.to(roomName).emit("chat message", {
|
|
45
|
-
name: "Server",
|
|
46
|
-
time: Date.now(),
|
|
47
|
-
text: `${socket.handshake.query.name} has joined the room.`
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
this.io.to(roomName).emit("chat info", {
|
|
51
|
-
name: socket.handshake.query.room,
|
|
52
|
-
time: Date.now(),
|
|
53
|
-
data: {
|
|
54
|
-
users: room.users
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
socket.on("chat message", (msg) => {
|
|
59
|
-
this.io.to(roomName).emit("chat message", {
|
|
60
|
-
name: msg.name,
|
|
61
|
-
time: msg.time,
|
|
62
|
-
text: stripHtml(msg.text).result
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
socket.on('disconnect', () => {
|
|
67
|
-
room.users.splice(room.users.indexOf(socket.handshake.query.name));
|
|
68
|
-
|
|
69
|
-
this.io.to(roomName).emit("chat message", {
|
|
70
|
-
name: "Server",
|
|
71
|
-
time: Date.now(),
|
|
72
|
-
text: `${socket.handshake.query.name} has left the room.`
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
this.io.to(roomName).emit("chat info", {
|
|
76
|
-
name: socket.handshake.query.room,
|
|
77
|
-
time: Date.now(),
|
|
78
|
-
data: {
|
|
79
|
-
users: room.users
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
if (room.users.length < 1) delete this.rooms[roomName];
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* This API route requests all spirits of a kind from the database.
|
|
89
|
-
* @param {Object} req
|
|
90
|
-
* @param {Object} res
|
|
91
|
-
* @returns {Object} The requested spirits.
|
|
92
|
-
*/
|
|
93
|
-
loadAll = async (req, res) => {
|
|
94
|
-
try {
|
|
95
|
-
let parent = null;
|
|
96
|
-
let data = req.body.data ? req.body.data : {};
|
|
97
|
-
let id = req.body.id ? req.body.id : null;
|
|
98
|
-
|
|
99
|
-
// if the scope is local, the parent is the user's id
|
|
100
|
-
if (req.body.scope === "local") {
|
|
101
|
-
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
102
|
-
if (user?.memory?._id) parent = user.memory._id;
|
|
103
|
-
else {
|
|
104
|
-
fail(res, "User had no id on load()");
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// recall all spirits with the given service name and parent
|
|
110
|
-
let spirits = await req.db.Spirit.recallAll(req.body.service, parent, data, id);
|
|
111
|
-
|
|
112
|
-
res.send(spirits);
|
|
113
|
-
} catch (error) {
|
|
114
|
-
console.log(error);
|
|
115
|
-
fail(res, "Server error");
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* This API route requests a spirit of a kind from the database.
|
|
121
|
-
* @param {Object} req
|
|
122
|
-
* @param {Object} res
|
|
123
|
-
* @returns {Object} The requested spirit.
|
|
124
|
-
*/
|
|
125
|
-
load = async (req, res) => {
|
|
126
|
-
try {
|
|
127
|
-
let parent = null;
|
|
128
|
-
let data = req.body.data ? req.body.data : {};
|
|
129
|
-
let id = req.body.id ? req.body.id : null;
|
|
130
|
-
|
|
131
|
-
// if the scope is local, the parent is the user's id
|
|
132
|
-
if (req.body.scope === "local") {
|
|
133
|
-
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
134
|
-
if (user?.memory?._id) parent = user.memory._id;
|
|
135
|
-
else {
|
|
136
|
-
fail(res, "User had no id on load()");
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// recall all spirits with the given service name and parent
|
|
142
|
-
let spirit = await req.db.Spirit.recallOne(req.body.service, parent, data, id);
|
|
143
|
-
|
|
144
|
-
res.send(spirit);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
console.log(error);
|
|
147
|
-
fail(res, "Server error");
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* This API route runs a script on the server. Responds with the result.
|
|
153
|
-
* @param {Object} req
|
|
154
|
-
* @param {Object} res
|
|
155
|
-
*/
|
|
156
|
-
serve = async (req, res) => {
|
|
157
|
-
try {
|
|
158
|
-
let scriptPath = `${req.contentPath}${req.body.route}/${req.body.script}.js`;
|
|
159
|
-
|
|
160
|
-
let script, result = null;
|
|
161
|
-
|
|
162
|
-
if (fs.existsSync(scriptPath)) {
|
|
163
|
-
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
164
|
-
|
|
165
|
-
script = await import(scriptPath);
|
|
166
|
-
result = await script.default(req, user, this.io);
|
|
167
|
-
success(res, "Served.", result);
|
|
168
|
-
}
|
|
169
|
-
else fail(res, `Script not found: ${req.body.script} at ${scriptPath}`);
|
|
170
|
-
} catch (error) {
|
|
171
|
-
console.log(error);
|
|
172
|
-
fail(res, "Server error");
|
|
173
|
-
}
|
|
174
|
-
}
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { stripHtml } from "string-strip-html";
|
|
3
|
+
import { success, fail } from "./util.js";
|
|
4
|
+
import User from "./user.js";
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The spirit world is the API of a base.
|
|
9
|
+
*/
|
|
10
|
+
export default class SpiritWorld {
|
|
11
|
+
/**
|
|
12
|
+
* Sets up the spirit world.
|
|
13
|
+
* @param {Server} io
|
|
14
|
+
*/
|
|
15
|
+
constructor(io) {
|
|
16
|
+
this.io = io;
|
|
17
|
+
this.rooms = {};
|
|
18
|
+
this.io.on('connection', this.setupChat);
|
|
19
|
+
|
|
20
|
+
this.user = new User();
|
|
21
|
+
this.router = express.Router();
|
|
22
|
+
this.router.post("/loadAll", this.loadAll);
|
|
23
|
+
this.router.post("/load", this.load);
|
|
24
|
+
this.router.post("/serve", this.serve);
|
|
25
|
+
this.router.use("/user", this.user.router);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Sets up socket.io for instant messaging and etc.
|
|
30
|
+
* @param {*} socket
|
|
31
|
+
*/
|
|
32
|
+
setupChat = (socket) => {
|
|
33
|
+
let roomName = socket.handshake.query.room;
|
|
34
|
+
socket.join(roomName);
|
|
35
|
+
let room = this.rooms[roomName];
|
|
36
|
+
if (room) room.users.push(socket.handshake.query.name);
|
|
37
|
+
else {
|
|
38
|
+
this.rooms[roomName] = {
|
|
39
|
+
users: [ socket.handshake.query.name ]
|
|
40
|
+
}
|
|
41
|
+
room = this.rooms[roomName];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.io.to(roomName).emit("chat message", {
|
|
45
|
+
name: "Server",
|
|
46
|
+
time: Date.now(),
|
|
47
|
+
text: `${socket.handshake.query.name} has joined the room.`
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
this.io.to(roomName).emit("chat info", {
|
|
51
|
+
name: socket.handshake.query.room,
|
|
52
|
+
time: Date.now(),
|
|
53
|
+
data: {
|
|
54
|
+
users: room.users
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
socket.on("chat message", (msg) => {
|
|
59
|
+
this.io.to(roomName).emit("chat message", {
|
|
60
|
+
name: msg.name,
|
|
61
|
+
time: msg.time,
|
|
62
|
+
text: stripHtml(msg.text).result
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
socket.on('disconnect', () => {
|
|
67
|
+
room.users.splice(room.users.indexOf(socket.handshake.query.name));
|
|
68
|
+
|
|
69
|
+
this.io.to(roomName).emit("chat message", {
|
|
70
|
+
name: "Server",
|
|
71
|
+
time: Date.now(),
|
|
72
|
+
text: `${socket.handshake.query.name} has left the room.`
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
this.io.to(roomName).emit("chat info", {
|
|
76
|
+
name: socket.handshake.query.room,
|
|
77
|
+
time: Date.now(),
|
|
78
|
+
data: {
|
|
79
|
+
users: room.users
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (room.users.length < 1) delete this.rooms[roomName];
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* This API route requests all spirits of a kind from the database.
|
|
89
|
+
* @param {Object} req
|
|
90
|
+
* @param {Object} res
|
|
91
|
+
* @returns {Object} The requested spirits.
|
|
92
|
+
*/
|
|
93
|
+
loadAll = async (req, res) => {
|
|
94
|
+
try {
|
|
95
|
+
let parent = null;
|
|
96
|
+
let data = req.body.data ? req.body.data : {};
|
|
97
|
+
let id = req.body.id ? req.body.id : null;
|
|
98
|
+
|
|
99
|
+
// if the scope is local, the parent is the user's id
|
|
100
|
+
if (req.body.scope === "local") {
|
|
101
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
102
|
+
if (user?.memory?._id) parent = user.memory._id;
|
|
103
|
+
else {
|
|
104
|
+
fail(res, "User had no id on load()");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// recall all spirits with the given service name and parent
|
|
110
|
+
let spirits = await req.db.Spirit.recallAll(req.body.service, parent, data, id);
|
|
111
|
+
|
|
112
|
+
res.send(spirits);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.log(error);
|
|
115
|
+
fail(res, "Server error");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* This API route requests a spirit of a kind from the database.
|
|
121
|
+
* @param {Object} req
|
|
122
|
+
* @param {Object} res
|
|
123
|
+
* @returns {Object} The requested spirit.
|
|
124
|
+
*/
|
|
125
|
+
load = async (req, res) => {
|
|
126
|
+
try {
|
|
127
|
+
let parent = null;
|
|
128
|
+
let data = req.body.data ? req.body.data : {};
|
|
129
|
+
let id = req.body.id ? req.body.id : null;
|
|
130
|
+
|
|
131
|
+
// if the scope is local, the parent is the user's id
|
|
132
|
+
if (req.body.scope === "local") {
|
|
133
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
134
|
+
if (user?.memory?._id) parent = user.memory._id;
|
|
135
|
+
else {
|
|
136
|
+
fail(res, "User had no id on load()");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// recall all spirits with the given service name and parent
|
|
142
|
+
let spirit = await req.db.Spirit.recallOne(req.body.service, parent, data, id);
|
|
143
|
+
|
|
144
|
+
res.send(spirit);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.log(error);
|
|
147
|
+
fail(res, "Server error");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* This API route runs a script on the server. Responds with the result.
|
|
153
|
+
* @param {Object} req
|
|
154
|
+
* @param {Object} res
|
|
155
|
+
*/
|
|
156
|
+
serve = async (req, res) => {
|
|
157
|
+
try {
|
|
158
|
+
let scriptPath = `${req.contentPath}${req.body.route}/${req.body.script}.js`;
|
|
159
|
+
|
|
160
|
+
let script, result = null;
|
|
161
|
+
|
|
162
|
+
if (fs.existsSync(scriptPath)) {
|
|
163
|
+
let user = await req.db.Spirit.recallOne("user", null, { username: req.session?.currentUser });
|
|
164
|
+
|
|
165
|
+
script = await import(process.env.WINDOWS == "true" ? `file://${scriptPath}` : scriptPath);
|
|
166
|
+
result = await script.default(req, user, this.io);
|
|
167
|
+
success(res, "Served.", result);
|
|
168
|
+
}
|
|
169
|
+
else fail(res, `Script not found: ${req.body.script} at ${scriptPath}`);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.log(error);
|
|
172
|
+
fail(res, "Server error");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
175
|
}
|