mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 14:47:53 +01:00
moving developer-only strings to api/common messages (#10258)
* move translatable string to apiMessages * use apiMessages instead of res.t for groupIdRequired / keepOrRemove * move pageMustBeNumber to apiMessages * change apimessages * move missingKeyParam to apiMessages * move more strings to apiMessages * fix lint * revert lodash imports to fix tests * fix webhook test * fix test * rollback key change of `keepOrRemove` * remove unneeded `req.language` param * extract more messages from i18n * add missing `missingTypeParam` message * Split api- and commonMessages * fix test * fix sanity * merge messages to an object, rename commonMessage to errorMessage * apiMessages -> apiError, commonMessages -> errorMessage, extract messages to separate objects * fix test * module.exports
This commit is contained in:
@@ -2,7 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
resetHabiticaDB,
|
resetHabiticaDB,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-v3-integration.helper';
|
||||||
import apiMessages from '../../../../../website/server/libs/apiMessages';
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('GET /coupons/', () => {
|
describe('GET /coupons/', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -19,7 +19,7 @@ describe('GET /coupons/', () => {
|
|||||||
await expect(user.get('/coupons')).to.eventually.be.rejected.and.eql({
|
await expect(user.get('/coupons')).to.eventually.be.rejected.and.eql({
|
||||||
code: 401,
|
code: 401,
|
||||||
error: 'NotAuthorized',
|
error: 'NotAuthorized',
|
||||||
message: apiMessages('noSudoAccess'),
|
message: apiError('noSudoAccess'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
resetHabiticaDB,
|
resetHabiticaDB,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-v3-integration.helper';
|
||||||
import couponCode from 'coupon-code';
|
import couponCode from 'coupon-code';
|
||||||
import apiMessages from '../../../../../website/server/libs/apiMessages';
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('POST /coupons/generate/:event', () => {
|
describe('POST /coupons/generate/:event', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -26,7 +26,7 @@ describe('POST /coupons/generate/:event', () => {
|
|||||||
await expect(user.post('/coupons/generate/aaa')).to.eventually.be.rejected.and.eql({
|
await expect(user.post('/coupons/generate/aaa')).to.eventually.be.rejected.and.eql({
|
||||||
code: 401,
|
code: 401,
|
||||||
error: 'NotAuthorized',
|
error: 'NotAuthorized',
|
||||||
message: apiMessages('noSudoAccess'),
|
message: apiError('noSudoAccess'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
TAVERN_ID,
|
TAVERN_ID,
|
||||||
} from '../../../../../website/server/models/group';
|
} from '../../../../../website/server/models/group';
|
||||||
import apiMessages from '../../../../../website/server/libs/apiMessages';
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('GET /groups', () => {
|
describe('GET /groups', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -167,7 +167,7 @@ describe('GET /groups', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: apiMessages('guildsOnlyPaginate'),
|
message: apiError('guildsOnlyPaginate'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../../helpers/api-integration/v3';
|
||||||
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
|
import apiError from '../../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('payments : paypal #checkoutSuccess', () => {
|
describe('payments : paypal #checkoutSuccess', () => {
|
||||||
let endpoint = '/paypal/checkout/success';
|
let endpoint = '/paypal/checkout/success';
|
||||||
@@ -17,7 +17,7 @@ describe('payments : paypal #checkoutSuccess', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('missingPaymentId'),
|
message: apiError('missingPaymentId'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ describe('payments : paypal #checkoutSuccess', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('missingCustomerId'),
|
message: apiError('missingCustomerId'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../../helpers/api-integration/v3';
|
||||||
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
import shared from '../../../../../../website/common';
|
import shared from '../../../../../../website/common';
|
||||||
|
import apiError from '../../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('payments : paypal #subscribe', () => {
|
describe('payments : paypal #subscribe', () => {
|
||||||
let endpoint = '/paypal/subscribe';
|
let endpoint = '/paypal/subscribe';
|
||||||
@@ -17,7 +17,7 @@ describe('payments : paypal #subscribe', () => {
|
|||||||
await expect(user.get(endpoint)).to.eventually.be.rejected.and.eql({
|
await expect(user.get(endpoint)).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('missingSubKey'),
|
message: apiError('missingSubKey'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../../helpers/api-integration/v3';
|
||||||
|
import apiError from '../../../../../../website/server/libs/apiError';
|
||||||
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
|
|
||||||
describe('payments : paypal #subscribeSuccess', () => {
|
describe('payments : paypal #subscribeSuccess', () => {
|
||||||
@@ -16,7 +16,7 @@ describe('payments : paypal #subscribeSuccess', () => {
|
|||||||
await expect(user.get(endpoint)).to.eventually.be.rejected.and.eql({
|
await expect(user.get(endpoint)).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('missingPaypalBlock'),
|
message: apiError('missingPaypalBlock'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import { quests as questScrolls } from '../../../../../website/common/script/content';
|
import { quests as questScrolls } from '../../../../../website/common/script/content';
|
||||||
import { model as Chat } from '../../../../../website/server/models/chat';
|
import { model as Chat } from '../../../../../website/server/models/chat';
|
||||||
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('POST /groups/:groupId/quests/invite/:questKey', () => {
|
describe('POST /groups/:groupId/quests/invite/:questKey', () => {
|
||||||
let questingGroup;
|
let questingGroup;
|
||||||
@@ -69,7 +70,7 @@ describe('POST /groups/:groupId/quests/invite/:questKey', () => {
|
|||||||
await expect(leader.post(`/groups/${questingGroup._id}/quests/invite/${FAKE_QUEST}`)).to.eventually.be.rejected.and.eql({
|
await expect(leader.post(`/groups/${questingGroup._id}/quests/invite/${FAKE_QUEST}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('questNotFound', {key: FAKE_QUEST}),
|
message: apiError('questNotFound', {key: FAKE_QUEST}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
|
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import { find } from 'lodash';
|
import { find } from 'lodash';
|
||||||
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('POST /user/class/cast/:spellId', () => {
|
describe('POST /user/class/cast/:spellId', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -24,7 +25,7 @@ describe('POST /user/class/cast/:spellId', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('spellNotFound', {spellId}),
|
message: apiError('spellNotFound', {spellId}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ describe('POST /user/class/cast/:spellId', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('spellNotFound', {spellId}),
|
message: apiError('spellNotFound', {spellId}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../../helpers/api-integration/v3';
|
||||||
import shared from '../../../../../../website/common/script';
|
import shared from '../../../../../../website/common/script';
|
||||||
|
import apiError from '../../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
let content = shared.content;
|
let content = shared.content;
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ describe('POST /user/buy/:key', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('itemNotFound', {key: 'notExisting'}),
|
message: apiError('itemNotFound', {key: 'notExisting'}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../../helpers/api-integration/v3';
|
||||||
|
import apiError from '../../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('POST /user/buy-gear/:key', () => {
|
describe('POST /user/buy-gear/:key', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -21,7 +21,7 @@ describe('POST /user/buy-gear/:key', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('itemNotFound', {key: 'notExisting'}),
|
message: apiError('itemNotFound', {key: 'notExisting'}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../../helpers/api-integration/v3';
|
||||||
import shared from '../../../../../../website/common/script';
|
import shared from '../../../../../../website/common/script';
|
||||||
|
import apiError from '../../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
let content = shared.content;
|
let content = shared.content;
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ describe('POST /user/buy-quest/:key', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('questNotFound', {key: 'notExisting'}),
|
message: apiError('questNotFound', {key: 'notExisting'}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../../helpers/api-integration/v3';
|
||||||
import shared from '../../../../../../website/common/script';
|
import shared from '../../../../../../website/common/script';
|
||||||
|
import apiError from '../../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
let content = shared.content;
|
let content = shared.content;
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ describe('POST /user/buy-special-spell/:key', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('spellNotFound', {spellId: 'notExisting'}),
|
message: apiError('spellNotFound', {spellId: 'notExisting'}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../../helpers/api-integration/v3';
|
||||||
|
import apiError from '../../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('POST /user/allocate', () => {
|
describe('POST /user/allocate', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -17,7 +18,7 @@ describe('POST /user/allocate', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('invalidAttribute', {attr: 'invalid'}),
|
message: apiError('invalidAttribute', {attr: 'invalid'}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('POST /user/webhook', () => {
|
describe('POST /user/webhook', () => {
|
||||||
let user, body;
|
let user, body;
|
||||||
@@ -205,7 +206,7 @@ describe('POST /user/webhook', () => {
|
|||||||
await expect(user.post('/user/webhook', body)).to.eventually.be.rejected.and.eql({
|
await expect(user.post('/user/webhook', body)).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('groupIdRequired'),
|
message: apiError('groupIdRequired'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID} from 'uuid';
|
import { v4 as generateUUID} from 'uuid';
|
||||||
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('PUT /user/webhook/:id', () => {
|
describe('PUT /user/webhook/:id', () => {
|
||||||
let user, webhookToUpdate;
|
let user, webhookToUpdate;
|
||||||
@@ -127,7 +128,7 @@ describe('PUT /user/webhook/:id', () => {
|
|||||||
await expect(user.put(`/user/webhook/${webhookToUpdate.id}`, {type, options})).to.eventually.be.rejected.and.eql({
|
await expect(user.put(`/user/webhook/${webhookToUpdate.id}`, {type, options})).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('groupIdRequired'),
|
message: apiError('groupIdRequired'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import apiMessages from '../../../../../website/server/libs/apiMessages';
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('API Messages', () => {
|
describe('API Messages', () => {
|
||||||
const message = 'Only public guilds support pagination.';
|
const message = 'Only public guilds support pagination.';
|
||||||
it('returns an API message', () => {
|
it('returns an API message', () => {
|
||||||
expect(apiMessages('guildsOnlyPaginate')).to.equal(message);
|
expect(apiError('guildsOnlyPaginate')).to.equal(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws if the API message does not exist', () => {
|
it('throws if the API message does not exist', () => {
|
||||||
expect(() => apiMessages('iDoNotExist')).to.throw;
|
expect(() => apiError('iDoNotExist')).to.throw;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clones the passed variables', () => {
|
it('clones the passed variables', () => {
|
||||||
let vars = {a: 1};
|
let vars = {a: 1};
|
||||||
sandbox.stub(_, 'clone').returns({});
|
sandbox.stub(_, 'clone').returns({});
|
||||||
apiMessages('guildsOnlyPaginate', vars);
|
apiError('guildsOnlyPaginate', vars);
|
||||||
expect(_.clone).to.have.been.calledOnce;
|
expect(_.clone).to.have.been.calledOnce;
|
||||||
expect(_.clone).to.have.been.calledWith(vars);
|
expect(_.clone).to.have.been.calledWith(vars);
|
||||||
});
|
});
|
||||||
@@ -22,7 +22,7 @@ describe('API Messages', () => {
|
|||||||
let vars = {a: 1};
|
let vars = {a: 1};
|
||||||
let stub = sinon.stub().returns('string');
|
let stub = sinon.stub().returns('string');
|
||||||
sandbox.stub(_, 'template').returns(stub);
|
sandbox.stub(_, 'template').returns(stub);
|
||||||
apiMessages('guildsOnlyPaginate', vars);
|
apiError('guildsOnlyPaginate', vars);
|
||||||
expect(_.template).to.have.been.calledOnce;
|
expect(_.template).to.have.been.calledOnce;
|
||||||
expect(_.template).to.have.been.calledWith(message);
|
expect(_.template).to.have.been.calledWith(message);
|
||||||
expect(stub).to.have.been.calledOnce;
|
expect(stub).to.have.been.calledOnce;
|
||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
import i18n from '../../../../../website/common/script/i18n';
|
import i18n from '../../../../../website/common/script/i18n';
|
||||||
import { ensureAdmin, ensureSudo } from '../../../../../website/server/middlewares/ensureAccessRight';
|
import { ensureAdmin, ensureSudo } from '../../../../../website/server/middlewares/ensureAccessRight';
|
||||||
import { NotAuthorized } from '../../../../../website/server/libs/errors';
|
import { NotAuthorized } from '../../../../../website/server/libs/errors';
|
||||||
import apiMessages from '../../../../../website/server/libs/apiMessages';
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('ensure access middlewares', () => {
|
describe('ensure access middlewares', () => {
|
||||||
let res, req, next;
|
let res, req, next;
|
||||||
@@ -46,7 +46,7 @@ describe('ensure access middlewares', () => {
|
|||||||
ensureSudo(req, res, next);
|
ensureSudo(req, res, next);
|
||||||
|
|
||||||
const calledWith = next.getCall(0).args;
|
const calledWith = next.getCall(0).args;
|
||||||
expect(calledWith[0].message).to.equal(apiMessages('noSudoAccess'));
|
expect(calledWith[0].message).to.equal(apiError('noSudoAccess'));
|
||||||
expect(calledWith[0] instanceof NotAuthorized).to.equal(true);
|
expect(calledWith[0] instanceof NotAuthorized).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { model as Webhook } from '../../../../../website/server/models/webhook';
|
import { model as Webhook } from '../../../../../website/server/models/webhook';
|
||||||
import { BadRequest } from '../../../../../website/server/libs/errors';
|
import { BadRequest } from '../../../../../website/server/libs/errors';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('Webhook Model', () => {
|
describe('Webhook Model', () => {
|
||||||
context('Instance Methods', () => {
|
context('Instance Methods', () => {
|
||||||
@@ -287,8 +288,8 @@ describe('Webhook Model', () => {
|
|||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceOf(BadRequest);
|
expect(err).to.be.an.instanceOf(BadRequest);
|
||||||
expect(res.t).to.be.calledOnce;
|
|
||||||
expect(res.t).to.be.calledWith('groupIdRequired');
|
expect(err.message).to.eql(apiError('groupIdRequired'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
} from '../../../../website/common/script/libs/errors';
|
} from '../../../../website/common/script/libs/errors';
|
||||||
import i18n from '../../../../website/common/script/i18n';
|
import i18n from '../../../../website/common/script/i18n';
|
||||||
import content from '../../../../website/common/script/content/index';
|
import content from '../../../../website/common/script/content/index';
|
||||||
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('shared.ops.buy', () => {
|
describe('shared.ops.buy', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -40,7 +41,7 @@ describe('shared.ops.buy', () => {
|
|||||||
buy(user);
|
buy(user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
expect(err.message).to.equal(errorMessage('missingKeyParam'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
BadRequest, NotAuthorized, NotFound,
|
BadRequest, NotAuthorized, NotFound,
|
||||||
} from '../../../../website/common/script/libs/errors';
|
} from '../../../../website/common/script/libs/errors';
|
||||||
import i18n from '../../../../website/common/script/i18n';
|
import i18n from '../../../../website/common/script/i18n';
|
||||||
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
function buyGear (user, req, analytics) {
|
function buyGear (user, req, analytics) {
|
||||||
let buyOp = new BuyMarketGearOperation(user, req, analytics);
|
let buyOp = new BuyMarketGearOperation(user, req, analytics);
|
||||||
@@ -190,7 +191,7 @@ describe('shared.ops.buyMarketGear', () => {
|
|||||||
buyGear(user);
|
buyGear(user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
expect(err.message).to.equal(errorMessage('missingKeyParam'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -202,7 +203,7 @@ describe('shared.ops.buyMarketGear', () => {
|
|||||||
buyGear(user, {params});
|
buyGear(user, {params});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(NotFound);
|
expect(err).to.be.an.instanceof(NotFound);
|
||||||
expect(err.message).to.equal(i18n.t('itemNotFound', params));
|
expect(err.message).to.equal(errorMessage('itemNotFound', params));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
NotFound,
|
NotFound,
|
||||||
} from '../../../../website/common/script/libs/errors';
|
} from '../../../../website/common/script/libs/errors';
|
||||||
import i18n from '../../../../website/common/script/i18n';
|
import i18n from '../../../../website/common/script/i18n';
|
||||||
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('shared.ops.buyMysterySet', () => {
|
describe('shared.ops.buyMysterySet', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -70,7 +71,7 @@ describe('shared.ops.buyMysterySet', () => {
|
|||||||
buyMysterySet(user);
|
buyMysterySet(user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
expect(err.message).to.equal(errorMessage('missingKeyParam'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
NotFound,
|
NotFound,
|
||||||
} from '../../../../website/common/script/libs/errors';
|
} from '../../../../website/common/script/libs/errors';
|
||||||
import i18n from '../../../../website/common/script/i18n';
|
import i18n from '../../../../website/common/script/i18n';
|
||||||
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('shared.ops.buyQuest', () => {
|
describe('shared.ops.buyQuest', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -106,7 +107,7 @@ describe('shared.ops.buyQuest', () => {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(NotFound);
|
expect(err).to.be.an.instanceof(NotFound);
|
||||||
expect(err.message).to.equal(i18n.t('questNotFound', {key: 'snarfblatter'}));
|
expect(err.message).to.equal(errorMessage('questNotFound', {key: 'snarfblatter'}));
|
||||||
expect(user.items.quests).to.eql({});
|
expect(user.items.quests).to.eql({});
|
||||||
expect(user.stats.gp).to.equal(9999);
|
expect(user.stats.gp).to.equal(9999);
|
||||||
done();
|
done();
|
||||||
@@ -151,7 +152,7 @@ describe('shared.ops.buyQuest', () => {
|
|||||||
buyQuest(user);
|
buyQuest(user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
expect(err.message).to.equal(errorMessage('missingKeyParam'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../helpers/common.helper';
|
} from '../../../helpers/common.helper';
|
||||||
import content from '../../../../website/common/script/content/index';
|
import content from '../../../../website/common/script/content/index';
|
||||||
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('shared.ops.buySpecialSpell', () => {
|
describe('shared.ops.buySpecialSpell', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -28,7 +29,7 @@ describe('shared.ops.buySpecialSpell', () => {
|
|||||||
buySpecialSpell(user);
|
buySpecialSpell(user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
expect(err.message).to.equal(errorMessage('missingKeyParam'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -42,7 +43,7 @@ describe('shared.ops.buySpecialSpell', () => {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(NotFound);
|
expect(err).to.be.an.instanceof(NotFound);
|
||||||
expect(err.message).to.equal(i18n.t('spellNotFound', {spellId: 'notExisting'}));
|
expect(err.message).to.equal(errorMessage('spellNotFound', {spellId: 'notExisting'}));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import content from '../../../../website/common/script/content/index';
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../helpers/common.helper';
|
} from '../../../helpers/common.helper';
|
||||||
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('common.ops.hourglassPurchase', () => {
|
describe('common.ops.hourglassPurchase', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -28,7 +29,7 @@ describe('common.ops.hourglassPurchase', () => {
|
|||||||
hourglassPurchase(user, {params: {}});
|
hourglassPurchase(user, {params: {}});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.eql(i18n.t('missingKeyParam'));
|
expect(err.message).to.eql(errorMessage('missingKeyParam'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -38,7 +39,7 @@ describe('common.ops.hourglassPurchase', () => {
|
|||||||
hourglassPurchase(user, {params: {key: 'Base'}});
|
hourglassPurchase(user, {params: {key: 'Base'}});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.eql(i18n.t('missingTypeParam'));
|
expect(err.message).to.eql(errorMessage('missingTypeParam'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import i18n from '../../../website/common/script/i18n';
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../helpers/common.helper';
|
} from '../../helpers/common.helper';
|
||||||
|
import errorMessage from '../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('shared.ops.feed', () => {
|
describe('shared.ops.feed', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -23,7 +24,7 @@ describe('shared.ops.feed', () => {
|
|||||||
feed(user);
|
feed(user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('missingPetFoodFeed'));
|
expect(err.message).to.equal(errorMessage('missingPetFoodFeed'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -33,7 +34,7 @@ describe('shared.ops.feed', () => {
|
|||||||
feed(user, {params: {pet: 'invalid', food: 'food'}});
|
feed(user, {params: {pet: 'invalid', food: 'food'}});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('invalidPetName'));
|
expect(err.message).to.equal(errorMessage('invalidPetName'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -43,7 +44,7 @@ describe('shared.ops.feed', () => {
|
|||||||
feed(user, {params: {pet: 'Wolf-Red', food: 'invalid food name'}});
|
feed(user, {params: {pet: 'Wolf-Red', food: 'invalid food name'}});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(NotFound);
|
expect(err).to.be.an.instanceof(NotFound);
|
||||||
expect(err.message).to.equal(i18n.t('messageFoodNotFound'));
|
expect(err.message).to.equal(errorMessage('invalidFoodName'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import i18n from '../../../website/common/script/i18n';
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../helpers/common.helper';
|
} from '../../helpers/common.helper';
|
||||||
|
import errorMessage from '../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('shared.ops.hatch', () => {
|
describe('shared.ops.hatch', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -24,7 +25,7 @@ describe('shared.ops.hatch', () => {
|
|||||||
hatch(user);
|
hatch(user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('missingEggHatchingPotionHatch'));
|
expect(err.message).to.equal(errorMessage('missingEggHatchingPotion'));
|
||||||
expect(user.items.pets).to.be.empty;
|
expect(user.items.pets).to.be.empty;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import i18n from '../../../../website/common/script/i18n';
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../helpers/common.helper';
|
} from '../../../helpers/common.helper';
|
||||||
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('shared.ops.allocate', () => {
|
describe('shared.ops.allocate', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -22,7 +23,7 @@ describe('shared.ops.allocate', () => {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('invalidAttribute', {attr: 'notValid'}));
|
expect(err.message).to.equal(errorMessage('invalidAttribute', {attr: 'notValid'}));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import i18n from '../../../../website/common/script/i18n';
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../helpers/common.helper';
|
} from '../../../helpers/common.helper';
|
||||||
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
|
||||||
describe('shared.ops.allocateBulk', () => {
|
describe('shared.ops.allocateBulk', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -27,7 +28,7 @@ describe('shared.ops.allocateBulk', () => {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('invalidAttribute', {attr: 'invalid'}));
|
expect(err.message).to.equal(errorMessage('invalidAttribute', {attr: 'invalid'}));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -37,7 +38,7 @@ describe('shared.ops.allocateBulk', () => {
|
|||||||
allocateBulk(user);
|
allocateBulk(user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('statsObjectRequired'));
|
expect(err.message).to.equal(errorMessage('statsObjectRequired'));
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
25
website/common/errors/apiErrorMessages.js
Normal file
25
website/common/errors/apiErrorMessages.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// When this file grows, it can be split into multiple ones.
|
||||||
|
module.exports = {
|
||||||
|
taskIdRequired: 'req.params.taskId must contain a task id.',
|
||||||
|
keepOrRemove: 'req.query.keep must be either "keep" or "remove".',
|
||||||
|
keepOrRemoveAll: 'req.query.keep must be either "keep-all" or "remove-all".',
|
||||||
|
|
||||||
|
queryPageInteger: 'req.query.page must be an integer greater than or equal to 0.',
|
||||||
|
|
||||||
|
missingTypeKeyEquip: '"key" and "type" are required parameters.',
|
||||||
|
|
||||||
|
guildsOnlyPaginate: 'Only public guilds support pagination.',
|
||||||
|
guildsPaginateBooleanString: 'req.query.paginate must be a boolean string.',
|
||||||
|
groupIdRequired: 'req.params.groupId must contain a groupId.',
|
||||||
|
groupRemainOrLeaveChallenges: 'req.query.keep must be either "remain-in-challenges" or "leave-challenges"',
|
||||||
|
managerIdRequired: 'req.body.managerId must contain a user ID.',
|
||||||
|
noSudoAccess: 'You don\'t have sudo access.',
|
||||||
|
|
||||||
|
eventRequired: '"req.params.event" is required.',
|
||||||
|
countRequired: '"req.query.count" is required.',
|
||||||
|
|
||||||
|
missingPaymentId: 'Missing "req.query.paymentId"',
|
||||||
|
missingCustomerId: 'Missing "req.query.customerId"',
|
||||||
|
missingPaypalBlock: 'Missing "req.session.paypalBlock"',
|
||||||
|
missingSubKey: 'Missing "req.query.sub"',
|
||||||
|
};
|
||||||
18
website/common/errors/commonErrorMessages.js
Normal file
18
website/common/errors/commonErrorMessages.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// When this file grows, it can be split into multiple ones.
|
||||||
|
module.exports = {
|
||||||
|
invalidAttribute: '"<%= attr %>" is not a valid Stat.',
|
||||||
|
|
||||||
|
statsObjectRequired: '"stats" update is required',
|
||||||
|
|
||||||
|
missingTypeParam: '"req.params.type" is required.',
|
||||||
|
missingKeyParam: '"req.params.key" is required.',
|
||||||
|
itemNotFound: 'Item "<%= key %>" not found.',
|
||||||
|
questNotFound: 'Quest "<%= key %>" not found.',
|
||||||
|
spellNotFound: 'Skill "<%= spellId %>" not found.',
|
||||||
|
invalidTypeEquip: '"type" must be one of "equipped", "pet", "mount", "costume"',
|
||||||
|
missingPetFoodFeed: '"pet" and "food" are required parameters.',
|
||||||
|
missingEggHatchingPotion: '"egg" and "hatchingPotion" are required parameters.',
|
||||||
|
|
||||||
|
invalidPetName: 'Invalid pet name supplied.',
|
||||||
|
invalidFoodName: 'Invalid food name supplied.',
|
||||||
|
};
|
||||||
@@ -201,7 +201,6 @@
|
|||||||
"showQuickAllocation": "Show Stat Allocation",
|
"showQuickAllocation": "Show Stat Allocation",
|
||||||
"hideQuickAllocation": "Hide Stat Allocation",
|
"hideQuickAllocation": "Hide Stat Allocation",
|
||||||
"quickAllocationLevelPopover": "Each level earns you one Point to assign to a Stat of your choice. You can do so manually, or let the game decide for you using one of the Automatic Allocation options found in User Icon > Stats.",
|
"quickAllocationLevelPopover": "Each level earns you one Point to assign to a Stat of your choice. You can do so manually, or let the game decide for you using one of the Automatic Allocation options found in User Icon > Stats.",
|
||||||
"invalidAttribute": "\"<%= attr %>\" is not a valid Stat.",
|
|
||||||
"notEnoughAttrPoints": "You don't have enough Stat Points.",
|
"notEnoughAttrPoints": "You don't have enough Stat Points.",
|
||||||
"style": "Style",
|
"style": "Style",
|
||||||
"facialhair": "Facial",
|
"facialhair": "Facial",
|
||||||
@@ -224,6 +223,5 @@
|
|||||||
"allocated": "Allocated",
|
"allocated": "Allocated",
|
||||||
"buffs": "Buffs",
|
"buffs": "Buffs",
|
||||||
"pointsAvailable": "Points Available",
|
"pointsAvailable": "Points Available",
|
||||||
"pts": "pts",
|
"pts": "pts"
|
||||||
"statsObjectRequired": "Stats update is required"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,6 @@
|
|||||||
"UUID": "User ID",
|
"UUID": "User ID",
|
||||||
"loadUser": "Load User",
|
"loadUser": "Load User",
|
||||||
"noAdminAccess": "You don't have admin access.",
|
"noAdminAccess": "You don't have admin access.",
|
||||||
"pageMustBeNumber": "req.query.page must be a number",
|
|
||||||
"userNotFound": "User not found.",
|
"userNotFound": "User not found.",
|
||||||
"invalidUUID": "UUID must be valid",
|
"invalidUUID": "UUID must be valid",
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
|
|||||||
@@ -210,7 +210,6 @@
|
|||||||
"partyOnName": "Party On",
|
"partyOnName": "Party On",
|
||||||
"partyUpText": "Joined a Party with another person! Have fun battling monsters and supporting each other.",
|
"partyUpText": "Joined a Party with another person! Have fun battling monsters and supporting each other.",
|
||||||
"partyOnText": "Joined a Party with at least four people! Enjoy your increased accountability as you unite with your friends to vanquish your foes!",
|
"partyOnText": "Joined a Party with at least four people! Enjoy your increased accountability as you unite with your friends to vanquish your foes!",
|
||||||
"groupIdRequired": "\"groupId\" must be a valid UUID",
|
|
||||||
"groupNotFound": "Group not found or you don't have access.",
|
"groupNotFound": "Group not found or you don't have access.",
|
||||||
"groupTypesRequired": "You must supply a valid \"type\" query string.",
|
"groupTypesRequired": "You must supply a valid \"type\" query string.",
|
||||||
"questLeaderCannotLeaveGroup": "You cannot leave your Party when you have started a quest. Abort the quest first.",
|
"questLeaderCannotLeaveGroup": "You cannot leave your Party when you have started a quest. Abort the quest first.",
|
||||||
@@ -220,8 +219,6 @@
|
|||||||
"memberCannotRemoveYourself": "You cannot remove yourself!",
|
"memberCannotRemoveYourself": "You cannot remove yourself!",
|
||||||
"groupMemberNotFound": "User not found among group's members",
|
"groupMemberNotFound": "User not found among group's members",
|
||||||
"mustBeGroupMember": "Must be member of the group.",
|
"mustBeGroupMember": "Must be member of the group.",
|
||||||
"keepOrRemoveAll": "req.query.keep must be either \"keep-all\" or \"remove-all\"",
|
|
||||||
"keepOrRemove": "req.query.keep must be either \"keep\" or \"remove\"",
|
|
||||||
"canOnlyInviteEmailUuid": "Can only invite using uuids or emails.",
|
"canOnlyInviteEmailUuid": "Can only invite using uuids or emails.",
|
||||||
"inviteMissingEmail": "Missing email address in invite.",
|
"inviteMissingEmail": "Missing email address in invite.",
|
||||||
"inviteMissingUuid": "Missing user id in invite",
|
"inviteMissingUuid": "Missing user id in invite",
|
||||||
@@ -328,7 +325,6 @@
|
|||||||
"cantDeleteAssignedGroupTasks": "Can't delete group tasks that are assigned to you.",
|
"cantDeleteAssignedGroupTasks": "Can't delete group tasks that are assigned to you.",
|
||||||
"confirmGuildPlanCreation": "Create this group?",
|
"confirmGuildPlanCreation": "Create this group?",
|
||||||
"onlyGroupLeaderCanInviteToGroupPlan": "Only the group leader can invite users to a group with a subscription.",
|
"onlyGroupLeaderCanInviteToGroupPlan": "Only the group leader can invite users to a group with a subscription.",
|
||||||
"remainOrLeaveChallenges": "req.query.keep must be either 'remain-in-challenges' or 'leave-challenges'",
|
|
||||||
"paymentDetails": "Payment Details",
|
"paymentDetails": "Payment Details",
|
||||||
"aboutToJoinCancelledGroupPlan": "You are about to join a group with a canceled plan. You will NOT receive a free subscription.",
|
"aboutToJoinCancelledGroupPlan": "You are about to join a group with a canceled plan. You will NOT receive a free subscription.",
|
||||||
"cannotChangeLeaderWithActiveGroupPlan": "You can not change the leader while the group has an active plan.",
|
"cannotChangeLeaderWithActiveGroupPlan": "You can not change the leader while the group has an active plan.",
|
||||||
|
|||||||
@@ -82,14 +82,7 @@
|
|||||||
"ianBrokenText": "Welcome to the Quest Shop... Here you can use Quest Scrolls to battle monsters with your friends... Be sure to check out our fine array of Quest Scrolls for purchase on the right...",
|
"ianBrokenText": "Welcome to the Quest Shop... Here you can use Quest Scrolls to battle monsters with your friends... Be sure to check out our fine array of Quest Scrolls for purchase on the right...",
|
||||||
"featuredQuests": "Featured Quests!",
|
"featuredQuests": "Featured Quests!",
|
||||||
|
|
||||||
"missingKeyParam": "\"req.params.key\" is required.",
|
|
||||||
"itemNotFound": "Item \"<%= key %>\" not found.",
|
|
||||||
"cannotBuyItem": "You can't buy this item.",
|
"cannotBuyItem": "You can't buy this item.",
|
||||||
"missingTypeKeyEquip": "\"key\" and \"type\" are required parameters.",
|
|
||||||
"missingPetFoodFeed": "\"pet\" and \"food\" are required parameters.",
|
|
||||||
"invalidPetName": "Invalid pet name supplied.",
|
|
||||||
"missingEggHatchingPotionHatch": "\"egg\" and \"hatchingPotion\" are required parameters.",
|
|
||||||
"invalidTypeEquip": "\"type\" must be one of 'equipped', 'pet', 'mount', 'costume'.",
|
|
||||||
"mustPurchaseToSet": "Must purchase <%= val %> to set it on <%= key %>.",
|
"mustPurchaseToSet": "Must purchase <%= val %> to set it on <%= key %>.",
|
||||||
"typeRequired": "Type is required",
|
"typeRequired": "Type is required",
|
||||||
"positiveAmountRequired": "Positive amount is required",
|
"positiveAmountRequired": "Positive amount is required",
|
||||||
|
|||||||
@@ -96,7 +96,6 @@
|
|||||||
"questInvitationDoesNotExist": "No quest invitation has been sent out yet.",
|
"questInvitationDoesNotExist": "No quest invitation has been sent out yet.",
|
||||||
"questInviteNotFound": "No quest invitation found.",
|
"questInviteNotFound": "No quest invitation found.",
|
||||||
"guildQuestsNotSupported": "Guilds cannot be invited on quests.",
|
"guildQuestsNotSupported": "Guilds cannot be invited on quests.",
|
||||||
"questNotFound": "Quest \"<%= key %>\" not found.",
|
|
||||||
"questNotOwned": "You don't own that quest scroll.",
|
"questNotOwned": "You don't own that quest scroll.",
|
||||||
"questNotGoldPurchasable": "Quest \"<%= key %>\" is not a Gold-purchasable quest.",
|
"questNotGoldPurchasable": "Quest \"<%= key %>\" is not a Gold-purchasable quest.",
|
||||||
"questLevelTooHigh": "You must be level <%= level %> to begin this quest.",
|
"questLevelTooHigh": "You must be level <%= level %> to begin this quest.",
|
||||||
|
|||||||
@@ -72,7 +72,6 @@
|
|||||||
"spellSpecialSandText": "Sand",
|
"spellSpecialSandText": "Sand",
|
||||||
"spellSpecialSandNotes": "Reverse the spell that made you a sea star.",
|
"spellSpecialSandNotes": "Reverse the spell that made you a sea star.",
|
||||||
|
|
||||||
"spellNotFound": "Skill \"<%= spellId %>\" not found.",
|
|
||||||
"partyNotFound": "Party not found",
|
"partyNotFound": "Party not found",
|
||||||
"targetIdUUID": "\"targetId\" must be a valid User ID.",
|
"targetIdUUID": "\"targetId\" must be a valid User ID.",
|
||||||
"challengeTasksNoCast": "Casting a skill on challenge tasks is not allowed.",
|
"challengeTasksNoCast": "Casting a skill on challenge tasks is not allowed.",
|
||||||
|
|||||||
@@ -178,12 +178,6 @@
|
|||||||
"invalidCoupon": "Invalid coupon code.",
|
"invalidCoupon": "Invalid coupon code.",
|
||||||
"couponUsed": "Coupon code already used.",
|
"couponUsed": "Coupon code already used.",
|
||||||
"couponCodeRequired": "The coupon code is required.",
|
"couponCodeRequired": "The coupon code is required.",
|
||||||
"eventRequired": "\"req.params.event\" is required.",
|
|
||||||
"countRequired": "\"req.query.count\" is required.",
|
|
||||||
"missingPaymentId": "Missing req.query.paymentId",
|
|
||||||
"missingCustomerId": "Missing req.query.customerId",
|
|
||||||
"missingPaypalBlock": "Missing req.session.paypalBlock",
|
|
||||||
"missingSubKey": "Missing req.query.sub",
|
|
||||||
"paypalCanceled": "Your subscription has been canceled",
|
"paypalCanceled": "Your subscription has been canceled",
|
||||||
"earnGemsMonthly": "Earn up to **<%= cap %> Gems** per month",
|
"earnGemsMonthly": "Earn up to **<%= cap %> Gems** per month",
|
||||||
"receiveMysticHourglass": "Receive a Mystic Hourglass!",
|
"receiveMysticHourglass": "Receive a Mystic Hourglass!",
|
||||||
|
|||||||
@@ -145,7 +145,6 @@
|
|||||||
"rewardHelp3": "Special equipment will appear here during World Events.",
|
"rewardHelp3": "Special equipment will appear here during World Events.",
|
||||||
"rewardHelp4": "Don't be afraid to set custom Rewards! Check out <a href='http://habitica.wikia.com/wiki/Sample_Custom_Rewards' target='_blank'>some samples here</a>.",
|
"rewardHelp4": "Don't be afraid to set custom Rewards! Check out <a href='http://habitica.wikia.com/wiki/Sample_Custom_Rewards' target='_blank'>some samples here</a>.",
|
||||||
"clickForHelp": "Click for help",
|
"clickForHelp": "Click for help",
|
||||||
"taskIdRequired": "\"taskId\" must be a valid UUID.",
|
|
||||||
"taskAliasAlreadyUsed": "Task alias already used on another task.",
|
"taskAliasAlreadyUsed": "Task alias already used on another task.",
|
||||||
"taskNotFound": "Task not found.",
|
"taskNotFound": "Task not found.",
|
||||||
"invalidTaskType": "Task type must be one of \"habit\", \"daily\", \"todo\", \"reward\".",
|
"invalidTaskType": "Task type must be one of \"habit\", \"daily\", \"todo\", \"reward\".",
|
||||||
|
|||||||
16
website/common/script/libs/errorMessage.js
Normal file
16
website/common/script/libs/errorMessage.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// errorMessage(key) will be called by all common-ops , which is also imported to the website
|
||||||
|
|
||||||
|
import _clone from 'lodash/clone';
|
||||||
|
import _template from 'lodash/template';
|
||||||
|
|
||||||
|
import messages from '../../errors/commonErrorMessages';
|
||||||
|
|
||||||
|
export default function (msgKey, vars = {}) {
|
||||||
|
let message = messages[msgKey];
|
||||||
|
if (!message) throw new Error(`Error processing the common message "${msgKey}".`);
|
||||||
|
|
||||||
|
let clonedVars = vars ? _clone(vars) : {};
|
||||||
|
|
||||||
|
// TODO cache the result of template() ? More memory usage, faster output
|
||||||
|
return _template(message)(clonedVars);
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import i18n from '../../i18n';
|
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import {
|
import {
|
||||||
BadRequest,
|
BadRequest,
|
||||||
@@ -11,6 +10,7 @@ import {BuyQuestWithGoldOperation} from './buyQuest';
|
|||||||
import buySpecialSpell from './buySpecialSpell';
|
import buySpecialSpell from './buySpecialSpell';
|
||||||
import purchaseOp from './purchase';
|
import purchaseOp from './purchase';
|
||||||
import hourglassPurchase from './hourglassPurchase';
|
import hourglassPurchase from './hourglassPurchase';
|
||||||
|
import errorMessage from '../../libs/errorMessage';
|
||||||
import {BuyGemOperation} from './buyGem';
|
import {BuyGemOperation} from './buyGem';
|
||||||
|
|
||||||
// @TODO: remove the req option style. Dependency on express structure is an anti-pattern
|
// @TODO: remove the req option style. Dependency on express structure is an anti-pattern
|
||||||
@@ -20,7 +20,7 @@ import {BuyGemOperation} from './buyGem';
|
|||||||
|
|
||||||
module.exports = function buy (user, req = {}, analytics) {
|
module.exports = function buy (user, req = {}, analytics) {
|
||||||
let key = get(req, 'params.key');
|
let key = get(req, 'params.key');
|
||||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||||
|
|
||||||
// @TODO: Slowly remove the need for key and use type instead
|
// @TODO: Slowly remove the need for key and use type instead
|
||||||
// This should evenutally be the 'factory' function with vendor classes
|
// This should evenutally be the 'factory' function with vendor classes
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import ultimateGear from '../../fns/ultimateGear';
|
|||||||
import {removePinnedGearAddPossibleNewOnes} from '../pinnedGearUtils';
|
import {removePinnedGearAddPossibleNewOnes} from '../pinnedGearUtils';
|
||||||
|
|
||||||
import { AbstractGoldItemOperation } from './abstractBuyOperation';
|
import { AbstractGoldItemOperation } from './abstractBuyOperation';
|
||||||
|
import errorMessage from '../../libs/errorMessage';
|
||||||
|
|
||||||
export class BuyMarketGearOperation extends AbstractGoldItemOperation {
|
export class BuyMarketGearOperation extends AbstractGoldItemOperation {
|
||||||
constructor (user, req, analytics) {
|
constructor (user, req, analytics) {
|
||||||
@@ -25,9 +26,10 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation {
|
|||||||
|
|
||||||
extractAndValidateParams (user, req) {
|
extractAndValidateParams (user, req) {
|
||||||
let key = this.key = get(req, 'params.key');
|
let key = this.key = get(req, 'params.key');
|
||||||
if (!key) throw new BadRequest(this.i18n('missingKeyParam'));
|
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||||
|
|
||||||
let item = content.gear.flat[key];
|
let item = content.gear.flat[key];
|
||||||
if (!item) throw new NotFound(this.i18n('itemNotFound', {key}));
|
if (!item) throw new NotFound(errorMessage('itemNotFound', {key}));
|
||||||
|
|
||||||
this.canUserPurchase(user, item);
|
this.canUserPurchase(user, item);
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ import {
|
|||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
NotFound,
|
NotFound,
|
||||||
} from '../../libs/errors';
|
} from '../../libs/errors';
|
||||||
|
import errorMessage from '../../libs/errorMessage';
|
||||||
|
|
||||||
module.exports = function buyMysterySet (user, req = {}, analytics) {
|
module.exports = function buyMysterySet (user, req = {}, analytics) {
|
||||||
let key = get(req, 'params.key');
|
let key = get(req, 'params.key');
|
||||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||||
|
|
||||||
if (!(user.purchased.plan.consecutive.trinkets > 0)) {
|
if (!(user.purchased.plan.consecutive.trinkets > 0)) {
|
||||||
throw new NotAuthorized(i18n.t('notEnoughHourglasses', req.language));
|
throw new NotAuthorized(i18n.t('notEnoughHourglasses', req.language));
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import content from '../../content/index';
|
|||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
|
|
||||||
import {AbstractGoldItemOperation} from './abstractBuyOperation';
|
import {AbstractGoldItemOperation} from './abstractBuyOperation';
|
||||||
|
import errorMessage from '../../libs/errorMessage';
|
||||||
|
|
||||||
export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
|
export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
|
||||||
constructor (user, req, analytics) {
|
constructor (user, req, analytics) {
|
||||||
@@ -30,7 +31,7 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
|
|||||||
|
|
||||||
extractAndValidateParams (user, req) {
|
extractAndValidateParams (user, req) {
|
||||||
let key = this.key = get(req, 'params.key');
|
let key = this.key = get(req, 'params.key');
|
||||||
if (!key) throw new BadRequest(this.i18n('missingKeyParam'));
|
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||||
|
|
||||||
if (key === 'lostMasterclasser1' && !this.userAbleToStartMasterClasser(user)) {
|
if (key === 'lostMasterclasser1' && !this.userAbleToStartMasterClasser(user)) {
|
||||||
throw new NotAuthorized(this.i18n('questUnlockLostMasterclasser'));
|
throw new NotAuthorized(this.i18n('questUnlockLostMasterclasser'));
|
||||||
@@ -38,7 +39,7 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
|
|||||||
|
|
||||||
let item = content.quests[key];
|
let item = content.quests[key];
|
||||||
|
|
||||||
if (!item) throw new NotFound(this.i18n('questNotFound', {key}));
|
if (!item) throw new NotFound(errorMessage('questNotFound', {key}));
|
||||||
|
|
||||||
if (!(item.category === 'gold' && item.goldValue)) {
|
if (!(item.category === 'gold' && item.goldValue)) {
|
||||||
throw new NotAuthorized(this.i18n('questNotGoldPurchasable', {key}));
|
throw new NotAuthorized(this.i18n('questNotGoldPurchasable', {key}));
|
||||||
|
|||||||
@@ -8,15 +8,16 @@ import {
|
|||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
NotFound,
|
NotFound,
|
||||||
} from '../../libs/errors';
|
} from '../../libs/errors';
|
||||||
|
import errorMessage from '../../libs/errorMessage';
|
||||||
|
|
||||||
module.exports = function buySpecialSpell (user, req = {}, analytics) {
|
module.exports = function buySpecialSpell (user, req = {}, analytics) {
|
||||||
let key = get(req, 'params.key');
|
let key = get(req, 'params.key');
|
||||||
let quantity = req.quantity || 1;
|
let quantity = req.quantity || 1;
|
||||||
|
|
||||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||||
|
|
||||||
let item = content.special[key];
|
let item = content.special[key];
|
||||||
if (!item) throw new NotFound(i18n.t('spellNotFound', {spellId: key}, req.language));
|
if (!item) throw new NotFound(errorMessage('spellNotFound', {spellId: key}));
|
||||||
|
|
||||||
if (user.stats.gp < item.value * quantity) {
|
if (user.stats.gp < item.value * quantity) {
|
||||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ import {
|
|||||||
BadRequest,
|
BadRequest,
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../../libs/errors';
|
} from '../../libs/errors';
|
||||||
|
import errorMessage from '../../libs/errorMessage';
|
||||||
|
|
||||||
module.exports = function purchaseHourglass (user, req = {}, analytics) {
|
module.exports = function purchaseHourglass (user, req = {}, analytics) {
|
||||||
let key = get(req, 'params.key');
|
let key = get(req, 'params.key');
|
||||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||||
|
|
||||||
let type = get(req, 'params.type');
|
let type = get(req, 'params.type');
|
||||||
if (!type) throw new BadRequest(i18n.t('missingTypeParam', req.language));
|
if (!type) throw new BadRequest(errorMessage('missingTypeParam'));
|
||||||
|
|
||||||
if (!content.timeTravelStable[type]) {
|
if (!content.timeTravelStable[type]) {
|
||||||
throw new NotAuthorized(i18n.t('typeNotAllowedHourglass', {allowedTypes: keys(content.timeTravelStable).toString()}, req.language));
|
throw new NotAuthorized(i18n.t('typeNotAllowedHourglass', {allowedTypes: keys(content.timeTravelStable).toString()}, req.language));
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
BadRequest,
|
BadRequest,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
|
import errorMessage from '../libs/errorMessage';
|
||||||
|
|
||||||
module.exports = function equip (user, req = {}) {
|
module.exports = function equip (user, req = {}) {
|
||||||
// Being type a parameter followed by another parameter
|
// Being type a parameter followed by another parameter
|
||||||
@@ -13,9 +14,9 @@ module.exports = function equip (user, req = {}) {
|
|||||||
let type = get(req, 'params.type', 'equipped');
|
let type = get(req, 'params.type', 'equipped');
|
||||||
let key = get(req, 'params.key');
|
let key = get(req, 'params.key');
|
||||||
|
|
||||||
if (!key || !type) throw new BadRequest(i18n.t('missingTypeKeyEquip', req.language));
|
if (!key || !type) throw new BadRequest(errorMessage('missingTypeKeyEquip'));
|
||||||
if (['mount', 'pet', 'costume', 'equipped'].indexOf(type) === -1) {
|
if (['mount', 'pet', 'costume', 'equipped'].indexOf(type) === -1) {
|
||||||
throw new BadRequest(i18n.t('invalidTypeEquip', req.language));
|
throw new BadRequest(errorMessage('invalidTypeEquip'));
|
||||||
}
|
}
|
||||||
|
|
||||||
let message;
|
let message;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
NotFound,
|
NotFound,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
|
import errorMessage from '../libs/errorMessage';
|
||||||
|
|
||||||
function evolve (user, pet, req) {
|
function evolve (user, pet, req) {
|
||||||
user.items.pets[pet.key] = -1;
|
user.items.pets[pet.key] = -1;
|
||||||
@@ -24,17 +25,17 @@ module.exports = function feed (user, req = {}) {
|
|||||||
let pet = get(req, 'params.pet');
|
let pet = get(req, 'params.pet');
|
||||||
let foodK = get(req, 'params.food');
|
let foodK = get(req, 'params.food');
|
||||||
|
|
||||||
if (!pet || !foodK) throw new BadRequest(i18n.t('missingPetFoodFeed', req.language));
|
if (!pet || !foodK) throw new BadRequest(errorMessage('missingPetFoodFeed'));
|
||||||
|
|
||||||
pet = content.petInfo[pet];
|
pet = content.petInfo[pet];
|
||||||
|
|
||||||
if (!pet) {
|
if (!pet) {
|
||||||
throw new BadRequest(i18n.t('invalidPetName', req.language));
|
throw new BadRequest(errorMessage('invalidPetName'));
|
||||||
}
|
}
|
||||||
|
|
||||||
let food = content.food[foodK];
|
let food = content.food[foodK];
|
||||||
if (!food) {
|
if (!food) {
|
||||||
throw new NotFound(i18n.t('messageFoodNotFound', req.language));
|
throw new NotFound(errorMessage('invalidFoodName', req.language));
|
||||||
}
|
}
|
||||||
|
|
||||||
let userPets = user.items.pets;
|
let userPets = user.items.pets;
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ import {
|
|||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
NotFound,
|
NotFound,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
|
import errorMessage from '../libs/errorMessage';
|
||||||
|
|
||||||
module.exports = function hatch (user, req = {}) {
|
module.exports = function hatch (user, req = {}) {
|
||||||
let egg = get(req, 'params.egg');
|
let egg = get(req, 'params.egg');
|
||||||
let hatchingPotion = get(req, 'params.hatchingPotion');
|
let hatchingPotion = get(req, 'params.hatchingPotion');
|
||||||
|
|
||||||
if (!(egg && hatchingPotion)) {
|
if (!(egg && hatchingPotion)) {
|
||||||
throw new BadRequest(i18n.t('missingEggHatchingPotionHatch', req.language));
|
throw new BadRequest(errorMessage('missingEggHatchingPotion'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(user.items.eggs[egg] > 0 && user.items.hatchingPotions[hatchingPotion] > 0)) {
|
if (!(user.items.eggs[egg] > 0 && user.items.hatchingPotions[hatchingPotion] > 0)) {
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import {
|
|||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../../libs/errors';
|
} from '../../libs/errors';
|
||||||
import i18n from '../../i18n';
|
import i18n from '../../i18n';
|
||||||
|
import errorMessage from '../../libs/errorMessage';
|
||||||
|
|
||||||
module.exports = function allocate (user, req = {}) {
|
module.exports = function allocate (user, req = {}) {
|
||||||
let stat = get(req, 'query.stat', 'str');
|
let stat = get(req, 'query.stat', 'str');
|
||||||
|
|
||||||
if (ATTRIBUTES.indexOf(stat) === -1) {
|
if (ATTRIBUTES.indexOf(stat) === -1) {
|
||||||
throw new BadRequest(i18n.t('invalidAttribute', {attr: stat}, req.language));
|
throw new BadRequest(errorMessage('invalidAttribute', {attr: stat}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.stats.points > 0) {
|
if (user.stats.points > 0) {
|
||||||
|
|||||||
@@ -7,17 +7,18 @@ import {
|
|||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../../libs/errors';
|
} from '../../libs/errors';
|
||||||
import i18n from '../../i18n';
|
import i18n from '../../i18n';
|
||||||
|
import errorMessage from '../../libs/errorMessage';
|
||||||
|
|
||||||
module.exports = function allocateBulk (user, req = {}) {
|
module.exports = function allocateBulk (user, req = {}) {
|
||||||
const stats = get(req, 'body.stats');
|
const stats = get(req, 'body.stats');
|
||||||
if (!stats) throw new BadRequest(i18n.t('statsObjectRequired', req.language));
|
if (!stats) throw new BadRequest(errorMessage('statsObjectRequired'));
|
||||||
|
|
||||||
const statKeys = Object.keys(stats);
|
const statKeys = Object.keys(stats);
|
||||||
const invalidStats = statKeys.filter(statKey => {
|
const invalidStats = statKeys.filter(statKey => {
|
||||||
return ATTRIBUTES.indexOf(statKey) === -1;
|
return ATTRIBUTES.indexOf(statKey) === -1;
|
||||||
});
|
});
|
||||||
if (invalidStats.length > 0) {
|
if (invalidStats.length > 0) {
|
||||||
throw new BadRequest(i18n.t('invalidAttribute', {attr: invalidStats.join(',')}, req.language));
|
throw new BadRequest(errorMessage('invalidAttribute', {attr: invalidStats.join(',')}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.stats.points <= 0) {
|
if (user.stats.points <= 0) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
createChallenge,
|
createChallenge,
|
||||||
cleanUpTask,
|
cleanUpTask,
|
||||||
} from '../../libs/challenges';
|
} from '../../libs/challenges';
|
||||||
|
import apiError from '../../libs/apiError';
|
||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
@@ -189,7 +190,7 @@ api.createChallenge = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkBody('group', res.t('groupIdRequired')).notEmpty();
|
req.checkBody('group', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
const validationErrors = req.validationErrors();
|
const validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -454,7 +455,7 @@ api.getGroupChallenges = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import bannedWords from '../../libs/bannedWords';
|
|||||||
import guildsAllowingBannedWords from '../../libs/guildsAllowingBannedWords';
|
import guildsAllowingBannedWords from '../../libs/guildsAllowingBannedWords';
|
||||||
import { getMatchesByWordArray } from '../../libs/stringUtils';
|
import { getMatchesByWordArray } from '../../libs/stringUtils';
|
||||||
import bannedSlurs from '../../libs/bannedSlurs';
|
import bannedSlurs from '../../libs/bannedSlurs';
|
||||||
|
import apiError from '../../libs/apiError';
|
||||||
|
|
||||||
const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
|
const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
|
||||||
return { email, canSend: true };
|
return { email, canSend: true };
|
||||||
@@ -67,7 +68,7 @@ api.getChat = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -110,7 +111,7 @@ api.postChat = {
|
|||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
let chatUpdated;
|
let chatUpdated;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
req.sanitize('message').trim();
|
req.sanitize('message').trim();
|
||||||
req.checkBody('message', res.t('messageGroupChatBlankMessage')).notEmpty();
|
req.checkBody('message', res.t('messageGroupChatBlankMessage')).notEmpty();
|
||||||
|
|
||||||
@@ -232,7 +233,7 @@ api.likeChat = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
req.checkParams('chatId', res.t('chatIdRequired')).notEmpty();
|
req.checkParams('chatId', res.t('chatIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -323,7 +324,7 @@ api.clearChatFlags = {
|
|||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
let chatId = req.params.chatId;
|
let chatId = req.params.chatId;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
req.checkParams('chatId', res.t('chatIdRequired')).notEmpty();
|
req.checkParams('chatId', res.t('chatIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -394,7 +395,7 @@ api.seenChat = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -463,7 +464,7 @@ api.deleteChat = {
|
|||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
let chatId = req.params.chatId;
|
let chatId = req.params.chatId;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
req.checkParams('chatId', res.t('chatIdRequired')).notEmpty();
|
req.checkParams('chatId', res.t('chatIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { ensureSudo } from '../../middlewares/ensureAccessRight';
|
|||||||
import { model as Coupon } from '../../models/coupon';
|
import { model as Coupon } from '../../models/coupon';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import couponCode from 'coupon-code';
|
import couponCode from 'coupon-code';
|
||||||
|
import apiError from '../../libs/apiError';
|
||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
@@ -71,8 +72,8 @@ api.generateCoupons = {
|
|||||||
userFieldsToExclude: ['inbox'],
|
userFieldsToExclude: ['inbox'],
|
||||||
}), ensureSudo],
|
}), ensureSudo],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('event', res.t('eventRequired')).notEmpty();
|
req.checkParams('event', apiError('eventRequired')).notEmpty();
|
||||||
req.checkQuery('count', res.t('countRequired')).notEmpty().isNumeric();
|
req.checkQuery('count', apiError('countRequired')).notEmpty().isNumeric();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import payments from '../../libs/payments/payments';
|
|||||||
import stripePayments from '../../libs/payments/stripe';
|
import stripePayments from '../../libs/payments/stripe';
|
||||||
import amzLib from '../../libs/payments/amazon';
|
import amzLib from '../../libs/payments/amazon';
|
||||||
import shared from '../../../common';
|
import shared from '../../../common';
|
||||||
import apiMessages from '../../libs/apiMessages';
|
import apiError from '../../libs/apiError';
|
||||||
|
|
||||||
const MAX_EMAIL_INVITES_BY_USER = 200;
|
const MAX_EMAIL_INVITES_BY_USER = 200;
|
||||||
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL');
|
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL');
|
||||||
@@ -279,7 +279,7 @@ api.createGroupPlan = {
|
|||||||
*
|
*
|
||||||
* @apiError (400) {BadRequest} groupTypesRequired Group types are required
|
* @apiError (400) {BadRequest} groupTypesRequired Group types are required
|
||||||
* @apiError (400) {BadRequest} guildsPaginateBooleanString Paginate query parameter must be a boolean (true or false)
|
* @apiError (400) {BadRequest} guildsPaginateBooleanString Paginate query parameter must be a boolean (true or false)
|
||||||
* @apiError (400) {BadRequest} guildsPageInteger Page query parameter must be a positive integer
|
* @apiError (400) {BadRequest} queryPageInteger Page query parameter must be a positive integer
|
||||||
* @apiError (400) {BadRequest} guildsOnlyPaginate Only public guilds support pagination
|
* @apiError (400) {BadRequest} guildsOnlyPaginate Only public guilds support pagination
|
||||||
*
|
*
|
||||||
* @apiSuccess {Object[]} data An array of the requested groups (See <a href="https://github.com/HabitRPG/habitica/blob/develop/website/server/models/group.js" target="_blank">/website/server/models/group.js</a>)
|
* @apiSuccess {Object[]} data An array of the requested groups (See <a href="https://github.com/HabitRPG/habitica/blob/develop/website/server/models/group.js" target="_blank">/website/server/models/group.js</a>)
|
||||||
@@ -301,8 +301,8 @@ api.getGroups = {
|
|||||||
|
|
||||||
req.checkQuery('type', res.t('groupTypesRequired')).notEmpty();
|
req.checkQuery('type', res.t('groupTypesRequired')).notEmpty();
|
||||||
// pagination options, can only be used with public guilds
|
// pagination options, can only be used with public guilds
|
||||||
req.checkQuery('paginate').optional().isIn(['true', 'false'], apiMessages('guildsPaginateBooleanString'));
|
req.checkQuery('paginate').optional().isIn(['true', 'false'], apiError('guildsPaginateBooleanString'));
|
||||||
req.checkQuery('page').optional().isInt({min: 0}, apiMessages('guildsPageInteger'));
|
req.checkQuery('page').optional().isInt({min: 0}, apiError('queryPageInteger'));
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -311,7 +311,7 @@ api.getGroups = {
|
|||||||
|
|
||||||
let paginate = req.query.paginate === 'true' ? true : false;
|
let paginate = req.query.paginate === 'true' ? true : false;
|
||||||
if (paginate && !_.includes(types, 'publicGuilds')) {
|
if (paginate && !_.includes(types, 'publicGuilds')) {
|
||||||
throw new BadRequest(apiMessages('guildsOnlyPaginate'));
|
throw new BadRequest(apiError('guildsOnlyPaginate'));
|
||||||
}
|
}
|
||||||
|
|
||||||
let groupFields = basicGroupFields.concat(' description memberCount balance');
|
let groupFields = basicGroupFields.concat(' description memberCount balance');
|
||||||
@@ -389,7 +389,7 @@ api.getGroup = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -449,7 +449,7 @@ api.updateGroup = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -515,7 +515,7 @@ api.joinGroup = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let inviter;
|
let inviter;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -687,7 +687,7 @@ api.rejectGroupInvite = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -763,10 +763,10 @@ api.leaveGroup = {
|
|||||||
})],
|
})],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
// When removing the user from challenges, should we keep the tasks?
|
// When removing the user from challenges, should we keep the tasks?
|
||||||
req.checkQuery('keep', res.t('keepOrRemoveAll')).optional().isIn(['keep-all', 'remove-all']);
|
req.checkQuery('keep', apiError('keepOrRemoveAll')).optional().isIn(['keep-all', 'remove-all']);
|
||||||
req.checkBody('keepChallenges', res.t('remainOrLeaveChallenges')).optional().isIn(['remain-in-challenges', 'leave-challenges']);
|
req.checkBody('keepChallenges', apiError('groupRemainOrLeaveChallenges')).optional().isIn(['remain-in-challenges', 'leave-challenges']);
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -853,7 +853,7 @@ api.removeGroupMember = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
req.checkParams('memberId', res.t('userIdRequired')).notEmpty().isUUID();
|
req.checkParams('memberId', res.t('userIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -1175,7 +1175,7 @@ api.inviteToGroup = {
|
|||||||
|
|
||||||
if (user.flags.chatRevoked) throw new NotAuthorized(res.t('cannotInviteWhenMuted'));
|
if (user.flags.chatRevoked) throw new NotAuthorized(res.t('cannotInviteWhenMuted'));
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
if (user.invitesSent >= MAX_EMAIL_INVITES_BY_USER) throw new NotAuthorized(res.t('inviteLimitReached', { techAssistanceEmail: TECH_ASSISTANCE_EMAIL }));
|
if (user.invitesSent >= MAX_EMAIL_INVITES_BY_USER) throw new NotAuthorized(res.t('inviteLimitReached', { techAssistanceEmail: TECH_ASSISTANCE_EMAIL }));
|
||||||
|
|
||||||
@@ -1239,8 +1239,8 @@ api.addGroupManager = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let managerId = req.body.managerId;
|
let managerId = req.body.managerId;
|
||||||
|
|
||||||
req.checkParams('groupId', apiMessages('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
|
||||||
req.checkBody('managerId', apiMessages('managerIdRequired')).notEmpty();
|
req.checkBody('managerId', apiError('managerIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -1290,8 +1290,8 @@ api.removeGroupManager = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let managerId = req.body.managerId;
|
let managerId = req.body.managerId;
|
||||||
|
|
||||||
req.checkParams('groupId', apiMessages('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
|
||||||
req.checkBody('managerId', apiMessages('managerIdRequired')).notEmpty();
|
req.checkBody('managerId', apiError('managerIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
NotFound,
|
NotFound,
|
||||||
} from '../../libs/errors';
|
} from '../../libs/errors';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import apiError from '../../libs/apiError';
|
||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ api.getPatrons = {
|
|||||||
userFieldsToExclude: ['inbox'],
|
userFieldsToExclude: ['inbox'],
|
||||||
})],
|
})],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkQuery('page', res.t('pageMustBeNumber')).optional().isNumeric();
|
req.checkQuery('page').optional().isInt({min: 0}, apiError('queryPageInteger'));
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
} from '../../libs/email';
|
} from '../../libs/email';
|
||||||
import common from '../../../common';
|
import common from '../../../common';
|
||||||
import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
|
import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
|
||||||
|
import apiError from '../../libs/apiError';
|
||||||
|
|
||||||
const questScrolls = common.content.quests;
|
const questScrolls = common.content.quests;
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ api.inviteToQuest = {
|
|||||||
let questKey = req.params.questKey;
|
let questKey = req.params.questKey;
|
||||||
let quest = questScrolls[questKey];
|
let quest = questScrolls[questKey];
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -71,7 +72,7 @@ api.inviteToQuest = {
|
|||||||
|
|
||||||
if (!group) throw new NotFound(res.t('groupNotFound'));
|
if (!group) throw new NotFound(res.t('groupNotFound'));
|
||||||
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
|
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
|
||||||
if (!quest) throw new NotFound(res.t('questNotFound', { key: questKey }));
|
if (!quest) throw new NotFound(apiError('questNotFound', { key: questKey }));
|
||||||
if (!user.items.quests[questKey]) throw new NotAuthorized(res.t('questNotOwned'));
|
if (!user.items.quests[questKey]) throw new NotAuthorized(res.t('questNotOwned'));
|
||||||
if (user.stats.lvl < quest.lvl) throw new NotAuthorized(res.t('questLevelTooHigh', { level: quest.lvl }));
|
if (user.stats.lvl < quest.lvl) throw new NotAuthorized(res.t('questLevelTooHigh', { level: quest.lvl }));
|
||||||
if (group.quest.key) throw new NotAuthorized(res.t('questAlreadyUnderway'));
|
if (group.quest.key) throw new NotAuthorized(res.t('questAlreadyUnderway'));
|
||||||
@@ -176,7 +177,7 @@ api.acceptQuest = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -237,7 +238,7 @@ api.rejectQuest = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -302,7 +303,7 @@ api.forceStart = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -366,7 +367,7 @@ api.cancelQuest = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -420,7 +421,7 @@ api.abortQuest = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -481,7 +482,7 @@ api.leaveQuest = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let groupId = req.params.groupId;
|
let groupId = req.params.groupId;
|
||||||
|
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import common from '../../../common';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import logger from '../../libs/logger';
|
import logger from '../../libs/logger';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import apiError from '../../libs/apiError';
|
||||||
|
|
||||||
const MAX_SCORE_NOTES_LENGTH = 256;
|
const MAX_SCORE_NOTES_LENGTH = 256;
|
||||||
|
|
||||||
@@ -430,7 +431,7 @@ api.updateTask = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let challenge;
|
let challenge;
|
||||||
|
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -710,7 +711,7 @@ api.moveTask = {
|
|||||||
url: '/tasks/:taskId/move/to/:position',
|
url: '/tasks/:taskId/move/to/:position',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
|
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -783,7 +784,7 @@ api.addChecklistItem = {
|
|||||||
let challenge;
|
let challenge;
|
||||||
let group;
|
let group;
|
||||||
|
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -841,7 +842,7 @@ api.scoreCheckListItem = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
|
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -897,7 +898,7 @@ api.updateChecklistItem = {
|
|||||||
let challenge;
|
let challenge;
|
||||||
let group;
|
let group;
|
||||||
|
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
|
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -962,7 +963,7 @@ api.removeChecklistItem = {
|
|||||||
let challenge;
|
let challenge;
|
||||||
let group;
|
let group;
|
||||||
|
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
|
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -1023,7 +1024,7 @@ api.addTagToTask = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
let userTags = user.tags.map(tag => tag.id);
|
let userTags = user.tags.map(tag => tag.id);
|
||||||
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID().isIn(userTags);
|
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID().isIn(userTags);
|
||||||
|
|
||||||
@@ -1072,7 +1073,7 @@ api.removeTagFromTask = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID();
|
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -1116,7 +1117,7 @@ api.unlinkAllTasks = {
|
|||||||
middlewares: [authWithHeaders()],
|
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.checkQuery('keep', res.t('keepOrRemoveAll')).notEmpty().isIn(['keep-all', 'remove-all']);
|
req.checkQuery('keep', apiError('keepOrRemoveAll')).notEmpty().isIn(['keep-all', 'remove-all']);
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
@@ -1182,8 +1183,8 @@ api.unlinkOneTask = {
|
|||||||
url: '/tasks/unlink-one/:taskId',
|
url: '/tasks/unlink-one/:taskId',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
|
||||||
req.checkQuery('keep', res.t('keepOrRemove')).notEmpty().isIn(['keep', 'remove']);
|
req.checkQuery('keep', apiError('keepOrRemove')).notEmpty().isIn(['keep', 'remove']);
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
getTasks,
|
getTasks,
|
||||||
moveTask,
|
moveTask,
|
||||||
} from '../../../libs/taskManager';
|
} from '../../../libs/taskManager';
|
||||||
|
import apiError from '../../../libs/apiError';
|
||||||
|
|
||||||
let requiredGroupFields = '_id leader tasksOrder name';
|
let requiredGroupFields = '_id leader tasksOrder name';
|
||||||
let types = Tasks.tasksTypes.map(type => `${type}s`);
|
let types = Tasks.tasksTypes.map(type => `${type}s`);
|
||||||
@@ -40,7 +41,7 @@ api.createGroupTasks = {
|
|||||||
url: '/tasks/group/:groupId',
|
url: '/tasks/group/:groupId',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty().isUUID();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let reqValidationErrors = req.validationErrors();
|
let reqValidationErrors = req.validationErrors();
|
||||||
if (reqValidationErrors) throw reqValidationErrors;
|
if (reqValidationErrors) throw reqValidationErrors;
|
||||||
@@ -84,7 +85,7 @@ api.getGroupTasks = {
|
|||||||
url: '/tasks/group/:groupId',
|
url: '/tasks/group/:groupId',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty().isUUID();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
|
||||||
req.checkQuery('type', res.t('invalidTasksType')).optional().isIn(types);
|
req.checkQuery('type', res.t('invalidTasksType')).optional().isIn(types);
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
@@ -117,7 +118,7 @@ api.groupMoveTask = {
|
|||||||
url: '/group-tasks/:taskId/move/to/:position',
|
url: '/group-tasks/:taskId/move/to/:position',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
|
||||||
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
|
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
|
||||||
|
|
||||||
let reqValidationErrors = req.validationErrors();
|
let reqValidationErrors = req.validationErrors();
|
||||||
@@ -168,7 +169,7 @@ api.assignTask = {
|
|||||||
url: '/tasks/:taskId/assign/:assignedUserId',
|
url: '/tasks/:taskId/assign/:assignedUserId',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
|
||||||
req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID();
|
req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let reqValidationErrors = req.validationErrors();
|
let reqValidationErrors = req.validationErrors();
|
||||||
@@ -228,7 +229,7 @@ api.unassignTask = {
|
|||||||
url: '/tasks/:taskId/unassign/:assignedUserId',
|
url: '/tasks/:taskId/unassign/:assignedUserId',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
|
||||||
req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID();
|
req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let reqValidationErrors = req.validationErrors();
|
let reqValidationErrors = req.validationErrors();
|
||||||
@@ -278,7 +279,7 @@ api.approveTask = {
|
|||||||
url: '/tasks/:taskId/approve/:userId',
|
url: '/tasks/:taskId/approve/:userId',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
|
||||||
req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID();
|
req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let reqValidationErrors = req.validationErrors();
|
let reqValidationErrors = req.validationErrors();
|
||||||
@@ -374,7 +375,7 @@ api.taskNeedsWork = {
|
|||||||
url: '/tasks/:taskId/needs-work/:userId',
|
url: '/tasks/:taskId/needs-work/:userId',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('taskId', res.t('taskIdRequired')).notEmpty().isUUID();
|
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
|
||||||
req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID();
|
req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let reqValidationErrors = req.validationErrors();
|
let reqValidationErrors = req.validationErrors();
|
||||||
@@ -471,7 +472,7 @@ api.getGroupApprovals = {
|
|||||||
url: '/approvals/group/:groupId',
|
url: '/approvals/group/:groupId',
|
||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty().isUUID();
|
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
let validationErrors = req.validationErrors();
|
||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
castPartySpell,
|
castPartySpell,
|
||||||
castUserSpell,
|
castUserSpell,
|
||||||
} from '../../../libs/spells';
|
} from '../../../libs/spells';
|
||||||
|
import apiError from '../../../libs/apiError';
|
||||||
|
|
||||||
const partyMembersFields = 'profile.name stats achievements items.special';
|
const partyMembersFields = 'profile.name stats achievements items.special';
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ api.castSpell = {
|
|||||||
let klass = common.content.spells.special[spellId] ? 'special' : user.stats.class;
|
let klass = common.content.spells.special[spellId] ? 'special' : user.stats.class;
|
||||||
let spell = common.content.spells[klass][spellId];
|
let spell = common.content.spells[klass][spellId];
|
||||||
|
|
||||||
if (!spell) throw new NotFound(res.t('spellNotFound', {spellId}));
|
if (!spell) throw new NotFound(apiError('spellNotFound', {spellId}));
|
||||||
if (spell.mana > user.stats.mp) throw new NotAuthorized(res.t('notEnoughMana'));
|
if (spell.mana > user.stats.mp) throw new NotAuthorized(res.t('notEnoughMana'));
|
||||||
if (spell.value > user.stats.gp && !spell.previousPurchase) throw new NotAuthorized(res.t('messageNotEnoughGold'));
|
if (spell.value > user.stats.gp && !spell.previousPurchase) throw new NotAuthorized(res.t('messageNotEnoughGold'));
|
||||||
if (spell.lvl > user.stats.lvl) throw new NotAuthorized(res.t('spellLevelTooHigh', {level: spell.lvl}));
|
if (spell.lvl > user.stats.lvl) throw new NotAuthorized(res.t('spellLevelTooHigh', {level: spell.lvl}));
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
BadRequest,
|
BadRequest,
|
||||||
} from '../../../libs/errors';
|
} from '../../../libs/errors';
|
||||||
|
import apiError from '../../../libs/apiError';
|
||||||
const i18n = shared.i18n;
|
|
||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
@@ -54,8 +53,8 @@ api.checkoutSuccess = {
|
|||||||
let gift = req.session.gift ? JSON.parse(req.session.gift) : undefined;
|
let gift = req.session.gift ? JSON.parse(req.session.gift) : undefined;
|
||||||
delete req.session.gift;
|
delete req.session.gift;
|
||||||
|
|
||||||
if (!paymentId) throw new BadRequest(i18n.t('missingPaymentId'));
|
if (!paymentId) throw new BadRequest(apiError('missingPaymentId'));
|
||||||
if (!customerId) throw new BadRequest(i18n.t('missingCustomerId'));
|
if (!customerId) throw new BadRequest(apiError('missingCustomerId'));
|
||||||
|
|
||||||
await paypalPayments.checkoutSuccess({user, gift, paymentId, customerId});
|
await paypalPayments.checkoutSuccess({user, gift, paymentId, customerId});
|
||||||
|
|
||||||
@@ -78,7 +77,7 @@ api.subscribe = {
|
|||||||
url: '/paypal/subscribe',
|
url: '/paypal/subscribe',
|
||||||
middlewares: [authWithUrl],
|
middlewares: [authWithUrl],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
if (!req.query.sub) throw new BadRequest(i18n.t('missingSubKey'));
|
if (!req.query.sub) throw new BadRequest(apiError('missingSubKey'));
|
||||||
|
|
||||||
let sub = shared.content.subscriptionBlocks[req.query.sub];
|
let sub = shared.content.subscriptionBlocks[req.query.sub];
|
||||||
let coupon = req.query.coupon;
|
let coupon = req.query.coupon;
|
||||||
@@ -109,7 +108,7 @@ api.subscribeSuccess = {
|
|||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
if (!req.session.paypalBlock) throw new BadRequest(i18n.t('missingPaypalBlock'));
|
if (!req.session.paypalBlock) throw new BadRequest(apiError('missingPaypalBlock'));
|
||||||
|
|
||||||
let block = shared.content.subscriptionBlocks[req.session.paypalBlock];
|
let block = shared.content.subscriptionBlocks[req.session.paypalBlock];
|
||||||
let groupId = req.session.groupId;
|
let groupId = req.session.groupId;
|
||||||
|
|||||||
18
website/server/libs/apiError.js
Normal file
18
website/server/libs/apiError.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// apiError(key) will be called by all controllers / api tests
|
||||||
|
// it includes the api- and commonErrors, since common-ops are used in the api too
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
import commonErrors from '../../common/errors/commonErrorMessages';
|
||||||
|
import apiErrors from '../../common/errors/apiErrorMessages';
|
||||||
|
|
||||||
|
export default function (msgKey, vars = {}) {
|
||||||
|
let message = apiErrors[msgKey];
|
||||||
|
if (!message) message = commonErrors[msgKey];
|
||||||
|
if (!message) throw new Error(`Error processing the API message "${msgKey}".`);
|
||||||
|
|
||||||
|
let clonedVars = vars ? _.clone(vars) : {};
|
||||||
|
|
||||||
|
// TODO cache the result of template() ? More memory usage, faster output
|
||||||
|
return _.template(message)(clonedVars);
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
// A map of messages used by the API that don't need to be translated and
|
|
||||||
// so are not placed into /common/locales
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
// When this file grows, it can be split into multiple ones.
|
|
||||||
const messages = {
|
|
||||||
guildsOnlyPaginate: 'Only public guilds support pagination.',
|
|
||||||
guildsPaginateBooleanString: 'req.query.paginate must be a boolean string.',
|
|
||||||
guildsPageInteger: 'req.query.page must be an integer greater than or equal to 0.',
|
|
||||||
groupIdRequired: 'req.params.groupId must contain a groupId.',
|
|
||||||
managerIdRequired: 'req.body.managerId must contain a user ID.',
|
|
||||||
noSudoAccess: 'You don\'t have sudo access',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function (msgKey, vars = {}) {
|
|
||||||
let message = messages[msgKey];
|
|
||||||
if (!message) throw new Error(`Error processing the API message "${msgKey}".`);
|
|
||||||
|
|
||||||
let clonedVars = vars ? _.clone(vars) : {};
|
|
||||||
|
|
||||||
// TODO cache the result of template() ? More memory usage, faster output
|
|
||||||
return _.template(message)(clonedVars);
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,7 @@ import { getGroupUrl, sendTxn } from '../email';
|
|||||||
import slack from '../slack';
|
import slack from '../slack';
|
||||||
import { model as Group } from '../../models/group';
|
import { model as Group } from '../../models/group';
|
||||||
import { model as Chat } from '../../models/chat';
|
import { model as Chat } from '../../models/chat';
|
||||||
|
import apiError from '../apiError';
|
||||||
|
|
||||||
const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS:COMMUNITY_MANAGER_EMAIL');
|
const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS:COMMUNITY_MANAGER_EMAIL');
|
||||||
const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
|
const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
|
||||||
@@ -24,7 +25,7 @@ export default class GroupChatReporter extends ChatReporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async validate () {
|
async validate () {
|
||||||
this.req.checkParams('groupId', this.res.t('groupIdRequired')).notEmpty();
|
this.req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
|
||||||
this.req.checkParams('chatId', this.res.t('chatIdRequired')).notEmpty();
|
this.req.checkParams('chatId', this.res.t('chatIdRequired')).notEmpty();
|
||||||
|
|
||||||
let validationErrors = this.req.validationErrors();
|
let validationErrors = this.req.validationErrors();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
import apiMessages from '../libs/apiMessages';
|
import apiError from '../libs/apiError';
|
||||||
|
|
||||||
export function ensureAdmin (req, res, next) {
|
export function ensureAdmin (req, res, next) {
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
@@ -17,7 +17,7 @@ export function ensureSudo (req, res, next) {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
if (!user.contributor.sudo) {
|
if (!user.contributor.sudo) {
|
||||||
return next(new NotAuthorized(apiMessages('noSudoAccess')));
|
return next(new NotAuthorized(apiError('noSudoAccess')));
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {v4 as uuid} from 'uuid';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { BadRequest } from '../libs/errors';
|
import { BadRequest } from '../libs/errors';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
|
import apiError from '../libs/apiError';
|
||||||
|
|
||||||
const IS_PRODUCTION = nconf.get('IS_PROD');
|
const IS_PRODUCTION = nconf.get('IS_PROD');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
@@ -95,7 +96,7 @@ schema.methods.formatOptions = function formatOptions (res) {
|
|||||||
this.options = _.pick(this.options, 'groupId');
|
this.options = _.pick(this.options, 'groupId');
|
||||||
|
|
||||||
if (!validator.isUUID(String(this.options.groupId))) {
|
if (!validator.isUUID(String(this.options.groupId))) {
|
||||||
throw new BadRequest(res.t('groupIdRequired'));
|
throw new BadRequest(apiError('groupIdRequired'));
|
||||||
}
|
}
|
||||||
} else if (this.type === 'userActivity') {
|
} else if (this.type === 'userActivity') {
|
||||||
_.defaults(this.options, USER_ACTIVITY_DEFAULT_OPTIONS);
|
_.defaults(this.options, USER_ACTIVITY_DEFAULT_OPTIONS);
|
||||||
|
|||||||
Reference in New Issue
Block a user