mirror of https://github.com/calzoneman/sync.git
commit
daec397015
|
@ -97,7 +97,6 @@ io:
|
||||||
# see https://github.com/andris9/Nodemailer
|
# see https://github.com/andris9/Nodemailer
|
||||||
mail:
|
mail:
|
||||||
enabled: false
|
enabled: false
|
||||||
transport: 'SMTP'
|
|
||||||
config:
|
config:
|
||||||
service: 'Gmail'
|
service: 'Gmail'
|
||||||
auth:
|
auth:
|
||||||
|
|
|
@ -59,7 +59,6 @@ var defaults = {
|
||||||
},
|
},
|
||||||
mail: {
|
mail: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
transport: "SMTP",
|
|
||||||
/* the key "config" is omitted because the format depends on the
|
/* the key "config" is omitted because the format depends on the
|
||||||
service the owner is configuring for nodemailer */
|
service the owner is configuring for nodemailer */
|
||||||
"from-address": "some.user@gmail.com"
|
"from-address": "some.user@gmail.com"
|
||||||
|
@ -215,7 +214,6 @@ function preprocessConfig(cfg) {
|
||||||
|
|
||||||
// Setup nodemailer
|
// Setup nodemailer
|
||||||
cfg.mail.nodemailer = nodemailer.createTransport(
|
cfg.mail.nodemailer = nodemailer.createTransport(
|
||||||
cfg.mail.transport,
|
|
||||||
cfg.mail.config
|
cfg.mail.config
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
var sio = require("socket.io");
|
var sio = require("socket.io");
|
||||||
var parseCookie = require("cookie").parse;
|
var cookieParser = require("cookie-parser")();
|
||||||
var Logger = require("../logger");
|
var Logger = require("../logger");
|
||||||
var db = require("../database");
|
var db = require("../database");
|
||||||
var User = require("../user");
|
var User = require("../user");
|
||||||
|
@ -29,8 +29,8 @@ var ipCount = {};
|
||||||
function handleAuth(data, accept) {
|
function handleAuth(data, accept) {
|
||||||
data.user = false;
|
data.user = false;
|
||||||
if (data.headers.cookie) {
|
if (data.headers.cookie) {
|
||||||
data.cookie = parseCookie(data.headers.cookie);
|
cookieParser(data, null, function () {
|
||||||
var auth = data.cookie.auth;
|
var auth = data.cookies.auth;
|
||||||
db.users.verifyAuth(auth, function (err, user) {
|
db.users.verifyAuth(auth, function (err, user) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
data.user = {
|
data.user = {
|
||||||
|
@ -40,6 +40,7 @@ function handleAuth(data, accept) {
|
||||||
}
|
}
|
||||||
accept(null, true);
|
accept(null, true);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
accept(null, true);
|
accept(null, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const VERSION = "3.4.0";
|
const VERSION = "3.5.0";
|
||||||
var singleton = null;
|
var singleton = null;
|
||||||
var Config = require("./config");
|
var Config = require("./config");
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@ var Server = function () {
|
||||||
self.db = null;
|
self.db = null;
|
||||||
self.api = null;
|
self.api = null;
|
||||||
self.announcement = null;
|
self.announcement = null;
|
||||||
self.httplog = null;
|
|
||||||
self.infogetter = null;
|
self.infogetter = null;
|
||||||
self.servers = {};
|
self.servers = {};
|
||||||
self.ioServers = {};
|
self.ioServers = {};
|
||||||
|
@ -64,8 +63,6 @@ var Server = function () {
|
||||||
self.db.init();
|
self.db.init();
|
||||||
|
|
||||||
// webserver init -----------------------------------------------------
|
// webserver init -----------------------------------------------------
|
||||||
self.httplog = new Logger.Logger(path.join(__dirname,
|
|
||||||
"../httpaccess.log"));
|
|
||||||
self.express = express();
|
self.express = express();
|
||||||
require("./web/webserver").init(self.express);
|
require("./web/webserver").init(self.express);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var webserver = require("./webserver");
|
var webserver = require("./webserver");
|
||||||
var logRequest = webserver.logRequest;
|
|
||||||
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");
|
||||||
|
@ -21,7 +20,6 @@ function handleAccountEditPage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logRequest(req);
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
|
@ -45,7 +43,6 @@ function handleAccountEditPage(req, res) {
|
||||||
* Handles a POST request to edit a user"s account
|
* Handles a POST request to edit a user"s account
|
||||||
*/
|
*/
|
||||||
function handleAccountEdit(req, res) {
|
function handleAccountEdit(req, res) {
|
||||||
logRequest(req);
|
|
||||||
var action = req.body.action;
|
var action = req.body.action;
|
||||||
switch(action) {
|
switch(action) {
|
||||||
case "change_password":
|
case "change_password":
|
||||||
|
@ -187,7 +184,6 @@ function handleAccountChannelPage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logRequest(req);
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
|
@ -221,7 +217,6 @@ function handleAccountChannelPage(req, res) {
|
||||||
* Handles a POST request to modify a user"s channels
|
* Handles a POST request to modify a user"s channels
|
||||||
*/
|
*/
|
||||||
function handleAccountChannel(req, res) {
|
function handleAccountChannel(req, res) {
|
||||||
logRequest(req);
|
|
||||||
var action = req.body.action;
|
var action = req.body.action;
|
||||||
switch(action) {
|
switch(action) {
|
||||||
case "new_channel":
|
case "new_channel":
|
||||||
|
@ -240,7 +235,6 @@ function handleAccountChannel(req, res) {
|
||||||
* Handles a request to register a new channel
|
* Handles a request to register a new channel
|
||||||
*/
|
*/
|
||||||
function handleNewChannel(req, res) {
|
function handleNewChannel(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
if (typeof name !== "string") {
|
if (typeof name !== "string") {
|
||||||
|
@ -338,8 +332,6 @@ function handleNewChannel(req, res) {
|
||||||
* Handles a request to delete a new channel
|
* Handles a request to delete a new channel
|
||||||
*/
|
*/
|
||||||
function handleDeleteChannel(req, res) {
|
function handleDeleteChannel(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
if (typeof name !== "string") {
|
if (typeof name !== "string") {
|
||||||
res.send(400);
|
res.send(400);
|
||||||
|
@ -429,8 +421,6 @@ function handleAccountProfilePage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (!req.cookies.auth) {
|
if (!req.cookies.auth) {
|
||||||
return sendJade(res, "account-profile", {
|
return sendJade(res, "account-profile", {
|
||||||
|
@ -475,8 +465,6 @@ function handleAccountProfilePage(req, res) {
|
||||||
* Handles a POST request to edit a profile
|
* Handles a POST request to edit a profile
|
||||||
*/
|
*/
|
||||||
function handleAccountProfile(req, res) {
|
function handleAccountProfile(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
|
@ -535,8 +523,6 @@ function handlePasswordResetPage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
sendJade(res, "account-passwordreset", {
|
sendJade(res, "account-passwordreset", {
|
||||||
reset: false,
|
reset: false,
|
||||||
resetEmail: "",
|
resetEmail: "",
|
||||||
|
@ -548,8 +534,6 @@ function handlePasswordResetPage(req, res) {
|
||||||
* Handles a POST request to reset a user's password
|
* Handles a POST request to reset a user's password
|
||||||
*/
|
*/
|
||||||
function handlePasswordReset(req, res) {
|
function handlePasswordReset(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var name = req.body.name,
|
var name = req.body.name,
|
||||||
email = req.body.email;
|
email = req.body.email;
|
||||||
|
|
||||||
|
@ -668,8 +652,6 @@ function handlePasswordReset(req, res) {
|
||||||
* Handles a request for /account/passwordrecover/<hash>
|
* Handles a request for /account/passwordrecover/<hash>
|
||||||
*/
|
*/
|
||||||
function handlePasswordRecover(req, res) {
|
function handlePasswordRecover(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var hash = req.params.hash;
|
var hash = req.params.hash;
|
||||||
if (typeof hash !== "string") {
|
if (typeof hash !== "string") {
|
||||||
res.send(400);
|
res.send(400);
|
||||||
|
|
|
@ -8,7 +8,6 @@ var Config = require("../config");
|
||||||
|
|
||||||
function checkAdmin(cb) {
|
function checkAdmin(cb) {
|
||||||
return function (req, res) {
|
return function (req, res) {
|
||||||
webserver.logRequest(req);
|
|
||||||
var auth = req.cookies.auth;
|
var auth = req.cookies.auth;
|
||||||
if (!auth) {
|
if (!auth) {
|
||||||
res.send(403);
|
res.send(403);
|
||||||
|
|
|
@ -201,7 +201,7 @@ function handleLogout(req, res) {
|
||||||
ref = "";
|
ref = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
var host = req.host;
|
var host = req.hostname;
|
||||||
if (host.indexOf(Config.get("http.root-domain")) !== -1) {
|
if (host.indexOf(Config.get("http.root-domain")) !== -1) {
|
||||||
res.clearCookie("auth", { domain: Config.get("http.root-domain-dotted") });
|
res.clearCookie("auth", { domain: Config.get("http.root-domain-dotted") });
|
||||||
res.clearCookie("rank", { domain: Config.get("http.root-domain-dotted") });
|
res.clearCookie("rank", { domain: Config.get("http.root-domain-dotted") });
|
||||||
|
|
|
@ -9,26 +9,10 @@ var $util = require("../utilities");
|
||||||
var Logger = require("../logger");
|
var Logger = require("../logger");
|
||||||
var Config = require("../config");
|
var Config = require("../config");
|
||||||
var db = require("../database");
|
var db = require("../database");
|
||||||
|
var bodyParser = require("body-parser");
|
||||||
var httplog = new Logger.Logger(path.join(__dirname, "..", "..", "http.log"));
|
var cookieParser = require("cookie-parser");
|
||||||
|
var static = require("serve-static");
|
||||||
var suspiciousPath = (/admin|adm|\.\.|\/etc\/passwd|\\x5c|%5c|0x5c|setup|install|php|pma|blog|sql|scripts|aspx?|database/ig);
|
var morgan = require("morgan");
|
||||||
/**
|
|
||||||
* Determines whether a request is suspected of being illegitimate
|
|
||||||
*/
|
|
||||||
function isSuspicious(req) {
|
|
||||||
// ZmEu is a penetration script
|
|
||||||
if (req.header("user-agent") &&
|
|
||||||
req.header("user-agent").toLowerCase() === "zmeu") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.path.match(suspiciousPath)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts an IP address from a request. Uses X-Forwarded-For if the IP is localhost
|
* Extracts an IP address from a request. Uses X-Forwarded-For if the IP is localhost
|
||||||
|
@ -53,22 +37,6 @@ function ipForRequest(req) {
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs an HTTP request
|
|
||||||
*/
|
|
||||||
function logRequest(req, status) {
|
|
||||||
if (status === undefined) {
|
|
||||||
status = 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
httplog.log([
|
|
||||||
ipForRequest(req),
|
|
||||||
req.method,
|
|
||||||
req.path,
|
|
||||||
req.header("user-agent")
|
|
||||||
].join(" "));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirects a request to HTTPS if the server supports it
|
* Redirects a request to HTTPS if the server supports it
|
||||||
*/
|
*/
|
||||||
|
@ -102,14 +70,11 @@ function handleChannel(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$util.isValidChannelName(req.params.channel)) {
|
if (!$util.isValidChannelName(req.params.channel)) {
|
||||||
logRequest(req, 404);
|
|
||||||
res.status(404);
|
res.status(404);
|
||||||
res.send("Invalid channel name '" + req.params.channel + "'");
|
res.send("Invalid channel name '" + req.params.channel + "'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
|
@ -138,8 +103,6 @@ function handleChannel(req, res) {
|
||||||
* Handles a request for the index page
|
* Handles a request for the index page
|
||||||
*/
|
*/
|
||||||
function handleIndex(req, res) {
|
function handleIndex(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
|
@ -165,8 +128,6 @@ function handleIndex(req, res) {
|
||||||
* Handles a request for the socket.io information
|
* Handles a request for the socket.io information
|
||||||
*/
|
*/
|
||||||
function handleSocketConfig(req, res) {
|
function handleSocketConfig(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
res.type("application/javascript");
|
res.type("application/javascript");
|
||||||
|
|
||||||
var sioconfig = Config.get("sioconfig");
|
var sioconfig = Config.get("sioconfig");
|
||||||
|
@ -188,8 +149,6 @@ function handleSocketConfig(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleUserAgreement(req, res) {
|
function handleUserAgreement(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
|
@ -203,8 +162,6 @@ function handleUserAgreement(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleContactPage(req, res) {
|
function handleContactPage(req, res) {
|
||||||
logRequest(req);
|
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
|
@ -239,48 +196,20 @@ function handleContactPage(req, res) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function static(dir) {
|
|
||||||
dir = path.join(__dirname, dir);
|
|
||||||
return function (req, res) {
|
|
||||||
try {
|
|
||||||
if (isSuspicious(req)) {
|
|
||||||
logRequest(req, 403);
|
|
||||||
res.status(403);
|
|
||||||
if (typeof req.header("user-agent") === "string" &&
|
|
||||||
req.header("user-agent").toLowerCase() === "zmeu") {
|
|
||||||
res.send("This server disallows requests from ZmEu.");
|
|
||||||
} else {
|
|
||||||
res.send("The request " + req.method.toUpperCase() + " " +
|
|
||||||
req.path + " looks pretty fishy to me. Double check that " +
|
|
||||||
"you typed it correctly.");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.sendfile(req.path.replace(/^\//, ""), {
|
|
||||||
maxAge: Config.get("http.cache-ttl") * 1000,
|
|
||||||
root: dir
|
|
||||||
}, function (err) {
|
|
||||||
logRequest(req);
|
|
||||||
if (err) {
|
|
||||||
res.send(err.status);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
Logger.errlog.log(e);
|
|
||||||
Logger.errlog.log(e.trace);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
/**
|
/**
|
||||||
* Initializes webserver callbacks
|
* Initializes webserver callbacks
|
||||||
*/
|
*/
|
||||||
init: function (app) {
|
init: function (app) {
|
||||||
app.use(express.json());
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
app.use(express.urlencoded());
|
app.use(cookieParser());
|
||||||
app.use(express.cookieParser());
|
app.use(morgan("combined", {
|
||||||
|
stream: require("fs").createWriteStream(path.join(__dirname, "..", "..",
|
||||||
|
"http.log"), {
|
||||||
|
flags: "a",
|
||||||
|
encoding: "utf-8"
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
if (Config.get("http.minify")) {
|
if (Config.get("http.minify")) {
|
||||||
var cache = path.join(__dirname, "..", "..", "www", "cache")
|
var cache = path.join(__dirname, "..", "..", "www", "cache")
|
||||||
|
@ -292,12 +221,7 @@ module.exports = {
|
||||||
}));
|
}));
|
||||||
Logger.syslog.log("Enabled express-minify for CSS and JS");
|
Logger.syslog.log("Enabled express-minify for CSS and JS");
|
||||||
}
|
}
|
||||||
/* Order here is important
|
|
||||||
* Since I placed /r/:channel above *, the function will
|
|
||||||
* not apply to the /r/:channel route. This prevents
|
|
||||||
* duplicate logging, since /r/:channel"s callback does
|
|
||||||
* its own logging
|
|
||||||
*/
|
|
||||||
app.get("/r/:channel", handleChannel);
|
app.get("/r/:channel", handleChannel);
|
||||||
app.get("/", handleIndex);
|
app.get("/", handleIndex);
|
||||||
app.get("/sioconfig", handleSocketConfig);
|
app.get("/sioconfig", handleSocketConfig);
|
||||||
|
@ -306,7 +230,7 @@ module.exports = {
|
||||||
require("./auth").init(app);
|
require("./auth").init(app);
|
||||||
require("./account").init(app);
|
require("./account").init(app);
|
||||||
require("./acp").init(app);
|
require("./acp").init(app);
|
||||||
app.use(static(path.join("..", "..", "www")));
|
app.use(static(path.join(__dirname, "..", "..", "www")));
|
||||||
app.use(function (err, req, res, next) {
|
app.use(function (err, req, res, next) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.message && err.message.match(/failed to decode param/i)) {
|
if (err.message && err.message.match(/failed to decode param/i)) {
|
||||||
|
@ -320,8 +244,6 @@ module.exports = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
logRequest: logRequest,
|
|
||||||
|
|
||||||
ipForRequest: ipForRequest,
|
ipForRequest: ipForRequest,
|
||||||
|
|
||||||
redirectHttps: redirectHttps,
|
redirectHttps: redirectHttps,
|
||||||
|
|
27
package.json
27
package.json
|
@ -2,22 +2,25 @@
|
||||||
"author": "Calvin Montgomery",
|
"author": "Calvin Montgomery",
|
||||||
"name": "CyTube",
|
"name": "CyTube",
|
||||||
"description": "Online media synchronizer and chat",
|
"description": "Online media synchronizer and chat",
|
||||||
"version": "3.4.0",
|
"version": "3.5.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "http://github.com/calzoneman/sync"
|
"url": "http://github.com/calzoneman/sync"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "~3.4.8",
|
"bcrypt": "^0.8.0",
|
||||||
"bcrypt": "~0.7.7",
|
"body-parser": "^1.6.5",
|
||||||
"mysql": "~2.0.1",
|
"cookie-parser": "^1.3.2",
|
||||||
"jade": "~1.1.5",
|
"express": "^4.8.5",
|
||||||
"socket.io": "~0.9.16",
|
"express-minify": "0.0.11",
|
||||||
"nodemailer": "~0.6.0",
|
"jade": "^1.5.0",
|
||||||
"cookie": "~0.1.0",
|
|
||||||
"yamljs": "~0.1.4",
|
|
||||||
"express-minify": "0.0.7",
|
|
||||||
"q": "^1.0.0",
|
|
||||||
"json-typecheck": "^0.1.0",
|
"json-typecheck": "^0.1.0",
|
||||||
"oauth": "^0.9.11"
|
"morgan": "^1.2.3",
|
||||||
|
"mysql": "^2.4.2",
|
||||||
|
"nodemailer": "^1.2.0",
|
||||||
|
"oauth": "^0.9.12",
|
||||||
|
"q": "^1.0.1",
|
||||||
|
"serve-static": "^1.5.3",
|
||||||
|
"socket.io": "~0.9.16",
|
||||||
|
"yamljs": "^0.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theme == null || !theme.match(/^\/css\/themes\/\w+.css$/)) {
|
if (theme == null || !theme.match(/^\/css\/themes\/.+?.css$/)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue