Skip to content

Commit

Permalink
Admin and back-end fixes
Browse files Browse the repository at this point in the history
* Move other JSON minification to `JSON.stringify` instead of *express-minify*... applies to OpenUserJS#432 and followup for OpenUserJS#899
* Remove some legacy dead code w/ route... can cause server trip
* Add some graceful failures for JSON pages... applies to OpenUserJS#37
* Stop using `res.json` as it's not very configurable... do it manually with `Content-Type` header and such
* Add `virtuals` to JSON output if available
* Fix `find` to `findOne` in moderation removed item routine... removes outer `Array` notation and makes it look more like the model... one would hope there would be a unique id in this case
* Add a missing `charset`

Applies to OpenUserJS#249 and some of OpenUserJS#262
  • Loading branch information
Martii committed Mar 23, 2016
1 parent 457bf11 commit d76c8a9
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 54 deletions.
6 changes: 5 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,11 @@ app.use(function(aReq, aRes, aNext) {
var pathname = aReq._parsedUrl.pathname;

// If a userscript or library...
if (/(\.user)?\.js|\.meta.js(on)?$/.test(pathname) && /^\/(meta|install|src)\//.test(pathname)) {
if (
(/(\.user)?\.js|\.meta.js(on)?$/.test(pathname) && /^\/(meta|install|src)\//.test(pathname)) ||
/^\/admin\/(npm|json)/.test(pathname) ||
/^\/mod\/removed\//.test(pathname)
) {
aRes._skip = true; // ... skip using release minification
}
aNext();
Expand Down
105 changes: 58 additions & 47 deletions controllers/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,33 +68,6 @@ function getOAuthStrategies(aStored) {
return oAuthStrats;
}

// View everything about a particular user
// This is mostly for debugging in production
exports.adminUserView = function (aReq, aRes, aNext) {
var id = aReq.params.id;
var authedUser = aReq.session.user;

if (!userIsAdmin(aReq)) {
aNext();
return;
}

// Nothing fancy, just the stringified user object
User.findOne({ '_id': id, role: { $gt: authedUser.role } },
function (aErr, aUser) {
if (aErr || !aUser) {
aNext();
return;
}

aRes.render('userAdmin', {
user: {
info: JSON.stringify(aUser.toObject(), null, ' ')
}
});
});
};

var jsonModelMap = {
'User': User,
'Script': Script,
Expand All @@ -104,34 +77,49 @@ var jsonModelMap = {
'Vote': Vote,
'Flag': Flag
};
// View everything about a particular user
// This is mostly for debugging in production

// View everything about a particular model
exports.adminJsonView = function (aReq, aRes, aNext) {
//
var authedUser = aReq.session.user;
var modelname = aReq.query.model;
var id = aReq.query.id;

if (!userIsAdmin(aReq)) {
aRes.status(403).send({ status: 403, message: 'Not an admin.' });
statusCodePage(aReq, aRes, aNext, {
statusCode: 403,
statusMessage: 'This page is only accessible by admins.',
});
return;
}

var model = jsonModelMap[modelname];
if (!model) {
aRes.status(400).send({ status: 400, message: 'Invalid model.' });
statusCodePage(aReq, aRes, aNext, {
statusCode: 400,
statusMessage: 'Invalid model.',
});
return;
}

model.findOne({
_id: id
}, function (aErr, aObj) {
if (aErr || !aObj) {
aRes.status(404).send({ status: 404, message: 'Id doesn\'t exist.' });
statusCodePage(aReq, aRes, aNext, {
statusCode: 404,
statusMessage: 'Id doesn\'t exist.',
});
return;
}

aRes.json(aObj);
aRes.set('Content-Type', 'application/json; charset=UTF-8');
aRes.write(JSON.stringify(
aObj.toObject ? aObj.toObject({ virtuals: true }) : aObj,
null,
isPro ? '' : ' ')
);
aRes.end();
});
};

Expand Down Expand Up @@ -161,7 +149,7 @@ exports.adminUserUpdate = function (aReq, aRes, aNext) {
if (!options.isAdmin) {
statusCodePage(aReq, aRes, aNext, {
statusCode: 403,
statusMessage: 'This page is only accessible by admins',
statusMessage: 'This page is only accessible by admins.',
});
return;
}
Expand Down Expand Up @@ -233,7 +221,7 @@ exports.adminPage = function (aReq, aRes, aNext) {
if (!options.isAdmin) {
statusCodePage(aReq, aRes, aNext, {
statusCode: 403,
statusMessage: 'This page is only accessible by admins',
statusMessage: 'This page is only accessible by admins.',
});
return;
}
Expand Down Expand Up @@ -277,7 +265,7 @@ exports.adminApiKeysPage = function (aReq, aRes, aNext) {
if (!options.isAdmin) {
statusCodePage(aReq, aRes, aNext, {
statusCode: 403,
statusMessage: 'This page is only accessible by admins',
statusMessage: 'This page is only accessible by admins.',
});
return;
}
Expand Down Expand Up @@ -313,54 +301,77 @@ exports.adminApiKeysPage = function (aReq, aRes, aNext) {
};

// View everything about current deployed `./package.json`
// This is mostly for debugging in production
exports.adminNpmPackageView = function (aReq, aRes, aNext) {
//

if (!userIsAdmin(aReq)) {
aRes.status(403).send({ status: 403, message: 'Not an admin.' });
statusCodePage(aReq, aRes, aNext, {
statusCode: 403,
statusMessage: 'This page is only accessible by admins.',
});
return;
}

aRes.json(pkg);
aRes.set('Content-Type', 'application/json; charset=UTF-8');
aRes.write(JSON.stringify(pkg, null, isPro ? '' : ' '));
aRes.end();
};

// View everything about current modules for the server
// This is mostly for debugging in production
exports.adminNpmListView = function (aReq, aRes, aNext) {
//

if (!userIsAdmin(aReq)) {
aRes.status(403).send({ status: 403, message: 'Not an admin.' });
statusCodePage(aReq, aRes, aNext, {
statusCode: 403,
statusMessage: 'This page is only accessible by admins.',
});
return;
}

exec('npm ls --json', function (aErr, aStdout, aStderr) {
var stdout = null;

if (aErr) {
console.warn(aErr);
}

try {
aRes.json(JSON.parse(aStdout));
stdout = JSON.parse(aStdout);

} catch (aE) {
aRes.status(520).send({ status: 520, message: 'Unknown error.' });
statusCodePage(aReq, aRes, aNext, {
statusCode: 520,
statusMessage: 'Unknown error.',
});
return;
}

aRes.set('Content-Type', 'application/json; charset=UTF-8');
aRes.write(JSON.stringify(stdout, null, isPro ? '' : ' '));
aRes.end();

});
};

// View current version of npm
// This is mostly for debugging in production
exports.adminNpmVersionView = function (aReq, aRes, aNext) {
//

if (!userIsAdmin(aReq)) {
aRes.status(403).send({ status: 403, message: 'Not an admin.' });
statusCodePage(aReq, aRes, aNext, {
statusCode: 403,
statusMessage: 'This page is only accessible by admins.',
});
return;
}

exec('npm --version', function (aErr, aStdout, aStderr) {
if (aErr) {
aRes.status(501).send({ status: 501, message: 'Not implemented.' });
statusCodePage(aReq, aRes, aNext, {
statusCode: 501,
statusMessage: 'Not implemented.',
});
return;
}

Expand Down Expand Up @@ -456,7 +467,7 @@ exports.authAsUser = function (aReq, aRes, aNext) {
if (!options.isAdmin) {
statusCodePage(aReq, aRes, aNext, {
statusCode: 403,
statusMessage: 'This page is only accessible by admins',
statusMessage: 'This page is only accessible by admins.',
});
return;
}
Expand Down
2 changes: 1 addition & 1 deletion controllers/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ exports.search = function (aReq, aRes) {
var terms = term.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1').split(/\s+/);
var results = null;

aRes.set('Content-Type', 'application/json');
aRes.set('Content-Type', 'application/json; charset=UTF-8');
if (terms.length === 0) {
return aRes.end(JSON.stringify([]));
}
Expand Down
10 changes: 8 additions & 2 deletions controllers/moderation.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,21 @@ exports.removedItemPage = function (aReq, aRes, aNext) {
return;
}

Remove.find({
Remove.findOne({
_id: removedItemId
}, function (aErr, aRemovedItem) {
if (aErr || !aRemovedItem) {
aNext();
return;
}

aRes.json(aRemovedItem);
aRes.set('Content-Type', 'application/json; charset=UTF-8');
aRes.write(JSON.stringify(
aRemovedItem.toObject ? aRemovedItem.toObject({ virtuals: true }) : aRemovedItem,
null,
isPro ? '' : ' ')
);
aRes.end();
});
};

Expand Down
6 changes: 4 additions & 2 deletions controllers/scriptStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -651,8 +651,10 @@ exports.storeScript = function (aUser, aMeta, aBuf, aCallback, aUpdate) {
// Don't save a script if storing failed
if (aErr) {
console.error(aUser.name, '-', installName);
console.error(JSON.stringify(aErr));
console.error(JSON.stringify(aScript.toObject()));
console.error(JSON.stringify(aErr, null, ' '));
console.error(JSON.stringify(
aScript.toObject ? aScript.toObject({ virtuals: true }) : aScript, null, ' ')
);
aCallback(null);
return;
}
Expand Down
1 change: 0 additions & 1 deletion routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ module.exports = function (aApp) {
aApp.route('/admin').get(admin.adminPage);
aApp.route('/admin/authas').get(admin.authAsUser);
aApp.route('/admin/json').get(admin.adminJsonView);
aApp.route('/admin/user/:id').get(admin.adminUserView);
aApp.route('/admin/api').get(admin.adminApiKeysPage);
aApp.route('/admin/npm/package').get(admin.adminNpmPackageView);
aApp.route('/admin/npm/list').get(admin.adminNpmListView);
Expand Down

0 comments on commit d76c8a9

Please sign in to comment.