@nka212bg/backend-utils 0.1.31 → 0.1.32
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/misc.js +1 -1
- package/package.json +1 -1
- package/session.js +106 -12
package/misc.js
CHANGED
package/package.json
CHANGED
package/session.js
CHANGED
|
@@ -1,28 +1,124 @@
|
|
|
1
|
-
const { existsSync, readFileSync,
|
|
1
|
+
const { existsSync, readFileSync, mkdirSync } = require("fs");
|
|
2
|
+
const { writeFile } = require("fs/promises");
|
|
2
3
|
const { createToken } = require("./misc");
|
|
3
4
|
|
|
4
5
|
!existsSync(`${__basedir}/state`) && mkdirSync(`${__basedir}/state`, { recursive: true });
|
|
5
|
-
const sessionStateFile = `${__basedir}/state/session.json`;
|
|
6
6
|
|
|
7
|
+
/* -------------------- ban list -------------------- */
|
|
8
|
+
const banListFile = `${__basedir}/state/banList.json`;
|
|
9
|
+
const BAN_LIST = existsSync(banListFile) ? JSON.parse(readFileSync(banListFile, "utf8") || "{}") : {};
|
|
10
|
+
|
|
11
|
+
/* -------------------- session --------------------- */
|
|
12
|
+
const sessionStateFile = `${__basedir}/state/session.json`;
|
|
7
13
|
const SESSION = existsSync(sessionStateFile) ? JSON.parse(readFileSync(sessionStateFile, "utf8") || "{}") : {};
|
|
8
14
|
|
|
15
|
+
/* -------------------- state --------------------- */
|
|
16
|
+
const serverStateFile = `${__basedir}/state/state.json`;
|
|
17
|
+
const STATE = existsSync(serverStateFile) ? JSON.parse(readFileSync(serverStateFile, "utf8") || "{}") : {};
|
|
18
|
+
|
|
9
19
|
setInterval(() => {
|
|
10
|
-
// delete expired sessions
|
|
11
20
|
const now = Date.now();
|
|
21
|
+
|
|
22
|
+
// delete expired sessions
|
|
12
23
|
Object.keys(SESSION).forEach((e) => {
|
|
13
24
|
SESSION[e].expireTime < now && delete SESSION[e];
|
|
14
25
|
});
|
|
26
|
+
// save the sessions in file (non-blocking write, JSON.stringify itself still runs sync)
|
|
27
|
+
writeFile(sessionStateFile, JSON.stringify(SESSION)).catch((error) => console.error("session save failed:", error));
|
|
15
28
|
|
|
16
|
-
//
|
|
17
|
-
|
|
29
|
+
// delete expired entries
|
|
30
|
+
Object.keys(STATE).forEach((e) => {
|
|
31
|
+
STATE[e].expireTime < now && delete STATE[e];
|
|
32
|
+
});
|
|
33
|
+
// save the state in file (non-blocking write, JSON.stringify itself still runs sync)
|
|
34
|
+
writeFile(serverStateFile, JSON.stringify(STATE)).catch((error) => console.error("state save failed:", error));
|
|
18
35
|
}, 60000);
|
|
19
36
|
|
|
37
|
+
// document.cookie-style: reading serverState[token] gets it, assigning
|
|
38
|
+
// serverState[token] = {...} sets/updates it, assigning a falsy value
|
|
39
|
+
// deletes it (the same "expire it out" trick browsers use for cookies).
|
|
40
|
+
exports.serverState = new Proxy(
|
|
41
|
+
{},
|
|
42
|
+
{
|
|
43
|
+
// GET
|
|
44
|
+
// const s = serverState["abc123"]; // => {name: 'alice', ..., expireIn: 604859999}
|
|
45
|
+
// const s = serverState[req.headers.authorization];
|
|
46
|
+
// const all = serverState.getAll; // => whole STATE map
|
|
47
|
+
// const alices = serverState["name=alice"]; // => all entries where name == "alice", each with its token
|
|
48
|
+
get(_, token) {
|
|
49
|
+
if (token === "getAll") return STATE;
|
|
50
|
+
|
|
51
|
+
if (token.includes("=")) {
|
|
52
|
+
const [field, value] = token.trim().split(/\s*=\s*/);
|
|
53
|
+
return Object.entries(STATE)
|
|
54
|
+
.filter(([, s]) => s[field] == value)
|
|
55
|
+
.map(([token, s]) => ({ ...s, token }));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!STATE[token]) return undefined;
|
|
59
|
+
return { ...STATE[token], expireIn: STATE[token].expireTime - Date.now() + 60000 };
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
// DELETE
|
|
63
|
+
// delete serverState["abc123"];
|
|
64
|
+
// delete serverState["name=alice"]; // bulk delete, removes every entry where name == "alice"
|
|
65
|
+
deleteProperty(_, token) {
|
|
66
|
+
if (token.includes("=")) {
|
|
67
|
+
const [field, value] = token.trim().split(/\s*=\s*/);
|
|
68
|
+
Object.entries(STATE).forEach(([t, s]) => {
|
|
69
|
+
if (s[field] == value) delete STATE[t];
|
|
70
|
+
});
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
delete STATE[token];
|
|
75
|
+
return true;
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
// SET / UPDATE / DELETE
|
|
79
|
+
// serverState["abc123"] = {name: 'alice'}; // create (stamps expirePeriod/expireTime/uuid)
|
|
80
|
+
// serverState["abc123"] = {name: 'alice2'}; // update (merges into existing)
|
|
81
|
+
// serverState["abc123"] = null; // delete, cookie-expiry trick
|
|
82
|
+
// serverState["name=alice"] = {name: 'john'}; // bulk update, merges into every entry where name == "alice"
|
|
83
|
+
set(_, token, fields) {
|
|
84
|
+
if (token.includes("=")) {
|
|
85
|
+
const [field, value] = token.trim().split(/\s*=\s*/);
|
|
86
|
+
Object.entries(STATE).forEach(([t, s]) => {
|
|
87
|
+
if (s[field] == value) STATE[t] = { ...s, ...fields };
|
|
88
|
+
});
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!fields) {
|
|
93
|
+
delete STATE[token];
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
|
|
99
|
+
if (STATE[token]) {
|
|
100
|
+
if (fields.expirePeriod) fields.expireTime = now + fields.expirePeriod;
|
|
101
|
+
STATE[token] = { ...STATE[token], ...fields };
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
fields.expirePeriod ||= 60000 * 60 * 24 * 7; // 7 days
|
|
106
|
+
fields.expireTime = now + fields.expirePeriod;
|
|
107
|
+
fields.uuid = createToken({ type: "date" });
|
|
108
|
+
|
|
109
|
+
STATE[token] = fields;
|
|
110
|
+
return true;
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
|
|
20
115
|
// session C.R.U.D.
|
|
21
116
|
exports.session = {
|
|
22
117
|
set(payload = {}) {
|
|
23
118
|
// payload.set => {token: 23456546, whatever: 'someValue', whatever_2: 'someValue'}
|
|
24
119
|
if (!payload.token) return { error: "missing_token" };
|
|
25
120
|
|
|
121
|
+
payload = { ...payload };
|
|
26
122
|
const token = payload.token;
|
|
27
123
|
delete payload.token;
|
|
28
124
|
|
|
@@ -64,6 +160,7 @@ exports.session = {
|
|
|
64
160
|
|
|
65
161
|
update(payload = {}) {
|
|
66
162
|
// payload => {id: 23456546, whatever: 'someValue', whatever_2: 'someValue'}
|
|
163
|
+
payload = { ...payload };
|
|
67
164
|
const _key = Object.keys(payload)[0];
|
|
68
165
|
const _value = Object.values(payload)[0];
|
|
69
166
|
delete payload[_key];
|
|
@@ -95,9 +192,6 @@ exports.session = {
|
|
|
95
192
|
},
|
|
96
193
|
};
|
|
97
194
|
|
|
98
|
-
// -------- check or get ban users --------
|
|
99
|
-
const banListFile = `${__basedir}/state/banList.json`;
|
|
100
|
-
const BAN_LIST = existsSync(banListFile) ? JSON.parse(readFileSync(banListFile, "utf8") || "{}") : {};
|
|
101
195
|
exports.banList = {
|
|
102
196
|
isBanned(payload) {
|
|
103
197
|
// payload = {ip: 123.67.432.43}
|
|
@@ -106,7 +200,7 @@ exports.banList = {
|
|
|
106
200
|
const _key = Object.keys(payload)[0];
|
|
107
201
|
const _value = Object.values(payload)[0];
|
|
108
202
|
|
|
109
|
-
BAN_LIST[_key]?.includes(_value);
|
|
203
|
+
return BAN_LIST[_key]?.includes(_value);
|
|
110
204
|
},
|
|
111
205
|
banUser(payload) {
|
|
112
206
|
// payload = {whatever: 'someValue'}
|
|
@@ -117,17 +211,17 @@ exports.banList = {
|
|
|
117
211
|
if (!BAN_LIST[_key]) BAN_LIST[_key] = [];
|
|
118
212
|
|
|
119
213
|
BAN_LIST[_key].push(_value);
|
|
120
|
-
|
|
214
|
+
writeFile(banListFile, JSON.stringify(BAN_LIST)).catch((error) => console.error("banList save failed:", error));
|
|
121
215
|
},
|
|
122
216
|
unBanUser(payload) {
|
|
123
217
|
// payload = {whatever: 'someValue'}
|
|
124
218
|
const _key = Object.keys(payload)[0];
|
|
125
219
|
const _value = Object.values(payload)[0];
|
|
126
220
|
|
|
127
|
-
const index = BAN_LIST[_key]?.indexOf(_value)
|
|
221
|
+
const index = BAN_LIST[_key]?.indexOf(_value) ?? -1;
|
|
128
222
|
if (index > -1) {
|
|
129
223
|
BAN_LIST[_key].splice(index, 1);
|
|
130
|
-
|
|
224
|
+
writeFile(banListFile, JSON.stringify(BAN_LIST)).catch((error) => console.error("banList save failed:", error));
|
|
131
225
|
}
|
|
132
226
|
},
|
|
133
227
|
};
|