Bump path-parse from 1.0.6 to 1.0.7
[KisSync.git] / src / acp.js
blob5c9e8c66c9c8bb16e6ddafd111e70285c756cd17
1 var Logger = require("./logger");
2 var Server = require("./server");
3 var db = require("./database");
4 var util = require("./utilities");
5 import { v4 as uuidv4 } from 'uuid';
7 function eventUsername(user) {
8 return user.getName() + "@" + user.realip;
11 function handleAnnounce(user, data) {
12 var sv = Server.getServer();
14 sv.announce({
15 id: uuidv4(),
16 title: data.title,
17 text: data.content,
18 from: user.getName()
19 });
21 Logger.eventlog.log("[acp] " + eventUsername(user) + " opened announcement `" +
22 data.title + "`");
25 function handleAnnounceClear(user) {
26 Server.getServer().announce(null);
27 Logger.eventlog.log("[acp] " + eventUsername(user) + " cleared announcement");
30 function handleGlobalBan(user, data) {
31 const globalBanDB = db.getGlobalBanDB();
32 globalBanDB.addGlobalIPBan(data.ip, data.note).then(() => {
33 Logger.eventlog.log("[acp] " + eventUsername(user) + " global banned " + data.ip);
34 return globalBanDB.listGlobalBans().then(bans => {
35 // Why is it called reason in the DB and note in the socket frame?
36 // Who knows...
37 const mappedBans = bans.map(ban => {
38 return { ip: ban.ip, note: ban.reason };
39 });
40 user.socket.emit("acp-gbanlist", mappedBans);
41 });
42 }).catch(error => {
43 user.socket.emit("errMessage", {
44 msg: error.message
45 });
46 });
49 function handleGlobalBanDelete(user, data) {
50 const globalBanDB = db.getGlobalBanDB();
51 globalBanDB.removeGlobalIPBan(data.ip).then(() => {
52 Logger.eventlog.log("[acp] " + eventUsername(user) + " un-global banned " +
53 data.ip);
54 return globalBanDB.listGlobalBans().then(bans => {
55 // Why is it called reason in the DB and note in the socket frame?
56 // Who knows...
57 const mappedBans = bans.map(ban => {
58 return { ip: ban.ip, note: ban.reason };
59 });
60 user.socket.emit("acp-gbanlist", mappedBans);
61 });
62 }).catch(error => {
63 user.socket.emit("errMessage", {
64 msg: error.message
65 });
66 });
69 function handleListUsers(user, data) {
70 var value = data.value;
71 var field = data.field;
72 value = (typeof value !== 'string') ? '' : value;
73 field = (typeof field !== 'string') ? 'name' : field;
75 var fields = ["id", "name", "global_rank", "email", "ip", "time"];
77 if(!fields.includes(field)){
78 user.socket.emit("errMessage", {
79 msg: `The field "${field}" doesn't exist or isn't searchable.`
80 });
81 return;
84 db.users.search(field, value, fields, function (err, users) {
85 if (err) {
86 user.socket.emit("errMessage", {
87 msg: err
88 });
89 return;
91 user.socket.emit("acp-list-users", users);
92 });
95 function handleSetRank(user, data) {
96 var name = data.name;
97 var rank = data.rank;
98 if (typeof name !== "string" || typeof rank !== "number") {
99 return;
102 if (rank >= user.global_rank) {
103 user.socket.emit("errMessage", {
104 msg: "You are not permitted to promote others to equal or higher rank than " +
105 "yourself."
107 return;
110 db.users.getGlobalRank(name, function (err, oldrank) {
111 if (err) {
112 user.socket.emit("errMessage", {
113 msg: err
115 return;
118 if (oldrank >= user.global_rank) {
119 user.socket.emit("errMessage", {
120 msg: "You are not permitted to change the rank of users who rank " +
121 "higher than you."
123 return;
126 db.users.setGlobalRank(name, rank, function (err) {
127 if (err) {
128 user.socket.emit("errMessage", {
129 msg: err
131 } else {
132 Logger.eventlog.log("[acp] " + eventUsername(user) + " set " + name +
133 "'s global_rank to " + rank);
134 user.socket.emit("acp-set-rank", data);
140 function handleResetPassword(user, data, ack) {
141 var name = data.name;
142 var email = data.email;
143 if (typeof name !== "string" || typeof email !== "string") {
144 return;
147 db.users.getGlobalRank(name, function (err, rank) {
148 if (rank >= user.global_rank) {
149 user.socket.emit("errMessage", {
150 msg: "You don't have permission to reset the password for " + name
152 return;
155 var hash = util.sha1(util.randomSalt(64));
156 var expire = Date.now() + 86400000;
157 db.addPasswordReset({
158 ip: "",
159 name: name,
160 email: email,
161 hash: hash,
162 expire: expire
163 }, function (err) {
164 if (err) {
165 ack && ack({ error: err });
166 return;
169 Logger.eventlog.log("[acp] " + eventUsername(user) + " initialized a " +
170 "password recovery for " + name);
172 ack && ack({ hash });
177 function handleListChannels(user, data) {
178 var field = data.field;
179 var value = data.value;
180 if (typeof field !== "string" || typeof value !== "string") {
181 return;
184 var dbfunc;
185 if (field === "owner") {
186 dbfunc = db.channels.searchOwner;
187 } else {
188 dbfunc = db.channels.search;
191 dbfunc(value, function (err, rows) {
192 if (err) {
193 user.socket.emit("errMessage", {
194 msg: err
196 return;
199 user.socket.emit("acp-list-channels", rows);
203 function handleDeleteChannel(user, data) {
204 var name = data.name;
205 if (typeof data.name !== "string") {
206 return;
209 var sv = Server.getServer();
210 if (sv.isChannelLoaded(name)) {
211 sv.getChannel(name).users.forEach(function (u) {
212 u.kick("Channel shutting down");
216 db.channels.drop(name, function (err) {
217 Logger.eventlog.log("[acp] " + eventUsername(user) + " deleted channel " + name);
218 if (err) {
219 user.socket.emit("errMessage", {
220 msg: err
222 } else {
223 user.socket.emit("acp-delete-channel", {
224 name: name
230 function handleListActiveChannels(user) {
231 user.socket.emit("acp-list-activechannels", Server.getServer().packChannelList(false, true));
234 function handleForceUnload(user, data) {
235 var name = data.name;
236 if (typeof name !== "string") {
237 return;
240 var sv = Server.getServer();
241 if (!sv.isChannelLoaded(name)) {
242 return;
245 var chan = sv.getChannel(name);
246 var users = Array.prototype.slice.call(chan.users);
247 chan.emit("empty");
248 users.forEach(function (u) {
249 u.kick("Channel shutting down");
252 Logger.eventlog.log("[acp] " + eventUsername(user) + " forced unload of " + name);
255 function init(user) {
256 var s = user.socket;
257 s.on("acp-announce", handleAnnounce.bind(this, user));
258 s.on("acp-announce-clear", handleAnnounceClear.bind(this, user));
259 s.on("acp-gban", handleGlobalBan.bind(this, user));
260 s.on("acp-gban-delete", handleGlobalBanDelete.bind(this, user));
261 s.on("acp-list-users", handleListUsers.bind(this, user));
262 s.on("acp-set-rank", handleSetRank.bind(this, user));
263 s.on("acp-reset-password", handleResetPassword.bind(this, user));
264 s.on("acp-list-channels", handleListChannels.bind(this, user));
265 s.on("acp-delete-channel", handleDeleteChannel.bind(this, user));
266 s.on("acp-list-activechannels", handleListActiveChannels.bind(this, user));
267 s.on("acp-force-unload", handleForceUnload.bind(this, user));
269 const globalBanDB = db.getGlobalBanDB();
270 globalBanDB.listGlobalBans().then(bans => {
271 // Why is it called reason in the DB and note in the socket frame?
272 // Who knows...
273 const mappedBans = bans.map(ban => {
274 return { ip: ban.ip, note: ban.reason };
276 user.socket.emit("acp-gbanlist", mappedBans);
277 }).catch(error => {
278 user.socket.emit("errMessage", {
279 msg: error.message
282 Logger.eventlog.log("[acp] Initialized ACP for " + eventUsername(user));
285 module.exports.init = init;