mirror of https://github.com/calzoneman/sync.git
Continue working on acp
This commit is contained in:
parent
1272425205
commit
ac89c87e29
289
lib/acp.js
289
lib/acp.js
|
@ -11,169 +11,140 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||||
|
|
||||||
var Logger = require("./logger");
|
var Logger = require("./logger");
|
||||||
var Server = require("./server");
|
var Server = require("./server");
|
||||||
var ActionLog = require("./actionlog");
|
var db = require("./database");
|
||||||
|
|
||||||
module.exports = {
|
function handleAnnounce(user, data) {
|
||||||
init: function (user) {
|
|
||||||
var sv = Server.getServer();
|
var sv = Server.getServer();
|
||||||
var db = sv.db;
|
|
||||||
ActionLog.record(user.ip, user.name, "acp-init");
|
|
||||||
user.socket.on("acp-announce", function(data) {
|
|
||||||
ActionLog.record(user.ip, user.name, "acp-announce", data);
|
|
||||||
sv.announcement = data;
|
|
||||||
sv.io.sockets.emit("announcement", data);
|
|
||||||
if (sv.cfg["enable-ssl"])
|
|
||||||
sv.ioSecure.sockets.emit("announcement", data);
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-announce-clear", function() {
|
sv.announcement = {
|
||||||
ActionLog.record(user.ip, user.name, "acp-announce-clear");
|
title: data.title,
|
||||||
sv.announcement = null;
|
text: data.content,
|
||||||
});
|
from: user.name
|
||||||
|
|
||||||
user.socket.on("acp-global-ban", function(data) {
|
|
||||||
ActionLog.record(user.ip, user.name, "acp-global-ban", data.ip);
|
|
||||||
db.setGlobalIPBan(data.ip, data.note, function (err, res) {
|
|
||||||
db.listGlobalIPBans(function (err, res) {
|
|
||||||
res = res || [];
|
|
||||||
user.socket.emit("acp-global-banlist", res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-global-unban", function(ip) {
|
|
||||||
ActionLog.record(user.ip, user.name, "acp-global-unban", ip);
|
|
||||||
db.clearGlobalIPBan(ip, function (err, res) {
|
|
||||||
db.listGlobalIPBans(function (err, res) {
|
|
||||||
res = res || [];
|
|
||||||
user.socket.emit("acp-global-banlist", res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
db.listGlobalIPBans(function (err, res) {
|
|
||||||
res = res || [];
|
|
||||||
user.socket.emit("acp-global-banlist", res);
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-lookup-user", function(name) {
|
|
||||||
db.users.search(name, ["name", "email", "global_rank"], function (err, res) {
|
|
||||||
res = res || [];
|
|
||||||
user.socket.emit("acp-userdata", res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-lookup-channel", function (data) {
|
|
||||||
db.searchChannel(data.field, data.value, function (e, res) {
|
|
||||||
res = res || [];
|
|
||||||
user.socket.emit("acp-channeldata", res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-reset-password", function(data) {
|
|
||||||
db.users.getGlobalRank(data.name, function (err, rank) {
|
|
||||||
if(err || rank >= user.global_rank)
|
|
||||||
return;
|
|
||||||
|
|
||||||
db.genPasswordReset(user.ip, data.name, data.email,
|
|
||||||
function (err, hash) {
|
|
||||||
var pkt = {
|
|
||||||
success: !err
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(err) {
|
sv.io.sockets.emit("announcement", sv.announcement);
|
||||||
pkt.error = err;
|
if (sv.ioSecure) {
|
||||||
} else {
|
sv.ioSecure.sockets.emit("announcement", sv.announcement);
|
||||||
pkt.hash = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
user.socket.emit("acp-reset-password", pkt);
|
|
||||||
ActionLog.record(user.ip, user.name,
|
|
||||||
"acp-reset-password", data.name);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-set-rank", function(data) {
|
|
||||||
if(data.rank < 1 || data.rank >= user.global_rank)
|
|
||||||
return;
|
|
||||||
|
|
||||||
db.users.getGlobalRank(data.name, function (err, rank) {
|
|
||||||
if(err || rank >= user.global_rank)
|
|
||||||
return;
|
|
||||||
|
|
||||||
db.users.setGlobalRank(data.name, data.rank,
|
|
||||||
function (err, res) {
|
|
||||||
ActionLog.record(user.ip, user.name, "acp-set-rank",
|
|
||||||
data);
|
|
||||||
if(!err)
|
|
||||||
user.socket.emit("acp-set-rank", data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-list-loaded", function() {
|
|
||||||
var chans = [];
|
|
||||||
var all = sv.channels;
|
|
||||||
for(var c in all) {
|
|
||||||
var chan = all[c];
|
|
||||||
|
|
||||||
chans.push({
|
|
||||||
name: chan.name,
|
|
||||||
title: chan.opts.pagetitle,
|
|
||||||
usercount: chan.users.length,
|
|
||||||
mediatitle: chan.playlist.current ? chan.playlist.current.media.title : "-",
|
|
||||||
is_public: chan.opts.show_public,
|
|
||||||
registered: chan.registered
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
user.socket.emit("acp-list-loaded", chans);
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-channel-unload", function(data) {
|
|
||||||
if(sv.isChannelLoaded(data.name)) {
|
|
||||||
var c = sv.getChannel(data.name);
|
|
||||||
if(!c)
|
|
||||||
return;
|
|
||||||
ActionLog.record(user.ip, user.name, "acp-channel-unload");
|
|
||||||
c.initialized = data.save;
|
|
||||||
// copy the list of users to prevent concurrent
|
|
||||||
// modification
|
|
||||||
var users = Array.prototype.slice.call(c.users);
|
|
||||||
users.forEach(function (u) {
|
|
||||||
c.kick(u, "Channel shutting down");
|
|
||||||
});
|
|
||||||
|
|
||||||
// At this point c should be unloaded
|
|
||||||
// if it's still loaded, kill it
|
|
||||||
if(sv.isChannelLoaded(data.name))
|
|
||||||
sv.unloadChannel(sv.getChannel(data.name));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-actionlog-list", function () {
|
|
||||||
ActionLog.listActionTypes(function (err, types) {
|
|
||||||
if(!err)
|
|
||||||
user.socket.emit("acp-actionlog-list", types);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-actionlog-clear", function(data) {
|
|
||||||
ActionLog.clear(data);
|
|
||||||
ActionLog.record(user.ip, user.name, "acp-actionlog-clear", data);
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-actionlog-clear-one", function(data) {
|
|
||||||
ActionLog.clearOne(data);
|
|
||||||
ActionLog.record(user.ip, user.name, "acp-actionlog-clear-one", data);
|
|
||||||
});
|
|
||||||
|
|
||||||
user.socket.on("acp-view-stats", function () {
|
|
||||||
db.listStats(function (err, res) {
|
|
||||||
if(!err)
|
|
||||||
user.socket.emit("acp-view-stats", res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleAnnounceClear(user) {
|
||||||
|
Server.getServer().announcement = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleGlobalBan(user, data) {
|
||||||
|
db.globalBanIP(data.ip, data.note, function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
user.socket.emit("errMessage", {
|
||||||
|
msg: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.listGlobalBans(function (err, bans) {
|
||||||
|
if (err) {
|
||||||
|
user.socket.emit("errMessage", {
|
||||||
|
msg: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var flat = [];
|
||||||
|
for (var ip in bans) {
|
||||||
|
flat.push({
|
||||||
|
ip: ip,
|
||||||
|
note: bans[ip].reason
|
||||||
|
});
|
||||||
|
}
|
||||||
|
user.socket.emit("acp-gbanlist", flat);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleGlobalBanDelete(user, data) {
|
||||||
|
db.globalUnbanIP(data.ip, function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
user.socket.emit("errMessage", {
|
||||||
|
msg: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.listGlobalBans(function (err, bans) {
|
||||||
|
if (err) {
|
||||||
|
user.socket.emit("errMessage", {
|
||||||
|
msg: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var flat = [];
|
||||||
|
for (var ip in bans) {
|
||||||
|
flat.push({
|
||||||
|
ip: ip,
|
||||||
|
note: bans[ip].reason
|
||||||
|
});
|
||||||
|
}
|
||||||
|
user.socket.emit("acp-gbanlist", flat);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleListUsers(user, data) {
|
||||||
|
var name = data.name;
|
||||||
|
if (typeof name !== "string") {
|
||||||
|
name = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
var fields = ["id", "name", "global_rank", "email", "ip", "time"];
|
||||||
|
|
||||||
|
db.users.search(name, fields, function (err, users) {
|
||||||
|
if (err) {
|
||||||
|
user.socket.emit("errMessage", {
|
||||||
|
msg: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
user.socket.emit("acp-list-users", users);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSetRank(user, data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleResetPassword(user, data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(user) {
|
||||||
|
var s = user.socket;
|
||||||
|
s.on("acp-announce", handleAnnounce.bind(this, user));
|
||||||
|
s.on("acp-announce-clear", handleAnnounceClear.bind(this, user));
|
||||||
|
s.on("acp-gban", handleGlobalBan.bind(this, user));
|
||||||
|
s.on("acp-gban-delete", handleGlobalBanDelete.bind(this, user));
|
||||||
|
s.on("acp-list-users", handleListUsers.bind(this, user));
|
||||||
|
s.on("acp-set-rank", handleSetRank.bind(this, user));
|
||||||
|
s.on("acp-reset-password", handleResetPassword(this, user));
|
||||||
|
|
||||||
|
db.listGlobalBans(function (err, bans) {
|
||||||
|
if (err) {
|
||||||
|
user.socket.emit("errMessage", {
|
||||||
|
msg: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var flat = [];
|
||||||
|
for (var ip in bans) {
|
||||||
|
flat.push({
|
||||||
|
ip: ip,
|
||||||
|
note: bans[ip].reason
|
||||||
|
});
|
||||||
|
}
|
||||||
|
user.socket.emit("acp-gbanlist", flat);
|
||||||
|
});
|
||||||
|
Logger.eventlog.log("[acp] Initialized ACP for " + user.name + "@" + user.ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.init = init;
|
||||||
|
|
14
lib/user.js
14
lib/user.js
|
@ -5,6 +5,7 @@ var MakeEmitter = require("./emitter");
|
||||||
var db = require("./database");
|
var db = require("./database");
|
||||||
var InfoGetter = require("./get-info");
|
var InfoGetter = require("./get-info");
|
||||||
var Config = require("./config");
|
var Config = require("./config");
|
||||||
|
var ACP = require("./acp");
|
||||||
|
|
||||||
function User(socket) {
|
function User(socket) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -36,6 +37,19 @@ function User(socket) {
|
||||||
self.initChannelCallbacks();
|
self.initChannelCallbacks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.socket.once("initACP", function () {
|
||||||
|
self.whenLoggedIn(function () {
|
||||||
|
if (self.global_rank >= 255) {
|
||||||
|
ACP.init(self);
|
||||||
|
} else {
|
||||||
|
self.kick("Attempted initACP from non privileged user. This incident " +
|
||||||
|
"will be reported.");
|
||||||
|
Logger.eventlog.log("[acp] Attempted initACP from socket client " +
|
||||||
|
self.name + "@" + self.ip);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
self.socket.on("login", function (data) {
|
self.socket.on("login", function (data) {
|
||||||
data = (typeof data === "object") ? data : {};
|
data = (typeof data === "object") ? data : {};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ var webserver = require("./webserver");
|
||||||
var sendJade = require("./jade").sendJade;
|
var sendJade = require("./jade").sendJade;
|
||||||
var Logger = require("../logger");
|
var Logger = require("../logger");
|
||||||
var db = require("../database");
|
var db = require("../database");
|
||||||
|
var Config = require("../config");
|
||||||
|
|
||||||
function checkAdmin(cb) {
|
function checkAdmin(cb) {
|
||||||
return function (req, res) {
|
return function (req, res) {
|
||||||
|
@ -40,9 +41,18 @@ function checkAdmin(cb) {
|
||||||
* Handles a request for the ACP
|
* Handles a request for the ACP
|
||||||
*/
|
*/
|
||||||
function handleAcp(req, res, user) {
|
function handleAcp(req, res, user) {
|
||||||
|
var sio;
|
||||||
|
if (req.secure) {
|
||||||
|
sio = Config.get("https.domain") + ":" + Config.get("https.port");
|
||||||
|
} else {
|
||||||
|
sio = Config.get("http.domain") + ":" + Config.get("io.port");
|
||||||
|
}
|
||||||
|
sio += "/socket.io/socket.io.js";
|
||||||
|
|
||||||
sendJade(res, "acp", {
|
sendJade(res, "acp", {
|
||||||
loginName: user.name,
|
loginName: user.name,
|
||||||
loggedIn: true
|
loggedIn: true,
|
||||||
|
sioSource: sio
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,13 +116,19 @@ function handleChannel(req, res) {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
var iourl = "";
|
var sio;
|
||||||
|
if (req.secure) {
|
||||||
|
sio = Config.get("https.domain") + ":" + Config.get("https.port");
|
||||||
|
} else {
|
||||||
|
sio = Config.get("http.domain") + ":" + Config.get("io.port");
|
||||||
|
}
|
||||||
|
sio += "/socket.io/socket.io.js";
|
||||||
|
|
||||||
sendJade(res, "channel", {
|
sendJade(res, "channel", {
|
||||||
channelName: req.params.channel,
|
channelName: req.params.channel,
|
||||||
loggedIn: loginName !== false,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
sioSource: Config.get("http.domain") + ":" + Config.get("io.port") +
|
sioSource: sio
|
||||||
"/socket.io/socket.io.js"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ html(lang="en")
|
||||||
#acp-announcements.col-md-12(style="display: none")
|
#acp-announcements.col-md-12(style="display: none")
|
||||||
h3 Announcements
|
h3 Announcements
|
||||||
h3 New Announcement
|
h3 New Announcement
|
||||||
.col-md-6
|
div(style="max-width: 50%")
|
||||||
form.form-horizontal(action="javascript:void(0)", role="form")
|
form.form-horizontal(action="javascript:void(0)", role="form")
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label.col-sm-2(for="acp-announce-title") Title
|
label.control-label.col-sm-2(for="acp-announce-title") Title
|
||||||
|
@ -54,7 +54,7 @@ html(lang="en")
|
||||||
th IP Address
|
th IP Address
|
||||||
th Note
|
th Note
|
||||||
h3 New Global Ban
|
h3 New Global Ban
|
||||||
.col-md-6
|
div(style="max-width: 50%")
|
||||||
form.form-horizontal(action="javascript:void(0)", role="form")
|
form.form-horizontal(action="javascript:void(0)", role="form")
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label.col-sm-3(for="acp-gban-ip") IP Address
|
label.control-label.col-sm-3(for="acp-gban-ip") IP Address
|
||||||
|
@ -76,10 +76,11 @@ html(lang="en")
|
||||||
table.table.table-bordered.table-striped(style="margin-top: 20px")
|
table.table.table-bordered.table-striped(style="margin-top: 20px")
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th#acp-ulookup-id ID
|
th#acp-users-id ID
|
||||||
th#acp-ulookup-name Name
|
th#acp-users-name Name
|
||||||
th#acp-ulookup-rank Rank
|
th#acp-users-rank Rank
|
||||||
th#acp-ulookup-email Email
|
th#acp-users-email Email
|
||||||
|
th Actions
|
||||||
#acp-channel-lookup.col-md-12(style="display: none")
|
#acp-channel-lookup.col-md-12(style="display: none")
|
||||||
h3 Channels
|
h3 Channels
|
||||||
form.form-inline(action="javascript:void(0)", role="form")
|
form.form-inline(action="javascript:void(0)", role="form")
|
||||||
|
@ -123,4 +124,10 @@ html(lang="en")
|
||||||
|
|
||||||
include footer
|
include footer
|
||||||
mixin footer()
|
mixin footer()
|
||||||
|
script(type="text/javascript").
|
||||||
|
var USEROPTS = { secure_connection: true };
|
||||||
|
script(src=sioSource)
|
||||||
|
script(src="/sioconfig")
|
||||||
|
script(src="/assets/js/util.js")
|
||||||
|
script(src="/assets/js/paginator.js")
|
||||||
script(src="/js/acp.js")
|
script(src="/js/acp.js")
|
||||||
|
|
172
www/js/acp.js
172
www/js/acp.js
|
@ -1,3 +1,18 @@
|
||||||
|
(function () {
|
||||||
|
var opts = {};
|
||||||
|
if (location.protocol === "https:") {
|
||||||
|
opts.secure = true;
|
||||||
|
}
|
||||||
|
window.socket = io.connect(IO_URL, opts);
|
||||||
|
window.socket.on("connect", function () {
|
||||||
|
window.socket.emit("initACP");
|
||||||
|
});
|
||||||
|
|
||||||
|
window.socket.on("errMessage", function (data) {
|
||||||
|
alert(data.msg);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
function addMenuItem(target, text) {
|
function addMenuItem(target, text) {
|
||||||
var ul = $("#nav-acp-section ul");
|
var ul = $("#nav-acp-section ul");
|
||||||
var li = $("<li/>").appendTo(ul);
|
var li = $("<li/>").appendTo(ul);
|
||||||
|
@ -19,6 +34,7 @@ addMenuItem("#acp-loaded-channels", "Active Channels");
|
||||||
addMenuItem("#acp-eventlog", "Event Log");
|
addMenuItem("#acp-eventlog", "Event Log");
|
||||||
addMenuItem("#acp-stats", "Stats");
|
addMenuItem("#acp-stats", "Stats");
|
||||||
|
|
||||||
|
/* Log Viewer */
|
||||||
function readSyslog() {
|
function readSyslog() {
|
||||||
$.ajax(location.protocol + "//" + location.host + "/acp/syslog").done(function (data) {
|
$.ajax(location.protocol + "//" + location.host + "/acp/syslog").done(function (data) {
|
||||||
$("#acp-log").text(data);
|
$("#acp-log").text(data);
|
||||||
|
@ -55,3 +71,159 @@ $("#acp-chanlog-name").keyup(function (ev) {
|
||||||
readChanlog($("#acp-chanlog-name").val());
|
readChanlog($("#acp-chanlog-name").val());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Announcements */
|
||||||
|
$("#acp-announce-submit").click(function () {
|
||||||
|
socket.emit("acp-announce", {
|
||||||
|
title: $("#acp-announce-title").val(),
|
||||||
|
content: $("#acp-announce-content").val()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("announcement", function (data) {
|
||||||
|
$("#acp-announcements").find(".announcement").remove();
|
||||||
|
|
||||||
|
var al = makeAlert(data.title, data.text)
|
||||||
|
.removeClass("col-md-12")
|
||||||
|
.addClass("announcement")
|
||||||
|
.insertAfter($("#acp-announcements h3")[0]);
|
||||||
|
|
||||||
|
al.find(".close").click(function () {
|
||||||
|
socket.emit("acp-announce-clear");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#acp-announce-title").val(data.title);
|
||||||
|
$("#acp-announce-content").val(data.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Global bans */
|
||||||
|
$("#acp-gban-submit").click(function () {
|
||||||
|
socket.emit("acp-gban", {
|
||||||
|
ip: $("#acp-gban-ip").val(),
|
||||||
|
note: $("#acp-gban-note").val()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("acp-gbanlist", function (bans) {
|
||||||
|
var tbl = $("#acp-global-bans table");
|
||||||
|
tbl.find("tbody").remove();
|
||||||
|
|
||||||
|
bans.forEach(function (b) {
|
||||||
|
var tr = $("<tr/>").appendTo(tbl);
|
||||||
|
var td = $("<td/>").appendTo(tr);
|
||||||
|
var del = $("<button/>").addClass("btn btn-xs btn-danger")
|
||||||
|
.html("<span class='glyphicon glyphicon-trash'></span>")
|
||||||
|
.click(function () {
|
||||||
|
socket.emit("acp-gban-delete", b);
|
||||||
|
})
|
||||||
|
.appendTo(td);
|
||||||
|
|
||||||
|
td = $("<td/>").appendTo(tr).html("<code>" + b.ip + "</code>");
|
||||||
|
td = $("<td/>").appendTo(tr).text(b.note);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* User listing */
|
||||||
|
(function () {
|
||||||
|
var doSearch = function () {
|
||||||
|
if ($("#acp-ulookup-name").val().trim() === "") {
|
||||||
|
if (!confirm("You are about to list the entire users table. " +
|
||||||
|
"This table might be very large and take a long " +
|
||||||
|
"time to query. Continue?")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket.emit("acp-list-users", {
|
||||||
|
name: $("#acp-ulookup-name").val()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$("#acp-ulookup-btn").click(doSearch);
|
||||||
|
$("#acp-ulookup-name").keyup(function (ev) {
|
||||||
|
if (ev.keyCode === 13) {
|
||||||
|
doSearch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
socket.on("acp-list-users", function (users) {
|
||||||
|
var tbl = $("#acp-user-lookup table");
|
||||||
|
tbl.data("entries", users);
|
||||||
|
var p = tbl.data("paginator");
|
||||||
|
if (p) {
|
||||||
|
p.paginator.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts = {
|
||||||
|
preLoadPage: function () {
|
||||||
|
tbl.find("tbody").remove();
|
||||||
|
},
|
||||||
|
|
||||||
|
generator: function (u, page, index) {
|
||||||
|
var tr = $("<tr/>").appendTo(tbl);
|
||||||
|
tr.attr("title", u.name + " joined on " + new Date(u.time) + " from " + u.ip);
|
||||||
|
$("<td/>").text(u.id).appendTo(tr);
|
||||||
|
$("<td/>").text(u.name).appendTo(tr);
|
||||||
|
var rank = $("<td/>").text(u.global_rank).appendTo(tr);
|
||||||
|
$("<td/>").text(u.email).appendTo(tr);
|
||||||
|
var reset = $("<td/>").appendTo(tr);
|
||||||
|
|
||||||
|
// Rank editor
|
||||||
|
rank.click(function () {
|
||||||
|
if (rank.find(".rank-edit").length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var old = rank.text();
|
||||||
|
rank.text("");
|
||||||
|
|
||||||
|
var editor = $("<input/>").addClass("rank-edit form-control")
|
||||||
|
.attr("type", "text")
|
||||||
|
.attr("placeholder", old)
|
||||||
|
.appendTo(rank)
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
var save = function () {
|
||||||
|
var newrank = editor.val();
|
||||||
|
if (newrank.trim() === "") {
|
||||||
|
newrank = old;
|
||||||
|
}
|
||||||
|
|
||||||
|
rank.text(old);
|
||||||
|
if (newrank === old) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.emit("acp-set-rank", {
|
||||||
|
name: u.uname,
|
||||||
|
rank: parseInt(newrank)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
editor.blur(save);
|
||||||
|
editor.keydown(function (ev) {
|
||||||
|
if (ev.keyCode === 13) {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Password reset
|
||||||
|
$("<button/>").addClass("btn btn-xs btn-danger")
|
||||||
|
.text("Reset password")
|
||||||
|
.click(function () {
|
||||||
|
if (!confirm("Really reset password for " + u.name + "?")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
socket.emit("acp-reset-password", {
|
||||||
|
name: u.uname,
|
||||||
|
email: u.email
|
||||||
|
});
|
||||||
|
}).appendTo(reset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
p = Paginate(users, opts);
|
||||||
|
p.paginator.insertBefore(tbl);
|
||||||
|
tbl.data("paginator", p);
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue