mirror of https://github.com/calzoneman/sync.git
Add action log
This commit is contained in:
parent
9d90f6c660
commit
6943845d7a
14
acp.js
14
acp.js
|
@ -1,24 +1,30 @@
|
||||||
var Server = require("./server");
|
var Server = require("./server");
|
||||||
var Auth = require("./auth");
|
var Auth = require("./auth");
|
||||||
var Database = require("./database");
|
var Database = require("./database");
|
||||||
|
var ActionLog = require("./actionlog");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(user) {
|
init: function(user) {
|
||||||
|
ActionLog.record(user.ip, user.name, "acp-init");
|
||||||
user.socket.on("acp-announce", function(data) {
|
user.socket.on("acp-announce", function(data) {
|
||||||
|
ActionLog.record(user.ip, user.name, ["acp-announce", data]);
|
||||||
Server.announcement = data;
|
Server.announcement = data;
|
||||||
Server.io.sockets.emit("announcement", data);
|
Server.io.sockets.emit("announcement", data);
|
||||||
});
|
});
|
||||||
|
|
||||||
user.socket.on("acp-announce-clear", function() {
|
user.socket.on("acp-announce-clear", function() {
|
||||||
|
ActionLog.record(user.ip, user.name, "acp-announce-clear");
|
||||||
Server.announcement = null;
|
Server.announcement = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
user.socket.on("acp-global-ban", function(data) {
|
user.socket.on("acp-global-ban", function(data) {
|
||||||
|
ActionLog.record(user.ip, user.name, ["acp-global-ban", data.ip]);
|
||||||
Database.globalBanIP(data.ip, data.note);
|
Database.globalBanIP(data.ip, data.note);
|
||||||
user.socket.emit("acp-global-banlist", Database.refreshGlobalBans());
|
user.socket.emit("acp-global-banlist", Database.refreshGlobalBans());
|
||||||
});
|
});
|
||||||
|
|
||||||
user.socket.on("acp-global-unban", function(ip) {
|
user.socket.on("acp-global-unban", function(ip) {
|
||||||
|
ActionLog.record(user.ip, user.name, ["acp-global-unban", data.ip]);
|
||||||
Database.globalUnbanIP(ip);
|
Database.globalUnbanIP(ip);
|
||||||
user.socket.emit("acp-global-banlist", Database.refreshGlobalBans());
|
user.socket.emit("acp-global-banlist", Database.refreshGlobalBans());
|
||||||
});
|
});
|
||||||
|
@ -49,6 +55,7 @@ module.exports = {
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
var hash = Database.generatePasswordReset(user.ip, data.name, data.email);
|
var hash = Database.generatePasswordReset(user.ip, data.name, data.email);
|
||||||
|
ActionLog.record(user.ip, user.name, ["acp-reset-password", data.name]);
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
user.socket.emit("acp-reset-password", {
|
user.socket.emit("acp-reset-password", {
|
||||||
|
@ -83,6 +90,7 @@ module.exports = {
|
||||||
if(!db)
|
if(!db)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ActionLog.record(user.ip, user.name, ["acp-set-rank", data]);
|
||||||
var query = Database.createQuery(
|
var query = Database.createQuery(
|
||||||
"UPDATE registrations SET global_rank=? WHERE uname=?",
|
"UPDATE registrations SET global_rank=? WHERE uname=?",
|
||||||
[data.name, data.rank]
|
[data.name, data.rank]
|
||||||
|
@ -120,6 +128,7 @@ module.exports = {
|
||||||
var c = Server.channels[data.name];
|
var c = Server.channels[data.name];
|
||||||
if(!c)
|
if(!c)
|
||||||
return;
|
return;
|
||||||
|
ActionLog.record(user.ip, user.name, "acp-channel-unload");
|
||||||
c.initialized = data.save;
|
c.initialized = data.save;
|
||||||
c.users.forEach(function(u) {
|
c.users.forEach(function(u) {
|
||||||
c.kick(u, "Channel shutting down");
|
c.kick(u, "Channel shutting down");
|
||||||
|
@ -127,5 +136,10 @@ module.exports = {
|
||||||
Server.unload(c);
|
Server.unload(c);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
user.socket.on("acp-actionlog-clear", function() {
|
||||||
|
ActionLog.clear();
|
||||||
|
ActionLog.record(user.ip, user.name, "acp-actionlog-clear");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
var fs = require("fs");
|
||||||
|
|
||||||
|
var buffer = [];
|
||||||
|
|
||||||
|
exports.record = function(ip, name, action) {
|
||||||
|
buffer.push(JSON.stringify({
|
||||||
|
ip: ip,
|
||||||
|
name: name,
|
||||||
|
action: action,
|
||||||
|
time: Date.now()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.flush = function() {
|
||||||
|
if(buffer.length == 0)
|
||||||
|
return;
|
||||||
|
var text = buffer.join("\n") + "\n";
|
||||||
|
buffer = [];
|
||||||
|
fs.appendFile("action.log", text, function(err) {
|
||||||
|
if(err) {
|
||||||
|
errlog.log("Append to actionlog failed: ");
|
||||||
|
errlog.log(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.clear = function() {
|
||||||
|
try {
|
||||||
|
fs.renameSync("action.log", "action-until-"+Date.now()+".log");
|
||||||
|
}
|
||||||
|
catch(e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(exports.flush, 15000);
|
126
api.js
126
api.js
|
@ -15,6 +15,7 @@ var Logger = require("./logger.js");
|
||||||
var apilog = new Logger.Logger("api.log");
|
var apilog = new Logger.Logger("api.log");
|
||||||
var Database = require("./database.js");
|
var Database = require("./database.js");
|
||||||
var Config = require("./config.js");
|
var Config = require("./config.js");
|
||||||
|
var ActionLog = require("./actionlog.js");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
|
|
||||||
var plainHandlers = {
|
var plainHandlers = {
|
||||||
|
@ -32,11 +33,21 @@ var jsonHandlers = {
|
||||||
"setprofile" : handleProfileChange,
|
"setprofile" : handleProfileChange,
|
||||||
"getprofile" : handleProfileGet,
|
"getprofile" : handleProfileGet,
|
||||||
"setemail" : handleEmailChange,
|
"setemail" : handleEmailChange,
|
||||||
"globalbans" : handleGlobalBans,
|
|
||||||
"admreports" : handleAdmReports,
|
"admreports" : handleAdmReports,
|
||||||
"acppwreset" : handleAcpPasswordReset
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getClientIP(req) {
|
||||||
|
var ip;
|
||||||
|
var forward = req.header("x-forwarded-for");
|
||||||
|
if(forward) {
|
||||||
|
ip = forward.split(",")[0];
|
||||||
|
}
|
||||||
|
if(!ip) {
|
||||||
|
ip = req.connection.remoteAddress;
|
||||||
|
}
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
function handle(path, req, res) {
|
function handle(path, req, res) {
|
||||||
var parts = path.split("/");
|
var parts = path.split("/");
|
||||||
var last = parts[parts.length - 1];
|
var last = parts[parts.length - 1];
|
||||||
|
@ -193,12 +204,14 @@ function handleLogin(params, req, res) {
|
||||||
|
|
||||||
var row = Auth.login(name, pw, session);
|
var row = Auth.login(name, pw, session);
|
||||||
if(row) {
|
if(row) {
|
||||||
|
ActionLog.record(getClientIP(req), name, "login-success");
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
success: true,
|
success: true,
|
||||||
session: row.session_hash
|
session: row.session_hash
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
ActionLog.record(getClientIP(req), name, "login-failure");
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
error: "Invalid username/password",
|
error: "Invalid username/password",
|
||||||
success: false
|
success: false
|
||||||
|
@ -219,6 +232,7 @@ function handlePasswordChange(params, req, res) {
|
||||||
}
|
}
|
||||||
var row = Auth.login(name, oldpw);
|
var row = Auth.login(name, oldpw);
|
||||||
if(row) {
|
if(row) {
|
||||||
|
ActionLog.record(getClientIP(req), name, "password-change");
|
||||||
var success = Auth.setUserPassword(name, newpw);
|
var success = Auth.setUserPassword(name, newpw);
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
success: success,
|
success: success,
|
||||||
|
@ -237,11 +251,12 @@ function handlePasswordChange(params, req, res) {
|
||||||
function handlePasswordReset(params, req, res) {
|
function handlePasswordReset(params, req, res) {
|
||||||
var name = params.name || "";
|
var name = params.name || "";
|
||||||
var email = unescape(params.email || "");
|
var email = unescape(params.email || "");
|
||||||
var ip = req.socket.address().address;
|
var ip = getClientIP(req);
|
||||||
|
|
||||||
var hash = false;
|
var hash = false;
|
||||||
try {
|
try {
|
||||||
hash = Database.generatePasswordReset(ip, name, email);
|
hash = Database.generatePasswordReset(ip, name, email);
|
||||||
|
ActionLog.record(ip, name, "password-reset-generate");
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
|
@ -301,7 +316,7 @@ function handlePasswordReset(params, req, res) {
|
||||||
|
|
||||||
function handlePasswordRecover(params, req, res) {
|
function handlePasswordRecover(params, req, res) {
|
||||||
var hash = params.hash || "";
|
var hash = params.hash || "";
|
||||||
var ip = req.socket.address().address;
|
var ip = getClientIP(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var info = Database.recoverPassword(hash);
|
var info = Database.recoverPassword(hash);
|
||||||
|
@ -310,10 +325,12 @@ function handlePasswordRecover(params, req, res) {
|
||||||
name: info[0],
|
name: info[0],
|
||||||
pw: info[1]
|
pw: info[1]
|
||||||
});
|
});
|
||||||
|
ActionLog.record(ip, name, "password-recover-success");
|
||||||
Logger.syslog.log(ip + " recovered password for " + name);
|
Logger.syslog.log(ip + " recovered password for " + name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
|
ActionLog.record(ip, name, "password-recover-failure");
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
success: false,
|
success: false,
|
||||||
error: e
|
error: e
|
||||||
|
@ -412,6 +429,7 @@ function handleEmailChange(params, req, res) {
|
||||||
var row = Auth.login(name, pw);
|
var row = Auth.login(name, pw);
|
||||||
if(row) {
|
if(row) {
|
||||||
var success = Database.setUserEmail(name, email);
|
var success = Database.setUserEmail(name, email);
|
||||||
|
ActionLog.record(getClientIP(req), name, ["email-update", email]);
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
success: success,
|
success: success,
|
||||||
error: success ? "" : "Email update failed",
|
error: success ? "" : "Email update failed",
|
||||||
|
@ -438,6 +456,7 @@ function handleRegister(params, req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(Auth.isRegistered(name)) {
|
else if(Auth.isRegistered(name)) {
|
||||||
|
ActionLog.record(getClientIP(req), name, "register-failure");
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
success: false,
|
success: false,
|
||||||
error: "That username is already taken"
|
error: "That username is already taken"
|
||||||
|
@ -445,6 +464,7 @@ function handleRegister(params, req, res) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(!Auth.validateName(name)) {
|
else if(!Auth.validateName(name)) {
|
||||||
|
ActionLog.record(getClientIP(req), name, "register-failure");
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
success: false,
|
success: false,
|
||||||
error: "Invalid username. Usernames must be 1-20 characters long and consist only of alphanumeric characters and underscores"
|
error: "Invalid username. Usernames must be 1-20 characters long and consist only of alphanumeric characters and underscores"
|
||||||
|
@ -453,7 +473,8 @@ function handleRegister(params, req, res) {
|
||||||
else {
|
else {
|
||||||
var session = Auth.register(name, pw);
|
var session = Auth.register(name, pw);
|
||||||
if(session) {
|
if(session) {
|
||||||
Logger.syslog.log(this.ip + " registered " + name);
|
ActionLog.record(getClientIP(req), name, "register-success");
|
||||||
|
Logger.syslog.log(getClientIP(req) + " registered " + name);
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
success: true,
|
success: true,
|
||||||
session: session
|
session: session
|
||||||
|
@ -468,103 +489,12 @@ function handleRegister(params, req, res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGlobalBans(params, req, res) {
|
|
||||||
var name = params.name || "";
|
|
||||||
var pw = params.pw || "";
|
|
||||||
var session = params.session || "";
|
|
||||||
var row = Auth.login(name, pw, session);
|
|
||||||
if(!row || row.global_rank < 255) {
|
|
||||||
res.send(403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var action = params.action || "list";
|
|
||||||
if(action == "list") {
|
|
||||||
var gbans = Database.refreshGlobalBans();
|
|
||||||
sendJSON(res, gbans);
|
|
||||||
}
|
|
||||||
else if(action == "add") {
|
|
||||||
var ip = params.ip || "";
|
|
||||||
var reason = params.reason || "";
|
|
||||||
if(!ip.match(/\d+\.\d+\.(\d+\.(\d+)?)?/)) {
|
|
||||||
sendJSON(res, {
|
|
||||||
error: "Invalid IP address"
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var result = Database.globalBanIP(ip, reason);
|
|
||||||
sendJSON(res, {
|
|
||||||
success: result,
|
|
||||||
ip: ip,
|
|
||||||
reason: reason
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if(action == "remove") {
|
|
||||||
var ip = params.ip || "";
|
|
||||||
if(!ip.match(/\d+\.\d+\.(\d+\.(\d+)?)?/)) {
|
|
||||||
sendJSON(res, {
|
|
||||||
error: "Invalid IP address"
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var result = Database.globalUnbanIP(ip);
|
|
||||||
sendJSON(res, {
|
|
||||||
success: result,
|
|
||||||
ip: ip,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sendJSON(res, {
|
|
||||||
error: "Invalid action: " + action
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleAdmReports(params, req, res) {
|
function handleAdmReports(params, req, res) {
|
||||||
sendJSON(res, {
|
sendJSON(res, {
|
||||||
error: "Not implemented"
|
error: "Not implemented"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAcpPasswordReset(params, req, res) {
|
|
||||||
var name = params.name || "";
|
|
||||||
var pw = params.pw || "";
|
|
||||||
var session = params.session || "";
|
|
||||||
var row = Auth.login(name, pw, session);
|
|
||||||
if(!row || row.global_rank < 255) {
|
|
||||||
res.send(403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var action = params.action || "";
|
|
||||||
if(action == "reset") {
|
|
||||||
var uname = params.reset_name;
|
|
||||||
if(Auth.getGlobalRank(uname) > row.global_rank) {
|
|
||||||
sendJSON(res, {
|
|
||||||
success: false
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var new_pw = Database.resetPassword(uname);
|
|
||||||
if(new_pw) {
|
|
||||||
sendJSON(res, {
|
|
||||||
success: true,
|
|
||||||
pw: new_pw
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sendJSON(res, {
|
|
||||||
success: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sendJSON(res, {
|
|
||||||
success: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function
|
// Helper function
|
||||||
function pipeLast(res, file, len) {
|
function pipeLast(res, file, len) {
|
||||||
fs.stat(file, function(err, data) {
|
fs.stat(file, function(err, data) {
|
||||||
|
@ -599,6 +529,10 @@ function handleReadLog(params, req, res) {
|
||||||
else if(type == "err") {
|
else if(type == "err") {
|
||||||
pipeLast(res, "error.log", 1024*1024);
|
pipeLast(res, "error.log", 1024*1024);
|
||||||
}
|
}
|
||||||
|
else if(type == "action") {
|
||||||
|
ActionLog.flush();
|
||||||
|
pipeLast(res, "action.log", 1024*1024*100);
|
||||||
|
}
|
||||||
else if(type == "channel") {
|
else if(type == "channel") {
|
||||||
var chan = params.channel || "";
|
var chan = params.channel || "";
|
||||||
fs.exists("chanlogs/" + chan + ".log", function(exists) {
|
fs.exists("chanlogs/" + chan + ".log", function(exists) {
|
||||||
|
|
|
@ -268,12 +268,14 @@ function incrementalDump(chan) {
|
||||||
|
|
||||||
Channel.prototype.tryRegister = function(user) {
|
Channel.prototype.tryRegister = function(user) {
|
||||||
if(this.registered) {
|
if(this.registered) {
|
||||||
|
ActionLog.record(user.ip, user.name, ["channel-register-failure", this.name]);
|
||||||
user.socket.emit("registerChannel", {
|
user.socket.emit("registerChannel", {
|
||||||
success: false,
|
success: false,
|
||||||
error: "This channel is already registered"
|
error: "This channel is already registered"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if(!user.loggedIn) {
|
else if(!user.loggedIn) {
|
||||||
|
ActionLog.record(user.ip, user.name, ["channel-register-failure", this.name]);
|
||||||
user.socket.emit("registerChannel", {
|
user.socket.emit("registerChannel", {
|
||||||
success: false,
|
success: false,
|
||||||
error: "You must log in to register a channel"
|
error: "You must log in to register a channel"
|
||||||
|
@ -281,6 +283,7 @@ Channel.prototype.tryRegister = function(user) {
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(!Rank.hasPermission(user, "registerChannel")) {
|
else if(!Rank.hasPermission(user, "registerChannel")) {
|
||||||
|
ActionLog.record(user.ip, user.name, ["channel-register-failure", this.name]);
|
||||||
user.socket.emit("registerChannel", {
|
user.socket.emit("registerChannel", {
|
||||||
success: false,
|
success: false,
|
||||||
error: "You don't have permission to register this channel"
|
error: "You don't have permission to register this channel"
|
||||||
|
@ -288,6 +291,7 @@ Channel.prototype.tryRegister = function(user) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(Database.registerChannel(this.name)) {
|
if(Database.registerChannel(this.name)) {
|
||||||
|
ActionLog.record(user.ip, user.name, ["channel-register-success", this.name]);
|
||||||
this.registered = true;
|
this.registered = true;
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
this.saveDump();
|
this.saveDump();
|
||||||
|
|
17
user.js
17
user.js
|
@ -18,6 +18,7 @@ var Database = require("./database.js");
|
||||||
var Logger = require("./logger.js");
|
var Logger = require("./logger.js");
|
||||||
var Config = require("./config.js");
|
var Config = require("./config.js");
|
||||||
var ACP = require("./acp");
|
var ACP = require("./acp");
|
||||||
|
var ActionLog = require("./actionlog");
|
||||||
|
|
||||||
// Represents a client connected via socket.io
|
// Represents a client connected via socket.io
|
||||||
var User = function(socket, ip) {
|
var User = function(socket, ip) {
|
||||||
|
@ -526,13 +527,6 @@ User.prototype.initCallbacks = function() {
|
||||||
var lastguestlogin = {};
|
var lastguestlogin = {};
|
||||||
// Attempt to login
|
// Attempt to login
|
||||||
User.prototype.login = function(name, pw, session) {
|
User.prototype.login = function(name, pw, session) {
|
||||||
if(this.channel != null && name != "") {
|
|
||||||
for(var i = 0; i < this.channel.users.length; i++) {
|
|
||||||
if(this.channel.users[i].name == name) {
|
|
||||||
this.channel.kick(this.channel.users[i], "Duplicate login");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// No password => try guest login
|
// No password => try guest login
|
||||||
if(pw == "" && session == "") {
|
if(pw == "" && session == "") {
|
||||||
if(this.ip in lastguestlogin) {
|
if(this.ip in lastguestlogin) {
|
||||||
|
@ -593,6 +587,14 @@ User.prototype.login = function(name, pw, session) {
|
||||||
try {
|
try {
|
||||||
var row;
|
var row;
|
||||||
if((row = Auth.login(name, pw, session))) {
|
if((row = Auth.login(name, pw, session))) {
|
||||||
|
if(this.channel != null) {
|
||||||
|
for(var i = 0; i < this.channel.users.length; i++) {
|
||||||
|
if(this.channel.users[i].name == name) {
|
||||||
|
this.channel.kick(this.channel.users[i], "Duplicate login");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ActionLog.record(this.ip, name, "login-success");
|
||||||
this.loggedIn = true;
|
this.loggedIn = true;
|
||||||
this.socket.emit("login", {
|
this.socket.emit("login", {
|
||||||
success: true,
|
success: true,
|
||||||
|
@ -620,6 +622,7 @@ User.prototype.login = function(name, pw, session) {
|
||||||
}
|
}
|
||||||
// Wrong password
|
// Wrong password
|
||||||
else {
|
else {
|
||||||
|
ActionLog.record(this.ip, this.name, "login-failure");
|
||||||
this.socket.emit("login", {
|
this.socket.emit("login", {
|
||||||
success: false,
|
success: false,
|
||||||
error: "Invalid session"
|
error: "Invalid session"
|
||||||
|
|
17
www/acp.html
17
www/acp.html
|
@ -59,6 +59,7 @@
|
||||||
<li id="li_gbans"><a href="javascript:void(0)" id="show_gbans">Global Bans</a></li>
|
<li id="li_gbans"><a href="javascript:void(0)" id="show_gbans">Global Bans</a></li>
|
||||||
<li id="li_userlookup"><a href="javascript:void(0)" id="show_userlookup">Users</a></li>
|
<li id="li_userlookup"><a href="javascript:void(0)" id="show_userlookup">Users</a></li>
|
||||||
<li id="li_chanloaded"><a href="javascript:void(0)" id="show_chanloaded">Loaded Channels</a></li>
|
<li id="li_chanloaded"><a href="javascript:void(0)" id="show_chanloaded">Loaded Channels</a></li>
|
||||||
|
<li id="li_actionlog"><a href="javascript:void(0)" id="show_actionlog">Action Log</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -174,6 +175,22 @@
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="span12" id="actionlog">
|
||||||
|
<h3>Action Log</h3>
|
||||||
|
<select multiple="multiple" id="actionlog_filter">
|
||||||
|
</select>
|
||||||
|
<button class="btn btn-danger" id="actionlog_clear">Clear</button>
|
||||||
|
<table class="table table-bordered table-striped table-compact">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>IP Address</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Action</th>
|
||||||
|
<th>Time</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> <!-- /container -->
|
</div> <!-- /container -->
|
||||||
<div class="push"></div>
|
<div class="push"></div>
|
||||||
|
|
|
@ -48,6 +48,27 @@ $("#show_chanloaded").click(function() {
|
||||||
$("#listloaded_refresh").click(function() {
|
$("#listloaded_refresh").click(function() {
|
||||||
socket.emit("acp-list-loaded");
|
socket.emit("acp-list-loaded");
|
||||||
});
|
});
|
||||||
|
menuHandler("#show_actionlog", "#actionlog");
|
||||||
|
$("#show_actionlog").click(getActionLog);
|
||||||
|
$("#actionlog_filter").click(function() {
|
||||||
|
var actions = $(this).val();
|
||||||
|
$("#actionlog tbody").remove();
|
||||||
|
$("#actionlog table").data("entries").forEach(function(e) {
|
||||||
|
if(typeof e.action == "string" && actions.indexOf(e.action) == -1)
|
||||||
|
return;
|
||||||
|
if(typeof e.action == "object" && "0" in e.action && actions.indexOf(e.action[0]) == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var tr = $("<tr/>").appendTo($("#actionlog table"));
|
||||||
|
$("<td/>").text(e.ip).appendTo(tr);
|
||||||
|
$("<td/>").text(e.name).appendTo(tr);
|
||||||
|
$("<td/>").text(e.action).appendTo(tr);
|
||||||
|
$("<td/>").text(new Date(e.time).toTimeString()).appendTo(tr);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#actionlog_clear").click(function() {
|
||||||
|
socket.emit("acp-actionlog-clear");
|
||||||
|
});
|
||||||
|
|
||||||
function getSyslog() {
|
function getSyslog() {
|
||||||
$.ajax(WEB_URL+"/api/plain/readlog?type=sys&"+AUTH).done(function(data) {
|
$.ajax(WEB_URL+"/api/plain/readlog?type=sys&"+AUTH).done(function(data) {
|
||||||
|
@ -61,6 +82,39 @@ function getErrlog() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$("#errlog").click(getErrlog);
|
$("#errlog").click(getErrlog);
|
||||||
|
function getActionLog() {
|
||||||
|
$.ajax(WEB_URL+"/api/plain/readlog?type=action&"+AUTH).done(function(data) {
|
||||||
|
var entries = [];
|
||||||
|
var actions = [];
|
||||||
|
data.split("\n").forEach(function(ln) {
|
||||||
|
var entry;
|
||||||
|
try {
|
||||||
|
entry = JSON.parse(ln);
|
||||||
|
if(typeof entry.action == "string") {
|
||||||
|
if(actions.indexOf(entry.action) == -1)
|
||||||
|
actions.push(entry.action);
|
||||||
|
}
|
||||||
|
else if(typeof entry.action == "object" && "0" in entry.action) {
|
||||||
|
if(actions.indexOf(entry.action[0]) == -1)
|
||||||
|
actions.push(entry.action[0]);
|
||||||
|
}
|
||||||
|
entries.push(entry);
|
||||||
|
}
|
||||||
|
catch(e) { }
|
||||||
|
});
|
||||||
|
entries.sort(function(a, b) {
|
||||||
|
return a.time == b.time ? 0 : (a.time < b.time ? 1 : -1);
|
||||||
|
});
|
||||||
|
$("#actionlog table").data("entries", entries);
|
||||||
|
$("#actionlog_filter").html("");
|
||||||
|
actions.sort(function(a, b) {
|
||||||
|
return a == b ? 0 : (a < b ? -1 : 1);
|
||||||
|
});
|
||||||
|
actions.forEach(function(a) {
|
||||||
|
$("<option/>").text(a).val(a).appendTo($("#actionlog_filter"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
function getChanlog() {
|
function getChanlog() {
|
||||||
var chan = $("#channame").val();
|
var chan = $("#channame").val();
|
||||||
$.ajax(WEB_URL+"/api/plain/readlog?type=channel&channel="+chan+"&"+AUTH).done(function(data) {
|
$.ajax(WEB_URL+"/api/plain/readlog?type=channel&channel="+chan+"&"+AUTH).done(function(data) {
|
||||||
|
|
Loading…
Reference in New Issue