refactor getUserLanguage, automatically apply getUserLanguage and cron middlewares where needed

This commit is contained in:
Matteo Pagliazzi
2016-04-14 13:30:58 +02:00
parent a590a66c47
commit bc9f2b81e7
28 changed files with 507 additions and 431 deletions

View File

@@ -6,7 +6,10 @@ import {
import errorHandler from '../../../../../website/src/middlewares/api-v3/errorHandler'; import errorHandler from '../../../../../website/src/middlewares/api-v3/errorHandler';
import responseMiddleware from '../../../../../website/src/middlewares/api-v3/response'; import responseMiddleware from '../../../../../website/src/middlewares/api-v3/response';
import getUserLanguage from '../../../../../website/src/middlewares/api-v3/getUserLanguage'; import {
getUserLanguage,
attachTranslateFunction,
} from '../../../../../website/src/middlewares/api-v3/language';
import { BadRequest } from '../../../../../website/src/libs/api-v3/errors'; import { BadRequest } from '../../../../../website/src/libs/api-v3/errors';
import logger from '../../../../../website/src/libs/api-v3/logger'; import logger from '../../../../../website/src/libs/api-v3/logger';
@@ -20,6 +23,7 @@ describe('errorHandler', () => {
next = generateNext(); next = generateNext();
responseMiddleware(req, res, next); responseMiddleware(req, res, next);
getUserLanguage(req, res, next); getUserLanguage(req, res, next);
attachTranslateFunction(req, res, next);
sandbox.stub(logger, 'error'); sandbox.stub(logger, 'error');
}); });

View File

@@ -1,267 +0,0 @@
import {
generateRes,
generateReq,
generateNext,
} from '../../../../helpers/api-unit.helper';
import getUserLanguage from '../../../../../website/src/middlewares/api-v3/getUserLanguage';
import { i18n } from '../../../../../common';
import Q from 'q';
import { model as User } from '../../../../../website/src/models/user';
describe('getUserLanguage', () => {
let res, req, next;
let checkResT = (resToCheck) => {
expect(resToCheck.t).to.be.a('function');
expect(resToCheck.t('help')).to.equal(i18n.t('help', req.language));
};
beforeEach(() => {
res = generateRes();
req = generateReq();
next = generateNext();
});
context('query parameter', () => {
it('uses the language in the query parameter if avalaible', () => {
req.query = {
lang: 'es',
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('es');
checkResT(res);
});
it('falls back to english if the query parameter language does not exists', () => {
req.query = {
lang: 'bla',
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('en');
checkResT(res);
});
it('uses query even if the request includes a user and session', () => {
req.query = {
lang: 'es',
};
req.locals = {
user: {
preferences: {
language: 'it',
},
},
};
req.session = {
userId: 123,
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('es');
checkResT(res);
});
});
context('authorized request', () => {
it('uses the user preferred language if avalaible', () => {
req.locals = {
user: {
preferences: {
language: 'it',
},
},
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('it');
checkResT(res);
});
it('falls back to english if the user preferred language is not avalaible', (done) => {
req.locals = {
user: {
preferences: {
language: 'bla',
},
},
};
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
checkResT(res);
done();
});
});
it('uses the user preferred language even if a session is included in request', () => {
req.locals = {
user: {
preferences: {
language: 'it',
},
},
};
req.session = {
userId: 123,
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('it');
checkResT(res);
});
});
context('request with session', () => {
it('uses the user preferred language if avalaible', (done) => {
sandbox.stub(User, 'findOne').returns({
lean () {
return this;
},
exec () {
return Q.resolve({
preferences: {
language: 'it',
},
});
},
});
req.session = {
userId: 123,
};
getUserLanguage(req, res, () => {
expect(req.language).to.equal('it');
checkResT(res);
done();
});
});
});
context('browser fallback', () => {
it('uses browser specificed language', (done) => {
req.headers['accept-language'] = 'pt';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('pt');
checkResT(res);
done();
});
});
it('uses first language in series if browser specifies multiple', (done) => {
req.headers['accept-language'] = 'he, pt, it';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('he');
checkResT(res);
done();
});
});
it('skips invalid lanaguages and uses first language in series if browser specifies multiple', (done) => {
req.headers['accept-language'] = 'blah, he, pt, it';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('he');
checkResT(res);
done();
});
});
it('uses normal version of language if specialized locale is passed in', (done) => {
req.headers['accept-language'] = 'fr-CA';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('fr');
checkResT(res);
done();
});
});
it('uses normal version of language if specialized locale is passed in', (done) => {
req.headers['accept-language'] = 'fr-CA';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('fr');
checkResT(res);
done();
});
});
it('uses es if es is passed in', (done) => {
req.headers['accept-language'] = 'es';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es');
checkResT(res);
done();
});
});
it('uses es_419 if applicable es-languages are passed in', (done) => {
req.headers['accept-language'] = 'es-mx';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es_419');
checkResT(res);
done();
});
});
it('uses es_419 if multiple es languages are passed in', (done) => {
req.headers['accept-language'] = 'es-GT, es-MX, es-CR';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es_419');
checkResT(res);
done();
});
});
it('zh', (done) => {
req.headers['accept-language'] = 'zh-TW';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('zh_TW');
checkResT(res);
done();
});
});
it('uses english if browser specified language is not compatible', (done) => {
req.headers['accept-language'] = 'blah';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
checkResT(res);
done();
});
});
it('uses english if browser does not specify', (done) => {
req.headers['accept-language'] = '';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
checkResT(res);
done();
});
});
it('uses english if browser does not supply an accept-language header', (done) => {
delete req.headers['accept-language'];
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
checkResT(res);
done();
});
});
});
});

View File

@@ -0,0 +1,307 @@
import {
generateRes,
generateReq,
generateNext,
} from '../../../../helpers/api-unit.helper';
import {
getUserLanguage,
attachTranslateFunction,
} from '../../../../../website/src/middlewares/api-v3/language';
import common from '../../../../../common';
import Q from 'q';
import { model as User } from '../../../../../website/src/models/user';
const i18n = common.i18n;
describe('language middleware', () => {
describe('res.t', () => {
let res, req, next;
beforeEach(() => {
res = generateRes();
req = generateReq();
next = generateNext();
sinon.stub(i18n, 't');
});
afterEach(() => {
i18n.t.restore();
});
it('attaches t method to res', () => {
attachTranslateFunction(req, res, next);
expect(res.t).to.exist;
});
it('uses the language specified in req.language', () => {
req.language = 'de';
attachTranslateFunction(req, res, next);
res.t(1, 2);
expect(i18n.t).to.be.calledOnce;
expect(i18n.t).to.be.calledWith(1, 2);
});
});
describe('getUserLanguage', () => {
let res, req, next;
let checkResT = (resToCheck) => {
expect(resToCheck.t).to.be.a('function');
expect(resToCheck.t('help')).to.equal(i18n.t('help', req.language));
};
beforeEach(() => {
res = generateRes();
req = generateReq();
next = generateNext();
attachTranslateFunction(req, res, next);
});
context('query parameter', () => {
it('uses the language in the query parameter if avalaible', () => {
req.query = {
lang: 'es',
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('es');
checkResT(res);
});
it('falls back to english if the query parameter language does not exists', () => {
req.query = {
lang: 'bla',
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('en');
checkResT(res);
});
it('uses query even if the request includes a user and session', () => {
req.query = {
lang: 'es',
};
req.locals = {
user: {
preferences: {
language: 'it',
},
},
};
req.session = {
userId: 123,
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('es');
checkResT(res);
});
});
context('authorized request', () => {
it('uses the user preferred language if avalaible', () => {
req.locals = {
user: {
preferences: {
language: 'it',
},
},
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('it');
checkResT(res);
});
it('falls back to english if the user preferred language is not avalaible', (done) => {
req.locals = {
user: {
preferences: {
language: 'bla',
},
},
};
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
checkResT(res);
done();
});
});
it('uses the user preferred language even if a session is included in request', () => {
req.locals = {
user: {
preferences: {
language: 'it',
},
},
};
req.session = {
userId: 123,
};
getUserLanguage(req, res, next);
expect(req.language).to.equal('it');
checkResT(res);
});
});
context('request with session', () => {
it('uses the user preferred language if avalaible', (done) => {
sandbox.stub(User, 'findOne').returns({
lean () {
return this;
},
exec () {
return Q.resolve({
preferences: {
language: 'it',
},
});
},
});
req.session = {
userId: 123,
};
getUserLanguage(req, res, () => {
expect(req.language).to.equal('it');
checkResT(res);
done();
});
});
});
context('browser fallback', () => {
it('uses browser specificed language', (done) => {
req.headers['accept-language'] = 'pt';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('pt');
checkResT(res);
done();
});
});
it('uses first language in series if browser specifies multiple', (done) => {
req.headers['accept-language'] = 'he, pt, it';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('he');
checkResT(res);
done();
});
});
it('skips invalid lanaguages and uses first language in series if browser specifies multiple', (done) => {
req.headers['accept-language'] = 'blah, he, pt, it';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('he');
checkResT(res);
done();
});
});
it('uses normal version of language if specialized locale is passed in', (done) => {
req.headers['accept-language'] = 'fr-CA';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('fr');
checkResT(res);
done();
});
});
it('uses normal version of language if specialized locale is passed in', (done) => {
req.headers['accept-language'] = 'fr-CA';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('fr');
checkResT(res);
done();
});
});
it('uses es if es is passed in', (done) => {
req.headers['accept-language'] = 'es';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es');
checkResT(res);
done();
});
});
it('uses es_419 if applicable es-languages are passed in', (done) => {
req.headers['accept-language'] = 'es-mx';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es_419');
checkResT(res);
done();
});
});
it('uses es_419 if multiple es languages are passed in', (done) => {
req.headers['accept-language'] = 'es-GT, es-MX, es-CR';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es_419');
checkResT(res);
done();
});
});
it('zh', (done) => {
req.headers['accept-language'] = 'zh-TW';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('zh_TW');
checkResT(res);
done();
});
});
it('uses english if browser specified language is not compatible', (done) => {
req.headers['accept-language'] = 'blah';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
checkResT(res);
done();
});
});
it('uses english if browser does not specify', (done) => {
req.headers['accept-language'] = '';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
checkResT(res);
done();
});
});
it('uses english if browser does not supply an accept-language header', (done) => {
delete req.headers['accept-language'];
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
checkResT(res);
done();
});
});
});
});
});

View File

@@ -6,7 +6,6 @@ import {
authWithHeaders, authWithHeaders,
authWithSession, authWithSession,
} from '../../middlewares/api-v3/auth'; } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import { import {
NotAuthorized, NotAuthorized,
BadRequest, BadRequest,
@@ -232,7 +231,6 @@ function _passportFbProfile (accessToken) {
api.loginSocial = { api.loginSocial = {
method: 'POST', method: 'POST',
url: '/user/auth/social', // this isn't the most appropriate url but must be the same as v2 url: '/user/auth/social', // this isn't the most appropriate url but must be the same as v2
middlewares: [cron],
async handler (req, res) { async handler (req, res) {
let accessToken = req.body.authResponse.access_token; let accessToken = req.body.authResponse.access_token;
let network = req.body.network; let network = req.body.network;
@@ -292,7 +290,7 @@ api.loginSocial = {
**/ **/
api.updateUsername = { api.updateUsername = {
method: 'PUT', method: 'PUT',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/auth/update-username', url: '/user/auth/update-username',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -338,7 +336,7 @@ api.updateUsername = {
**/ **/
api.updatePassword = { api.updatePassword = {
method: 'PUT', method: 'PUT',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/auth/update-password', url: '/user/auth/update-password',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -428,7 +426,7 @@ api.resetPassword = {
*/ */
api.updateEmail = { api.updateEmail = {
method: 'PUT', method: 'PUT',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/auth/update-email', url: '/user/auth/update-email',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -456,7 +454,7 @@ const firebaseTokenGenerator = new FirebaseTokenGenerator(nconf.get('FIREBASE:SE
api.getFirebaseToken = { api.getFirebaseToken = {
method: 'POST', method: 'POST',
url: '/user/auth/firebase', url: '/user/auth/firebase',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
// Expires 24 hours from now (60*60*24*1000) (in milliseconds) // Expires 24 hours from now (60*60*24*1000) (in milliseconds)
@@ -483,7 +481,7 @@ api.getFirebaseToken = {
api.deleteSocial = { api.deleteSocial = {
method: 'DELETE', method: 'DELETE',
url: '/user/auth/social/:network', url: '/user/auth/social/:network',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let network = req.params.network; let network = req.params.network;
@@ -501,7 +499,7 @@ api.deleteSocial = {
api.logout = { api.logout = {
method: 'GET', method: 'GET',
url: '/user/auth/logout', // TODO this is under /api/v3 route, should be accessible through habitica.com/logout url: '/user/auth/logout', // TODO this is under /api/v3 route, should be accessible through habitica.com/logout
middlewares: [authWithSession, cron], middlewares: [authWithSession],
async handler (req, res) { async handler (req, res) {
req.logout(); // passportjs method req.logout(); // passportjs method
req.session = null; req.session = null;

View File

@@ -1,6 +1,5 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import _ from 'lodash'; import _ from 'lodash';
import cron from '../../middlewares/api-v3/cron';
import { model as Challenge } from '../../models/challenge'; import { model as Challenge } from '../../models/challenge';
import { import {
model as Group, model as Group,
@@ -35,7 +34,7 @@ let api = {};
api.createChallenge = { api.createChallenge = {
method: 'POST', method: 'POST',
url: '/challenges', url: '/challenges',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -125,7 +124,7 @@ api.createChallenge = {
api.joinChallenge = { api.joinChallenge = {
method: 'POST', method: 'POST',
url: '/challenges/:challengeId/join', url: '/challenges/:challengeId/join',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -171,7 +170,7 @@ api.joinChallenge = {
api.leaveChallenge = { api.leaveChallenge = {
method: 'POST', method: 'POST',
url: '/challenges/:challengeId/leave', url: '/challenges/:challengeId/leave',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let keep = req.body.keep === 'remove-all' ? 'remove-all' : 'keep-all'; let keep = req.body.keep === 'remove-all' ? 'remove-all' : 'keep-all';
@@ -208,7 +207,7 @@ api.leaveChallenge = {
api.getUserChallenges = { api.getUserChallenges = {
method: 'GET', method: 'GET',
url: '/challenges/user', url: '/challenges/user',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -254,7 +253,7 @@ api.getUserChallenges = {
api.getGroupChallenges = { api.getGroupChallenges = {
method: 'GET', method: 'GET',
url: '/challenges/groups/:groupId', url: '/challenges/groups/:groupId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let groupId = req.params.groupId; let groupId = req.params.groupId;
@@ -297,7 +296,7 @@ api.getGroupChallenges = {
api.getChallenge = { api.getChallenge = {
method: 'GET', method: 'GET',
url: '/challenges/:challengeId', url: '/challenges/:challengeId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
@@ -339,7 +338,7 @@ api.getChallenge = {
api.exportChallengeCsv = { api.exportChallengeCsv = {
method: 'GET', method: 'GET',
url: '/challenges/:challengeId/export/csv', url: '/challenges/:challengeId/export/csv',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
@@ -412,7 +411,7 @@ api.exportChallengeCsv = {
api.updateChallenge = { api.updateChallenge = {
method: 'PUT', method: 'PUT',
url: '/challenges/:challengeId', url: '/challenges/:challengeId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
@@ -513,7 +512,7 @@ export async function _closeChal (challenge, broken = {}) {
api.deleteChallenge = { api.deleteChallenge = {
method: 'DELETE', method: 'DELETE',
url: '/challenges/:challengeId', url: '/challenges/:challengeId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -543,7 +542,7 @@ api.deleteChallenge = {
api.selectChallengeWinner = { api.selectChallengeWinner = {
method: 'POST', method: 'POST',
url: '/challenges/:challengeId/selectWinner/:winnerId', url: '/challenges/:challengeId/selectWinner/:winnerId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;

View File

@@ -1,5 +1,4 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import { import {
model as Group, model as Group,
TAVERN_ID, TAVERN_ID,
@@ -33,7 +32,7 @@ let api = {};
api.getChat = { api.getChat = {
method: 'GET', method: 'GET',
url: '/groups/:groupId/chat', url: '/groups/:groupId/chat',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -64,7 +63,7 @@ api.getChat = {
api.postChat = { api.postChat = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/chat', url: '/groups/:groupId/chat',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let groupId = req.params.groupId; let groupId = req.params.groupId;
@@ -116,7 +115,7 @@ api.postChat = {
api.likeChat = { api.likeChat = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/chat/:chatId/like', url: '/groups/:groupId/chat/:chatId/like',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let groupId = req.params.groupId; let groupId = req.params.groupId;
@@ -163,7 +162,7 @@ api.likeChat = {
api.flagChat = { api.flagChat = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/chat/:chatId/flag', url: '/groups/:groupId/chat/:chatId/flag',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let groupId = req.params.groupId; let groupId = req.params.groupId;
@@ -268,7 +267,7 @@ api.flagChat = {
api.clearChatFlags = { api.clearChatFlags = {
method: 'Post', method: 'Post',
url: '/groups/:groupId/chat/:chatId/clearflags', url: '/groups/:groupId/chat/:chatId/clearflags',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let groupId = req.params.groupId; let groupId = req.params.groupId;
@@ -312,7 +311,7 @@ api.clearChatFlags = {
api.seenChat = { api.seenChat = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/chat/seen', url: '/groups/:groupId/chat/seen',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let groupId = req.params.groupId; let groupId = req.params.groupId;
@@ -348,7 +347,7 @@ api.seenChat = {
api.deleteChat = { api.deleteChat = {
method: 'DELETE', method: 'DELETE',
url: '/groups/:groupId/chat/:chatId', url: '/groups/:groupId/chat/:chatId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let groupId = req.params.groupId; let groupId = req.params.groupId;

View File

@@ -3,7 +3,6 @@ import {
authWithHeaders, authWithHeaders,
authWithSession, authWithSession,
} from '../../middlewares/api-v3/auth'; } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import { ensureSudo } from '../../middlewares/api-v3/ensureAccessRight'; import { ensureSudo } from '../../middlewares/api-v3/ensureAccessRight';
import { model as Coupon } from '../../models/coupon'; import { model as Coupon } from '../../models/coupon';
import _ from 'lodash'; import _ from 'lodash';
@@ -22,7 +21,7 @@ let api = {};
api.getCoupons = { api.getCoupons = {
method: 'GET', method: 'GET',
url: '/coupons', url: '/coupons',
middlewares: [authWithSession, cron, ensureSudo], middlewares: [authWithSession, ensureSudo],
async handler (req, res) { async handler (req, res) {
let coupons = await Coupon.find().sort('createdAt').lean().exec(); let coupons = await Coupon.find().sort('createdAt').lean().exec();
@@ -53,7 +52,7 @@ api.getCoupons = {
api.generateCoupons = { api.generateCoupons = {
method: 'POST', method: 'POST',
url: '/coupons/generate/:event', url: '/coupons/generate/:event',
middlewares: [authWithHeaders(), cron, ensureSudo], middlewares: [authWithHeaders(), ensureSudo],
async handler (req, res) { async handler (req, res) {
req.checkParams('event', res.t('eventRequired')).notEmpty(); req.checkParams('event', res.t('eventRequired')).notEmpty();
req.checkQuery('count', res.t('countRequired')).notEmpty().isNumeric(); req.checkQuery('count', res.t('countRequired')).notEmpty().isNumeric();
@@ -79,7 +78,7 @@ api.generateCoupons = {
api.enterCouponCode = { api.enterCouponCode = {
method: 'POST', method: 'POST',
url: '/coupons/enter/:code', url: '/coupons/enter/:code',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;

View File

@@ -1,15 +1,8 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import ensureDevelpmentMode from '../../middlewares/api-v3/ensureDevelpmentMode'; import ensureDevelpmentMode from '../../middlewares/api-v3/ensureDevelpmentMode';
let api = {}; let api = {};
api.debug = {
method: 'all',
url: '/debug/*',
middlewares: [ensureDevelpmentMode, authWithHeaders(), cron],
};
/** /**
* @api {post} /debug/add-ten-gems Add ten gems to the current user * @api {post} /debug/add-ten-gems Add ten gems to the current user
* @apiVersion 3.0.0 * @apiVersion 3.0.0
@@ -21,6 +14,7 @@ api.debug = {
api.addTenGems = { api.addTenGems = {
method: 'POST', method: 'POST',
url: '/debug/add-ten-gems', url: '/debug/add-ten-gems',
middlewares: [ensureDevelpmentMode, authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -43,6 +37,7 @@ api.addTenGems = {
api.addHourglass = { api.addHourglass = {
method: 'POST', method: 'POST',
url: '/debug/add-hourglass', url: '/debug/add-hourglass',
middlewares: [ensureDevelpmentMode, authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;

View File

@@ -1,7 +1,6 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import Q from 'q'; import Q from 'q';
import _ from 'lodash'; import _ from 'lodash';
import cron from '../../middlewares/api-v3/cron';
import { import {
INVITES_LIMIT, INVITES_LIMIT,
model as Group, model as Group,
@@ -38,7 +37,7 @@ let api = {};
api.createGroup = { api.createGroup = {
method: 'POST', method: 'POST',
url: '/groups', url: '/groups',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let group = new Group(Group.sanitize(req.body)); // TODO validate empty req.body let group = new Group(Group.sanitize(req.body)); // TODO validate empty req.body
@@ -89,7 +88,7 @@ api.createGroup = {
api.getGroups = { api.getGroups = {
method: 'GET', method: 'GET',
url: '/groups', url: '/groups',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -125,7 +124,7 @@ api.getGroups = {
api.getGroup = { api.getGroup = {
method: 'GET', method: 'GET',
url: '/groups/:groupId', url: '/groups/:groupId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -159,7 +158,7 @@ api.getGroup = {
api.updateGroup = { api.updateGroup = {
method: 'PUT', method: 'PUT',
url: '/groups/:groupId', url: '/groups/:groupId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -205,7 +204,7 @@ api.updateGroup = {
api.joinGroup = { api.joinGroup = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/join', url: '/groups/:groupId/join',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let inviter; let inviter;
@@ -296,7 +295,7 @@ api.joinGroup = {
api.rejectGroupInvite = { api.rejectGroupInvite = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/reject-invite', url: '/groups/:groupId/reject-invite',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -342,7 +341,7 @@ api.rejectGroupInvite = {
api.leaveGroup = { api.leaveGroup = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/leave', url: '/groups/:groupId/leave',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -399,7 +398,7 @@ function _sendMessageToRemoved (group, removedUser, message) {
api.removeGroupMember = { api.removeGroupMember = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/removeMember/:memberId', url: '/groups/:groupId/removeMember/:memberId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -602,7 +601,7 @@ async function _inviteByEmail (invite, group, inviter, req, res) {
api.inviteToGroup = { api.inviteToGroup = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/invite', url: '/groups/:groupId/invite',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;

View File

@@ -1,6 +1,5 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { ensureAdmin } from '../../middlewares/api-v3/ensureAccessRight'; import { ensureAdmin } from '../../middlewares/api-v3/ensureAccessRight';
import cron from '../../middlewares/api-v3/cron';
import { model as User } from '../../models/user'; import { model as User } from '../../models/user';
import { import {
NotFound, NotFound,
@@ -22,7 +21,7 @@ let api = {};
api.getPatrons = { api.getPatrons = {
method: 'GET', method: 'GET',
url: '/hall/patrons', url: '/hall/patrons',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkQuery('page', res.t('pageMustBeNumber')).optional().isNumeric(); req.checkQuery('page', res.t('pageMustBeNumber')).optional().isNumeric();
@@ -58,7 +57,7 @@ api.getPatrons = {
api.getHeroes = { api.getHeroes = {
method: 'GET', method: 'GET',
url: '/hall/heroes', url: '/hall/heroes',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let heroes = await User let heroes = await User
.find({ .find({
@@ -90,7 +89,7 @@ const heroAdminFields = 'contributor balance profile.name purchased items auth';
api.getHero = { api.getHero = {
method: 'GET', method: 'GET',
url: '/hall/heroes/:heroId', url: '/hall/heroes/:heroId',
middlewares: [authWithHeaders(), cron, ensureAdmin], middlewares: [authWithHeaders(), ensureAdmin],
async handler (req, res) { async handler (req, res) {
let heroId = req.params.heroId; let heroId = req.params.heroId;
@@ -127,7 +126,7 @@ const gemsPerTier = {1: 3, 2: 3, 3: 3, 4: 4, 5: 4, 6: 4, 7: 4, 8: 0, 9: 0};
api.updateHero = { api.updateHero = {
method: 'PUT', method: 'PUT',
url: '/hall/heroes/:heroId', url: '/hall/heroes/:heroId',
middlewares: [authWithHeaders(), cron, ensureAdmin], middlewares: [authWithHeaders(), ensureAdmin],
async handler (req, res) { async handler (req, res) {
let heroId = req.params.heroId; let heroId = req.params.heroId;
let updateData = req.body; let updateData = req.body;

View File

@@ -1,5 +1,4 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import { import {
model as User, model as User,
publicFields as memberFields, publicFields as memberFields,
@@ -33,7 +32,7 @@ let api = {};
api.getMember = { api.getMember = {
method: 'GET', method: 'GET',
url: '/members/:memberId', url: '/members/:memberId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID(); req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
@@ -144,7 +143,7 @@ function _getMembersForItem (type) {
api.getMembersForGroup = { api.getMembersForGroup = {
method: 'GET', method: 'GET',
url: '/groups/:groupId/members', url: '/groups/:groupId/members',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
handler: _getMembersForItem('group-members'), handler: _getMembersForItem('group-members'),
}; };
@@ -162,7 +161,7 @@ api.getMembersForGroup = {
api.getInvitesForGroup = { api.getInvitesForGroup = {
method: 'GET', method: 'GET',
url: '/groups/:groupId/invites', url: '/groups/:groupId/invites',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
handler: _getMembersForItem('group-invites'), handler: _getMembersForItem('group-invites'),
}; };
@@ -180,7 +179,7 @@ api.getInvitesForGroup = {
api.getMembersForChallenge = { api.getMembersForChallenge = {
method: 'GET', method: 'GET',
url: '/challenges/:challengeId/members', url: '/challenges/:challengeId/members',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
handler: _getMembersForItem('challenge-members'), handler: _getMembersForItem('challenge-members'),
}; };
@@ -198,7 +197,7 @@ api.getMembersForChallenge = {
api.getChallengeMemberProgress = { api.getChallengeMemberProgress = {
method: 'GET', method: 'GET',
url: '/challenges/:challengeId/members/:memberId', url: '/challenges/:challengeId/members/:memberId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID(); req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
@@ -251,7 +250,7 @@ api.getChallengeMemberProgress = {
api.sendPrivateMessage = { api.sendPrivateMessage = {
method: 'POST', method: 'POST',
url: '/members/send-private-message', url: '/members/send-private-message',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkBody('message', res.t('messageRequired')).notEmpty(); req.checkBody('message', res.t('messageRequired')).notEmpty();
req.checkBody('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID(); req.checkBody('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID();
@@ -300,7 +299,7 @@ api.sendPrivateMessage = {
api.transferGems = { api.transferGems = {
method: 'POST', method: 'POST',
url: '/members/transfer-gems', url: '/members/transfer-gems',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkBody('message', res.t('messageRequired')).notEmpty(); req.checkBody('message', res.t('messageRequired')).notEmpty();
req.checkBody('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID(); req.checkBody('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID();

View File

@@ -1,7 +1,6 @@
import _ from 'lodash'; import _ from 'lodash';
import Q from 'q'; import Q from 'q';
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import analytics from '../../libs/api-v3/analyticsService'; import analytics from '../../libs/api-v3/analyticsService';
import { import {
model as Group, model as Group,
@@ -42,7 +41,7 @@ let api = {};
api.inviteToQuest = { api.inviteToQuest = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/quests/invite/:questKey', url: '/groups/:groupId/quests/invite/:questKey',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let questKey = req.params.questKey; let questKey = req.params.questKey;
@@ -145,7 +144,7 @@ api.inviteToQuest = {
api.acceptQuest = { api.acceptQuest = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/quests/accept', url: '/groups/:groupId/quests/accept',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -202,7 +201,7 @@ api.acceptQuest = {
api.rejectQuest = { api.rejectQuest = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/quests/reject', url: '/groups/:groupId/quests/reject',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -261,7 +260,7 @@ api.rejectQuest = {
api.forceStart = { api.forceStart = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/quests/force-start', url: '/groups/:groupId/quests/force-start',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -313,7 +312,7 @@ api.forceStart = {
api.cancelQuest = { api.cancelQuest = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/quests/cancel', url: '/groups/:groupId/quests/cancel',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
// Cancel a quest BEFORE it has begun (i.e., in the invitation stage) // Cancel a quest BEFORE it has begun (i.e., in the invitation stage)
// Quest scroll has not yet left quest owner's inventory so no need to return it. // Quest scroll has not yet left quest owner's inventory so no need to return it.
@@ -362,7 +361,7 @@ api.cancelQuest = {
api.abortQuest = { api.abortQuest = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/quests/abort', url: '/groups/:groupId/quests/abort',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
// Abort a quest AFTER it has begun (see questCancel for BEFORE) // Abort a quest AFTER it has begun (see questCancel for BEFORE)
let user = res.locals.user; let user = res.locals.user;
@@ -416,7 +415,7 @@ api.abortQuest = {
api.leaveQuest = { api.leaveQuest = {
method: 'POST', method: 'POST',
url: '/groups/:groupId/quests/leave', url: '/groups/:groupId/quests/leave',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let groupId = req.params.groupId; let groupId = req.params.groupId;

View File

@@ -1,5 +1,4 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import { model as Tag } from '../../models/tag'; import { model as Tag } from '../../models/tag';
import * as Tasks from '../../models/task'; import * as Tasks from '../../models/task';
import { import {
@@ -20,7 +19,7 @@ let api = {};
api.createTag = { api.createTag = {
method: 'POST', method: 'POST',
url: '/tags', url: '/tags',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -44,7 +43,7 @@ api.createTag = {
api.getTags = { api.getTags = {
method: 'GET', method: 'GET',
url: '/tags', url: '/tags',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
res.respond(200, user.tags); res.respond(200, user.tags);
@@ -64,7 +63,7 @@ api.getTags = {
api.getTag = { api.getTag = {
method: 'GET', method: 'GET',
url: '/tags/:tagId', url: '/tags/:tagId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -92,7 +91,7 @@ api.getTag = {
api.updateTag = { api.updateTag = {
method: 'PUT', method: 'PUT',
url: '/tags/:tagId', url: '/tags/:tagId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -126,7 +125,7 @@ api.updateTag = {
api.deleteTag = { api.deleteTag = {
method: 'DELETE', method: 'DELETE',
url: '/tags/:tagId', url: '/tags/:tagId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;

View File

@@ -1,5 +1,4 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import { sendTaskWebhook } from '../../libs/api-v3/webhook'; import { sendTaskWebhook } from '../../libs/api-v3/webhook';
import { removeFromArray } from '../../libs/api-v3/collectionManipulators'; import { removeFromArray } from '../../libs/api-v3/collectionManipulators';
import * as Tasks from '../../models/task'; import * as Tasks from '../../models/task';
@@ -66,7 +65,7 @@ async function _createTasks (req, res, user, challenge) {
api.createUserTasks = { api.createUserTasks = {
method: 'POST', method: 'POST',
url: '/tasks/user', url: '/tasks/user',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let tasks = await _createTasks(req, res, res.locals.user); let tasks = await _createTasks(req, res, res.locals.user);
res.respond(201, tasks.length === 1 ? tasks[0] : tasks); res.respond(201, tasks.length === 1 ? tasks[0] : tasks);
@@ -87,7 +86,7 @@ api.createUserTasks = {
api.createChallengeTasks = { api.createChallengeTasks = {
method: 'POST', method: 'POST',
url: '/tasks/challenge/:challengeId', // TODO should be /tasks/challengeS/:challengeId ? plural? url: '/tasks/challenge/:challengeId', // TODO should be /tasks/challengeS/:challengeId ? plural?
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
@@ -177,7 +176,7 @@ async function _getTasks (req, res, user, challenge) {
api.getUserTasks = { api.getUserTasks = {
method: 'GET', method: 'GET',
url: '/tasks/user', url: '/tasks/user',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let types = Tasks.tasksTypes.map(type => `${type}s`); let types = Tasks.tasksTypes.map(type => `${type}s`);
types.push('completedTodos'); types.push('completedTodos');
@@ -204,7 +203,7 @@ api.getUserTasks = {
api.getChallengeTasks = { api.getChallengeTasks = {
method: 'GET', method: 'GET',
url: '/tasks/challenge/:challengeId', url: '/tasks/challenge/:challengeId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
let types = Tasks.tasksTypes.map(type => `${type}s`); let types = Tasks.tasksTypes.map(type => `${type}s`);
@@ -238,7 +237,7 @@ api.getChallengeTasks = {
api.getTask = { api.getTask = {
method: 'GET', method: 'GET',
url: '/tasks/:taskId', url: '/tasks/:taskId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -279,7 +278,7 @@ api.getTask = {
api.updateTask = { api.updateTask = {
method: 'PUT', method: 'PUT',
url: '/tasks/:taskId', url: '/tasks/:taskId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let challenge; let challenge;
@@ -357,7 +356,7 @@ function _generateWebhookTaskData (task, direction, delta, stats, user) {
api.scoreTask = { api.scoreTask = {
method: 'POST', method: 'POST',
url: '/tasks/:taskId/score/:direction', url: '/tasks/:taskId/score/:direction',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID(); req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID();
req.checkParams('direction', res.t('directionUpDown')).notEmpty().isIn(['up', 'down']); // TODO what about rewards? maybe separate route? req.checkParams('direction', res.t('directionUpDown')).notEmpty().isIn(['up', 'down']); // TODO what about rewards? maybe separate route?
@@ -440,7 +439,7 @@ api.scoreTask = {
api.moveTask = { api.moveTask = {
method: 'POST', method: 'POST',
url: '/tasks/:taskId/move/to/:position', url: '/tasks/:taskId/move/to/:position',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID(); req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID();
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric(); req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
@@ -494,7 +493,7 @@ api.moveTask = {
api.addChecklistItem = { api.addChecklistItem = {
method: 'POST', method: 'POST',
url: '/tasks/:taskId/checklist', url: '/tasks/:taskId/checklist',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let challenge; let challenge;
@@ -543,7 +542,7 @@ api.addChecklistItem = {
api.scoreCheckListItem = { api.scoreCheckListItem = {
method: 'POST', method: 'POST',
url: '/tasks/:taskId/checklist/:itemId/score', url: '/tasks/:taskId/checklist/:itemId/score',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -585,7 +584,7 @@ api.scoreCheckListItem = {
api.updateChecklistItem = { api.updateChecklistItem = {
method: 'PUT', method: 'PUT',
url: '/tasks/:taskId/checklist/:itemId', url: '/tasks/:taskId/checklist/:itemId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let challenge; let challenge;
@@ -636,7 +635,7 @@ api.updateChecklistItem = {
api.removeChecklistItem = { api.removeChecklistItem = {
method: 'DELETE', method: 'DELETE',
url: '/tasks/:taskId/checklist/:itemId', url: '/tasks/:taskId/checklist/:itemId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let challenge; let challenge;
@@ -685,7 +684,7 @@ api.removeChecklistItem = {
api.addTagToTask = { api.addTagToTask = {
method: 'POST', method: 'POST',
url: '/tasks/:taskId/tags/:tagId', url: '/tasks/:taskId/tags/:tagId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -728,7 +727,7 @@ api.addTagToTask = {
api.removeTagFromTask = { api.removeTagFromTask = {
method: 'DELETE', method: 'DELETE',
url: '/tasks/:taskId/tags/:tagId', url: '/tasks/:taskId/tags/:tagId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -767,7 +766,7 @@ api.removeTagFromTask = {
api.unlinkTask = { api.unlinkTask = {
method: 'POST', method: 'POST',
url: '/tasks/unlink/:taskId', url: '/tasks/unlink/:taskId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID(); req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID();
req.checkQuery('keep', res.t('keepOrRemove')).notEmpty().isIn(['keep', 'remove']); req.checkQuery('keep', res.t('keepOrRemove')).notEmpty().isIn(['keep', 'remove']);
@@ -814,7 +813,7 @@ api.unlinkTask = {
api.clearCompletedTodos = { api.clearCompletedTodos = {
method: 'POST', method: 'POST',
url: '/tasks/clearCompletedTodos', url: '/tasks/clearCompletedTodos',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -847,7 +846,7 @@ api.clearCompletedTodos = {
api.deleteTask = { api.deleteTask = {
method: 'DELETE', method: 'DELETE',
url: '/tasks/:taskId', url: '/tasks/:taskId',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
let challenge; let challenge;

View File

@@ -1,5 +1,4 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth'; import { authWithHeaders } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import common from '../../../../common'; import common from '../../../../common';
import { import {
NotFound, NotFound,
@@ -29,7 +28,7 @@ let api = {};
*/ */
api.getUser = { api.getUser = {
method: 'GET', method: 'GET',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user', url: '/user',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user.toJSON(); let user = res.locals.user.toJSON();
@@ -56,7 +55,7 @@ api.getUser = {
*/ */
api.getBuyList = { api.getBuyList = {
method: 'GET', method: 'GET',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/inventory/buy', url: '/user/inventory/buy',
async handler (req, res) { async handler (req, res) {
let list = _.cloneDeep(common.updateStore(res.locals.user)); let list = _.cloneDeep(common.updateStore(res.locals.user));
@@ -150,7 +149,7 @@ let checkPreferencePurchase = (user, path, item) => {
*/ */
api.updateUser = { api.updateUser = {
method: 'PUT', method: 'PUT',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user', url: '/user',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -186,7 +185,7 @@ api.updateUser = {
*/ */
api.deleteUser = { api.deleteUser = {
method: 'DELETE', method: 'DELETE',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user', url: '/user',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -246,7 +245,7 @@ function _cleanChecklist (task) {
**/ **/
api.getUserAnonymized = { api.getUserAnonymized = {
method: 'GET', method: 'GET',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/anonymized', url: '/user/anonymized',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user.toJSON(); let user = res.locals.user.toJSON();
@@ -313,7 +312,7 @@ const partyMembersFields = 'profile.name stats achievements items.special';
*/ */
api.castSpell = { api.castSpell = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/class/cast/:spellId', url: '/user/class/cast/:spellId',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -423,7 +422,7 @@ api.castSpell = {
*/ */
api.sleep = { api.sleep = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/sleep', url: '/user/sleep',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -443,7 +442,7 @@ api.sleep = {
*/ */
api.allocate = { api.allocate = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/allocate', url: '/user/allocate',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -463,7 +462,7 @@ api.allocate = {
*/ */
api.allocateNow = { api.allocateNow = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/allocate-now', url: '/user/allocate-now',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -487,7 +486,7 @@ api.allocateNow = {
*/ */
api.buy = { api.buy = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/buy/:key', url: '/user/buy/:key',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -510,7 +509,7 @@ api.buy = {
*/ */
api.buyMysterySet = { api.buyMysterySet = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/buy-mystery-set/:key', url: '/user/buy-mystery-set/:key',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -533,7 +532,7 @@ api.buyMysterySet = {
*/ */
api.buyQuest = { api.buyQuest = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/buy-quest/:key', url: '/user/buy-quest/:key',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -556,7 +555,7 @@ api.buyQuest = {
*/ */
api.buySpecialSpell = { api.buySpecialSpell = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/buy-special-spell/:key', url: '/user/buy-special-spell/:key',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -580,7 +579,7 @@ api.buySpecialSpell = {
*/ */
api.hatch = { api.hatch = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/hatch/:egg/:hatchingPotion', url: '/user/hatch/:egg/:hatchingPotion',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -604,7 +603,7 @@ api.hatch = {
*/ */
api.equip = { api.equip = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/equip/:type/:key', url: '/user/equip/:type/:key',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -628,7 +627,7 @@ api.equip = {
*/ */
api.feed = { api.feed = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/feed/:pet/:food', url: '/user/feed/:pet/:food',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -650,7 +649,7 @@ api.feed = {
*/ */
api.changeClass = { api.changeClass = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/change-class', url: '/user/change-class',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -670,7 +669,7 @@ api.changeClass = {
*/ */
api.disableClasses = { api.disableClasses = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/disable-classes', url: '/user/disable-classes',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -693,7 +692,7 @@ api.disableClasses = {
*/ */
api.purchase = { api.purchase = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/purchase/:type/:key', url: '/user/purchase/:type/:key',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -716,7 +715,7 @@ api.purchase = {
*/ */
api.userPurchaseHourglass = { api.userPurchaseHourglass = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/purchase-hourglass/:type/:key', url: '/user/purchase-hourglass/:type/:key',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -738,7 +737,7 @@ api.userPurchaseHourglass = {
*/ */
api.readCard = { api.readCard = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/read-card/:cardType', url: '/user/read-card/:cardType',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -758,7 +757,7 @@ api.readCard = {
*/ */
api.userOpenMysteryItem = { api.userOpenMysteryItem = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/open-mystery-item', url: '/user/open-mystery-item',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -835,7 +834,7 @@ api.deleteWebhook = {
*/ */
api.userReleasePets = { api.userReleasePets = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/release-pets', url: '/user/release-pets',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -855,7 +854,7 @@ api.userReleasePets = {
*/ */
api.userReleaseBoth = { api.userReleaseBoth = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/release-both', url: '/user/release-both',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -875,7 +874,7 @@ api.userReleaseBoth = {
*/ */
api.userReleaseMounts = { api.userReleaseMounts = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/release-mounts', url: '/user/release-mounts',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -895,7 +894,7 @@ api.userReleaseMounts = {
*/ */
api.userSell = { api.userSell = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/sell/:type/:key', url: '/user/sell/:type/:key',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -915,7 +914,7 @@ api.userSell = {
*/ */
api.userUnlock = { api.userUnlock = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/unlock', url: '/user/unlock',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -935,7 +934,7 @@ api.userUnlock = {
*/ */
api.userRevive = { api.userRevive = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/revive', url: '/user/revive',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -955,7 +954,7 @@ api.userRevive = {
*/ */
api.userRebirth = { api.userRebirth = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/rebirth', url: '/user/rebirth',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -1002,7 +1001,7 @@ api.blockUser = {
**/ **/
api.deleteMessage = { api.deleteMessage = {
method: 'DELETE', method: 'DELETE',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/messages/:id', url: '/user/messages/:id',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -1021,7 +1020,7 @@ api.deleteMessage = {
**/ **/
api.clearMessages = { api.clearMessages = {
method: 'DELETE', method: 'DELETE',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/messages', url: '/user/messages',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -1041,7 +1040,7 @@ api.clearMessages = {
*/ */
api.userReroll = { api.userReroll = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/reroll', url: '/user/reroll',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -1071,7 +1070,7 @@ api.userReroll = {
*/ */
api.userAddPushDevice = { api.userAddPushDevice = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/addPushDevice', url: '/user/addPushDevice',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -1093,7 +1092,7 @@ api.userAddPushDevice = {
*/ */
api.userReset = { api.userReset = {
method: 'POST', method: 'POST',
middlewares: [authWithHeaders(), cron], middlewares: [authWithHeaders()],
url: '/user/reset', url: '/user/reset',
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;

View File

@@ -1,5 +1,4 @@
import { authWithSession } from '../../middlewares/api-v3/auth'; import { authWithSession } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import { model as User } from '../../models/user'; import { model as User } from '../../models/user';
import * as Tasks from '../../models/task'; import * as Tasks from '../../models/task';
import { import {
@@ -39,7 +38,7 @@ let api = {};
api.exportUserHistory = { api.exportUserHistory = {
method: 'GET', method: 'GET',
url: '/export/history.csv', url: '/export/history.csv',
middlewares: [authWithSession, cron], middlewares: [authWithSession],
async handler (req, res) { async handler (req, res) {
let user = res.locals.user; let user = res.locals.user;
@@ -107,7 +106,7 @@ async function _getUserDataForExport (user) {
api.exportUserDataJson = { api.exportUserDataJson = {
method: 'GET', method: 'GET',
url: '/export/userdata.json', url: '/export/userdata.json',
middlewares: [authWithSession, cron], middlewares: [authWithSession],
async handler (req, res) { async handler (req, res) {
let userData = await _getUserDataForExport(res.locals.user); let userData = await _getUserDataForExport(res.locals.user);
@@ -132,7 +131,7 @@ api.exportUserDataJson = {
api.exportUserDataXml = { api.exportUserDataXml = {
method: 'GET', method: 'GET',
url: '/export/userdata.xml', url: '/export/userdata.xml',
middlewares: [authWithSession, cron], middlewares: [authWithSession],
async handler (req, res) { async handler (req, res) {
let userData = await _getUserDataForExport(res.locals.user); let userData = await _getUserDataForExport(res.locals.user);

View File

@@ -1,5 +1,4 @@
import locals from '../../middlewares/api-v3/locals'; import locals from '../../middlewares/api-v3/locals';
import getUserLanguage from '../../middlewares/api-v3/getUserLanguage';
import _ from 'lodash'; import _ from 'lodash';
const marked = require('marked'); const marked = require('marked');
@@ -11,7 +10,8 @@ const TOTAL_USER_COUNT = '1,100,000';
api.getFrontPage = { api.getFrontPage = {
method: 'GET', method: 'GET',
url: '/', url: '/',
middlewares: [getUserLanguage, locals], middlewares: [locals],
runCron: false,
async handler (req, res) { async handler (req, res) {
if (!req.header('x-api-user') && !req.header('x-api-key') && !(req.session && req.session.userId)) { if (!req.header('x-api-user') && !req.header('x-api-key') && !(req.session && req.session.userId)) {
return res.redirect('/static/front'); return res.redirect('/static/front');
@@ -34,7 +34,8 @@ _.each(staticPages, (name) => {
api[`get${name}Page`] = { api[`get${name}Page`] = {
method: 'GET', method: 'GET',
url: `/static/${name}`, url: `/static/${name}`,
middlewares: [getUserLanguage, locals], middlewares: [locals],
runCron: false,
async handler (req, res) { async handler (req, res) {
res.render(`static/${name}.jade`, { res.render(`static/${name}.jade`, {
env: res.locals.habitrpg, env: res.locals.habitrpg,
@@ -51,7 +52,8 @@ _.each(shareables, (name) => {
api[`get${name}ShareablePage`] = { api[`get${name}ShareablePage`] = {
method: 'GET', method: 'GET',
url: `/social/${name}`, url: `/social/${name}`,
middlewares: [getUserLanguage, locals], middlewares: [locals],
runCron: false,
async handler (req, res) { async handler (req, res) {
res.render(`social/${name}`, { res.render(`social/${name}`, {
env: res.locals.habitrpg, env: res.locals.habitrpg,
@@ -65,6 +67,7 @@ _.each(shareables, (name) => {
api.redirectExtensionsPage = { api.redirectExtensionsPage = {
method: 'GET', method: 'GET',
url: '/static/extensions', url: '/static/extensions',
runCron: false,
async handler (req, res) { async handler (req, res) {
res.redirect('http://habitica.wikia.com/wiki/App_and_Extension_Integrations'); res.redirect('http://habitica.wikia.com/wiki/App_and_Extension_Integrations');
}, },

View File

@@ -1,5 +1,9 @@
import fs from 'fs'; import fs from 'fs';
import _ from 'lodash'; import _ from 'lodash';
import {
getUserLanguage,
} from '../../middlewares/api-v3/language';
import cron from '../../middlewares/api-v3/cron';
// Wrapper function to handler `async` route handlers that return promises // Wrapper function to handler `async` route handlers that return promises
// It takes the async function, execute it and pass any error to next (args[2]) // It takes the async function, execute it and pass any error to next (args[2])
@@ -8,12 +12,39 @@ let noop = (req, res, next) => next();
module.exports.readController = function readController (router, controller) { module.exports.readController = function readController (router, controller) {
_.each(controller, (action) => { _.each(controller, (action) => {
let {method, url, middlewares = [], handler} = action; let {method, url, middlewares = [], handler, runCron} = action;
// If an authentication middleware is used run getUserLanguage after it, otherwise before
// for cron instead use it only if an authentication middleware is present
let authMiddlewareIndex = _.findIndex(middlewares, middleware => {
if (middleware.name.indexOf('authWith') === 0) { // authWith{Headers|Session|Url|...}
return true;
} else {
return false;
}
});
let middlewaresToAdd = [getUserLanguage];
if (authMiddlewareIndex !== -1) { // the user will be authenticated, getUserLanguage and cron after authentication
if (!(runCron === false)) { // eslint-disable-line no-extra-parens
middlewaresToAdd.push(cron);
}
if (authMiddlewareIndex === middlewares.length - 1) {
middlewares.push(...middlewaresToAdd);
} else {
middlewares.splice(authMiddlewareIndex + 1, 0, ...middlewaresToAdd);
}
} else { // no auth, getUserLanguage as the first middleware
middlewares.unshift(...middlewaresToAdd);
}
method = method.toLowerCase(); method = method.toLowerCase();
let fn = handler ? _wrapAsyncFn(handler) : noop; let fn = handler ? _wrapAsyncFn(handler) : noop;
router[method](url, ...middlewares, fn); router[method](url, ...middlewares, fn);
console.log(url, middlewares.map(m => m.name));
}); });
}; };

View File

@@ -1,12 +1,11 @@
import { import {
NotAuthorized, NotAuthorized,
} from '../../libs/api-v3/errors'; } from '../../libs/api-v3/errors';
import common from '../../../../common';
import { import {
model as User, model as User,
} from '../../models/user'; } from '../../models/user';
const i18n = common.i18n; // TODO how to translate the strings here since getUserLanguage hasn't run yet?
// Authenticate a request through the x-api-user and x-api key header // Authenticate a request through the x-api-user and x-api key header
// If optional is true, don't error on missing authentication // If optional is true, don't error on missing authentication
@@ -26,8 +25,8 @@ export function authWithHeaders (optional = false) {
}) })
.exec() .exec()
.then((user) => { .then((user) => {
if (!user) throw new NotAuthorized(i18n.t('invalidCredentials')); if (!user) throw new NotAuthorized(res.t('invalidCredentials'));
if (user.auth.blocked) throw new NotAuthorized(i18n.t('accountSuspended', {userId: user._id})); if (user.auth.blocked) throw new NotAuthorized(res.t('accountSuspended', {userId: user._id}));
res.locals.user = user; res.locals.user = user;
// TODO use either session/cookie or headers, not both // TODO use either session/cookie or headers, not both
@@ -42,14 +41,14 @@ export function authWithHeaders (optional = false) {
export function authWithSession (req, res, next) { export function authWithSession (req, res, next) {
let userId = req.session.userId; let userId = req.session.userId;
if (!userId) return next(new NotAuthorized(i18n.t('invalidCredentials'))); if (!userId) return next(new NotAuthorized(res.t('invalidCredentials')));
User.findOne({ User.findOne({
_id: userId, _id: userId,
}) })
.exec() .exec()
.then((user) => { .then((user) => {
if (!user) throw new NotAuthorized(i18n.t('invalidCredentials')); if (!user) throw new NotAuthorized(res.t('invalidCredentials'));
res.locals.user = user; res.locals.user = user;
next(); next();

View File

@@ -271,7 +271,6 @@ function cron (options = {}) {
return _progress; return _progress;
} }
// TODO check that it's used everywhere
module.exports = function cronMiddleware (req, res, next) { module.exports = function cronMiddleware (req, res, next) {
let user = res.locals.user; let user = res.locals.user;
let analytics = res.analytics; let analytics = res.analytics;

View File

@@ -21,6 +21,10 @@ import {
import v1 from './v1'; import v1 from './v1';
import v2 from './v2'; import v2 from './v2';
import v3 from './v3'; import v3 from './v3';
import responseHandler from './response';
import {
attachTranslateFunction,
} from './language';
const IS_PROD = nconf.get('IS_PROD'); const IS_PROD = nconf.get('IS_PROD');
const DISABLE_LOGGING = nconf.get('DISABLE_REQUEST_LOGGING'); const DISABLE_LOGGING = nconf.get('DISABLE_REQUEST_LOGGING');
@@ -37,6 +41,10 @@ module.exports = function attachMiddlewares (app, server) {
if (!IS_PROD && !DISABLE_LOGGING) app.use(morgan('dev')); if (!IS_PROD && !DISABLE_LOGGING) app.use(morgan('dev'));
// add res.respond and res.t
app.use(responseHandler);
app.use(attachTranslateFunction);
app.use(compression()); app.use(compression());
app.use(favicon(`${PUBLIC_DIR}/favicon.ico`)); app.use(favicon(`${PUBLIC_DIR}/favicon.ico`));

View File

@@ -1,6 +1,6 @@
import { model as User } from '../../models/user'; import { model as User } from '../../models/user';
import accepts from 'accepts'; import accepts from 'accepts';
import { i18n } from '../../../../common'; import common from '../../../../common';
import _ from 'lodash'; import _ from 'lodash';
import { import {
translations, translations,
@@ -8,6 +8,8 @@ import {
multipleVersionsLanguages, multipleVersionsLanguages,
} from '../../libs/api-v3/i18n'; } from '../../libs/api-v3/i18n';
const i18n = common.i18n;
function _getUniqueListOfLanguages (languages) { function _getUniqueListOfLanguages (languages) {
let acceptableLanguages = _(languages).map((lang) => { let acceptableLanguages = _(languages).map((lang) => {
return lang.slice(0, 2); return lang.slice(0, 2);
@@ -56,7 +58,7 @@ function _getFromUser (user, req) {
return lang; return lang;
} }
function _attachTranslateFunction (req, res, next) { export function attachTranslateFunction (req, res, next) {
res.t = function reqTranslation () { res.t = function reqTranslation () {
return i18n.t(...arguments, req.language); return i18n.t(...arguments, req.language);
}; };
@@ -64,13 +66,13 @@ function _attachTranslateFunction (req, res, next) {
next(); next();
} }
module.exports = function getUserLanguage (req, res, next) { export function getUserLanguage (req, res, next) {
if (req.query.lang) { // In case the language is specified in the request url, use it if (req.query.lang) { // In case the language is specified in the request url, use it
req.language = translations[req.query.lang] ? req.query.lang : 'en'; req.language = translations[req.query.lang] ? req.query.lang : 'en';
return _attachTranslateFunction(...arguments); return next();
} else if (req.locals && req.locals.user) { // If the request is authenticated, use the user's preferred language } else if (req.locals && req.locals.user) { // If the request is authenticated, use the user's preferred language
req.language = _getFromUser(req.locals.user, req); req.language = _getFromUser(req.locals.user, req);
return _attachTranslateFunction(...arguments); return next();
} else if (req.session && req.session.userId) { // Same thing if the user has a valid session } else if (req.session && req.session.userId) { // Same thing if the user has a valid session
User.findOne({ User.findOne({
_id: req.session.userId, _id: req.session.userId,
@@ -79,11 +81,11 @@ module.exports = function getUserLanguage (req, res, next) {
.exec() .exec()
.then((user) => { .then((user) => {
req.language = _getFromUser(user, req); req.language = _getFromUser(user, req);
return _attachTranslateFunction(...arguments); return next();
}) })
.catch(next); .catch(next);
} else { // Otherwise get from browser } else { // Otherwise get from browser
req.language = _getFromUser(null, req); req.language = _getFromUser(null, req);
return _attachTranslateFunction(...arguments); return next();
} }
}; }

View File

@@ -1,12 +1,13 @@
import express from 'express'; import express from 'express';
import expressValidator from 'express-validator'; import expressValidator from 'express-validator';
import getUserLanguage from './getUserLanguage';
import responseHandler from './response';
import analytics from './analytics'; import analytics from './analytics';
import setupBody from './setupBody'; import setupBody from './setupBody';
import routes from '../../libs/api-v3/routes'; import routes from '../../libs/api-v3/routes';
import path from 'path'; import path from 'path';
const API_CONTROLLERS_PATH = path.join(__dirname, '/../../controllers/api-v3/');
const TOP_LEVEL_CONTROLLERS_PATH = path.join(__dirname, '/../../controllers/top-level/');
const v3app = express(); const v3app = express();
// re-set the view options because they are not inherited from the top level app // re-set the view options because they are not inherited from the top level app
@@ -16,15 +17,12 @@ v3app.set('views', `${__dirname}/../../../views`);
v3app.use(expressValidator()); v3app.use(expressValidator());
v3app.use(analytics); v3app.use(analytics);
v3app.use(setupBody); v3app.use(setupBody);
v3app.use(responseHandler);
v3app.use(getUserLanguage); // TODO move to after auth for authenticated routes
const TOP_LEVEL_CONTROLLERS_PATH = path.join(__dirname, '/../../controllers/top-level/');
const topLevelRouter = express.Router(); // eslint-disable-line babel/new-cap const topLevelRouter = express.Router(); // eslint-disable-line babel/new-cap
routes.walkControllers(topLevelRouter, TOP_LEVEL_CONTROLLERS_PATH); routes.walkControllers(topLevelRouter, TOP_LEVEL_CONTROLLERS_PATH);
v3app.use('/', topLevelRouter); v3app.use('/', topLevelRouter);
const API_CONTROLLERS_PATH = path.join(__dirname, '/../../controllers/api-v3/');
const v3Router = express.Router(); // eslint-disable-line babel/new-cap const v3Router = express.Router(); // eslint-disable-line babel/new-cap
routes.walkControllers(v3Router, API_CONTROLLERS_PATH); routes.walkControllers(v3Router, API_CONTROLLERS_PATH);
v3app.use('/api/v3', v3Router); v3app.use('/api/v3', v3Router);

View File

@@ -2,7 +2,9 @@ var auth = require('../../controllers/api-v2/auth');
var express = require('express'); var express = require('express');
var i18n = require('../../libs/api-v2/i18n'); var i18n = require('../../libs/api-v2/i18n');
var router = express.Router(); var router = express.Router();
import getUserLanguage from '../../middlewares/api-v3/getUserLanguage'; import {
getUserLanguage
} from '../../middlewares/api-v3/language';
/* auth.auth*/ /* auth.auth*/
// auth.setupPassport(router); //TODO make this consistent with the others // auth.setupPassport(router); //TODO make this consistent with the others

View File

@@ -4,7 +4,9 @@ var router = express.Router();
var auth = require('../../controllers/api-v2/auth'); var auth = require('../../controllers/api-v2/auth');
var coupon = require('../../controllers/api-v2/coupon'); var coupon = require('../../controllers/api-v2/coupon');
var i18n = require('../../libs/api-v2/i18n'); var i18n = require('../../libs/api-v2/i18n');
import getUserLanguage from '../../middlewares/api-v3/getUserLanguage'; import {
getUserLanguage
} from '../../middlewares/api-v3/language';
router.get('/coupons', auth.authWithUrl, getUserLanguage, coupon.ensureAdmin, coupon.getCoupons); router.get('/coupons', auth.authWithUrl, getUserLanguage, coupon.ensureAdmin, coupon.getCoupons);
router.post('/coupons/generate/:event', auth.auth, getUserLanguage, coupon.ensureAdmin, coupon.generateCoupons); router.post('/coupons/generate/:event', auth.auth, getUserLanguage, coupon.ensureAdmin, coupon.generateCoupons);

View File

@@ -19,7 +19,9 @@ var cron = user.cron;
var _ = require('lodash'); var _ = require('lodash');
var content = require('../../../../common').content; var content = require('../../../../common').content;
var i18n = require('../../libs/api-v2/i18n'); var i18n = require('../../libs/api-v2/i18n');
import getUserLanguage from '../../middlewares/api-v3/getUserLanguage'; import {
getUserLanguage
} from '../../middlewares/api-v3/language';
var forceRefresh = require('../../middlewares/forceRefresh').middleware; var forceRefresh = require('../../middlewares/forceRefresh').middleware;
module.exports = function(swagger, v2) { module.exports = function(swagger, v2) {

View File

@@ -2,7 +2,9 @@ var express = require('express');
var router = express.Router(); var router = express.Router();
var i18n = require('../../libs/api-v2/i18n'); var i18n = require('../../libs/api-v2/i18n');
var unsubscription = require('../../controllers/api-v2/unsubscription'); var unsubscription = require('../../controllers/api-v2/unsubscription');
import getUserLanguage from '../../middlewares/api-v3/getUserLanguage'; import {
getUserLanguage
} from '../../middlewares/api-v3/language';
router.get('/unsubscribe', getUserLanguage, unsubscription.unsubscribe); router.get('/unsubscribe', getUserLanguage, unsubscription.unsubscribe);

View File

@@ -4,7 +4,9 @@ var router = express.Router();
var auth = require('../controllers/api-v2/auth'); var auth = require('../controllers/api-v2/auth');
var payments = require('../controllers/payments'); var payments = require('../controllers/payments');
var i18n = require('../libs/api-v2/i18n'); var i18n = require('../libs/api-v2/i18n');
import getUserLanguage from '../../middlewares/api-v3/getUserLanguage'; import {
getUserLanguage
} from '../../middlewares/api-v3/language';
router.get('/paypal/checkout', auth.authWithUrl, getUserLanguage, payments.paypalCheckout); router.get('/paypal/checkout', auth.authWithUrl, getUserLanguage, payments.paypalCheckout);
router.get('/paypal/checkout/success', getUserLanguage, payments.paypalCheckoutSuccess); router.get('/paypal/checkout/success', getUserLanguage, payments.paypalCheckoutSuccess);