Upgrade server deps (#10017)
* remove unused apn lib and upgrade moment-recur * upgrade validator * upgrade got * request -> got * fix validation * fix tests * upgrade nodemailer * fix unit tests * fix webhook tests, upgrade express-validator (using legacy api) * upgrade js2xmlparser * update misc packages * fix linting * update packages
This commit is contained in:
@@ -247,7 +247,7 @@ api.loginLocal = {
|
||||
let username = req.body.username;
|
||||
let password = req.body.password;
|
||||
|
||||
if (validator.isEmail(username)) {
|
||||
if (validator.isEmail(String(username))) {
|
||||
login = {'auth.local.email': username.toLowerCase()}; // Emails are stored lowercase
|
||||
} else {
|
||||
login = {'auth.local.username': username};
|
||||
@@ -410,7 +410,7 @@ api.pusherAuth = {
|
||||
}
|
||||
|
||||
resourceId = resourceId.join('-'); // the split at the beginning had split resourceId too
|
||||
if (!validator.isUUID(resourceId)) {
|
||||
if (!validator.isUUID(String(resourceId))) {
|
||||
throw new BadRequest('Invalid Pusher resource id, must be a UUID.');
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,12 @@ api.exportUserDataXml = {
|
||||
'Content-Type': 'text/xml',
|
||||
'Content-disposition': 'attachment; filename=habitica-user-data.xml',
|
||||
});
|
||||
res.status(200).send(js2xml('user', userData));
|
||||
res.status(200).send(js2xml.parse('user', userData, {
|
||||
cdataInvalidChars: true,
|
||||
declaration: {
|
||||
include: false,
|
||||
},
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -33,16 +33,16 @@ api.verifyGemPurchase = async function verifyGemPurchase (user, receipt, headers
|
||||
let correctReceipt = false;
|
||||
|
||||
// Purchasing one item at a time (processing of await(s) below is sequential not parallel)
|
||||
for (let index in purchaseDataList) { // eslint-disable-line no-await-in-loop
|
||||
for (let index in purchaseDataList) {
|
||||
let purchaseData = purchaseDataList[index];
|
||||
let token = purchaseData.transactionId;
|
||||
|
||||
let existingReceipt = await IapPurchaseReceipt.findOne({
|
||||
let existingReceipt = await IapPurchaseReceipt.findOne({ // eslint-disable-line no-await-in-loop
|
||||
_id: token,
|
||||
}).exec();
|
||||
|
||||
if (!existingReceipt) {
|
||||
await IapPurchaseReceipt.create({
|
||||
await IapPurchaseReceipt.create({ // eslint-disable-line no-await-in-loop
|
||||
_id: token,
|
||||
consumed: true,
|
||||
userId: user._id,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createTransport } from 'nodemailer';
|
||||
import nodemailer from 'nodemailer';
|
||||
import nconf from 'nconf';
|
||||
import { TAVERN_ID } from '../models/group';
|
||||
import { encrypt } from './encryption';
|
||||
import request from 'request';
|
||||
import got from 'got';
|
||||
import logger from './logger';
|
||||
import common from '../../common';
|
||||
|
||||
@@ -16,7 +16,7 @@ const EMAIL_SERVER = {
|
||||
};
|
||||
const BASE_URL = nconf.get('BASE_URL');
|
||||
|
||||
let smtpTransporter = createTransport({
|
||||
let smtpTransporter = nodemailer.createTransport({
|
||||
service: nconf.get('SMTP_SERVICE'),
|
||||
auth: {
|
||||
user: nconf.get('SMTP_USER'),
|
||||
@@ -150,13 +150,10 @@ export function sendTxn (mailingInfoArray, emailType, variables, personalVariabl
|
||||
}
|
||||
|
||||
if (IS_PROD && mailingInfoArray.length > 0) {
|
||||
request.post({
|
||||
url: `${EMAIL_SERVER.url}/job`,
|
||||
auth: {
|
||||
user: EMAIL_SERVER.auth.user,
|
||||
pass: EMAIL_SERVER.auth.password,
|
||||
},
|
||||
json: {
|
||||
got.post(`${EMAIL_SERVER.url}/job`, {
|
||||
auth: `${EMAIL_SERVER.auth.user}:${EMAIL_SERVER.auth.password}`,
|
||||
json: true,
|
||||
body: {
|
||||
type: 'email',
|
||||
data: {
|
||||
emailType,
|
||||
@@ -170,6 +167,6 @@ export function sendTxn (mailingInfoArray, emailType, variables, personalVariabl
|
||||
backoff: {delay: 10 * 60 * 1000, type: 'fixed'},
|
||||
},
|
||||
},
|
||||
}, (err) => logger.error(err));
|
||||
}).catch((err) => logger.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import nconf from 'nconf';
|
||||
// TODO remove this lib and use directly the apn module
|
||||
// @TODO remove this lib and use directly the apn module
|
||||
import pushNotify from 'push-notify';
|
||||
import apnLib from 'apn';
|
||||
import logger from './logger';
|
||||
import Bluebird from 'bluebird';
|
||||
import {
|
||||
@@ -44,21 +43,9 @@ if (APN_ENABLED) {
|
||||
apn.on('transmissionError', (errorCode, notification, device) => {
|
||||
logger.error('APN transmissionError', errorCode, notification, device);
|
||||
});
|
||||
|
||||
let feedback = new apnLib.Feedback({
|
||||
key,
|
||||
cert,
|
||||
batchFeedback: true,
|
||||
interval: 3600, // Check for feedback once an hour
|
||||
});
|
||||
|
||||
feedback.on('feedback', (devices) => {
|
||||
if (devices && devices.length > 0) {
|
||||
logger.info('Delivery of push notifications failed for some Apple devices.', devices);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function sendNotification (user, details = {}) {
|
||||
if (!user) throw new Error('User is required.');
|
||||
if (user.preferences.pushNotifications.unsubscribeFromAll === true) return;
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { post } from 'request';
|
||||
import got from 'got';
|
||||
import { isURL } from 'validator';
|
||||
import logger from './logger';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const IS_PRODUCTION = nconf.get('IS_PROD');
|
||||
|
||||
function sendWebhook (url, body) {
|
||||
post({
|
||||
url,
|
||||
got.post(url, {
|
||||
body,
|
||||
json: true,
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
logger.error(err);
|
||||
}
|
||||
});
|
||||
}).catch(err => logger.error(err));
|
||||
}
|
||||
|
||||
function isValidWebhook (hook) {
|
||||
return hook.enabled && isURL(hook.url);
|
||||
return hook.enabled && isURL(hook.url, {
|
||||
require_tld: IS_PRODUCTION ? true : false, // eslint-disable-line camelcase
|
||||
});
|
||||
}
|
||||
|
||||
export class WebhookSender {
|
||||
|
||||
@@ -144,7 +144,7 @@ TaskSchema.statics.findByIdOrAlias = async function findByIdOrAlias (identifier,
|
||||
|
||||
let query = _.cloneDeep(additionalQueries);
|
||||
|
||||
if (validator.isUUID(identifier)) {
|
||||
if (validator.isUUID(String(identifier))) {
|
||||
query._id = identifier;
|
||||
} else {
|
||||
query.userId = userId;
|
||||
|
||||
@@ -5,7 +5,9 @@ import shared from '../../common';
|
||||
import {v4 as uuid} from 'uuid';
|
||||
import _ from 'lodash';
|
||||
import { BadRequest } from '../libs/errors';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const IS_PRODUCTION = nconf.get('IS_PROD');
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const TASK_ACTIVITY_DEFAULT_OPTIONS = Object.freeze({
|
||||
@@ -36,7 +38,11 @@ export let schema = new Schema({
|
||||
url: {
|
||||
type: String,
|
||||
required: true,
|
||||
validate: [validator.isURL, shared.i18n.t('invalidUrl')],
|
||||
validate: [(v) => {
|
||||
return validator.isURL(v, {
|
||||
require_tld: IS_PRODUCTION ? true : false, // eslint-disable-line camelcase
|
||||
});
|
||||
}, shared.i18n.t('invalidUrl')],
|
||||
},
|
||||
enabled: { type: Boolean, required: true, default: true },
|
||||
options: {
|
||||
@@ -72,7 +78,7 @@ schema.methods.formatOptions = function formatOptions (res) {
|
||||
} else if (this.type === 'groupChatReceived') {
|
||||
this.options = _.pick(this.options, 'groupId');
|
||||
|
||||
if (!validator.isUUID(this.options.groupId)) {
|
||||
if (!validator.isUUID(String(this.options.groupId))) {
|
||||
throw new BadRequest(res.t('groupIdRequired'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user