mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
Merge branch 'api-v3' into api-v3-i18n
This commit is contained in:
@@ -2,7 +2,7 @@ import 'coffee-script';
|
|||||||
|
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import autoinc from 'mongoose-id-autoinc';
|
import autoinc from 'mongoose-id-autoinc';
|
||||||
import logging from '../website/src/libs/logging';
|
import logging from '../website/src/libs/api-v2/logging';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import utils from '../website/src/libs/utils';
|
import utils from '../website/src/libs/utils';
|
||||||
import repl from 'repl';
|
import repl from 'repl';
|
||||||
|
|||||||
136
test/api/v3/unit/libs/webhooks.test.js
Normal file
136
test/api/v3/unit/libs/webhooks.test.js
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
import request from 'request';
|
||||||
|
import { sendTaskWebhook } from '../../../../../website/src/libs/api-v3/webhook';
|
||||||
|
|
||||||
|
describe('webhooks', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
sandbox.stub(request, 'post');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
sandbox.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('sendTaskWebhook', () => {
|
||||||
|
let task = {
|
||||||
|
details: { _id: 'task-id' },
|
||||||
|
delta: 1.4,
|
||||||
|
direction: 'up'
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
task: task,
|
||||||
|
user: { _id: 'user-id' }
|
||||||
|
};
|
||||||
|
|
||||||
|
it('does not send if no webhook endpoints exist', () => {
|
||||||
|
let webhooks = { };
|
||||||
|
|
||||||
|
sendTaskWebhook(webhooks, data);
|
||||||
|
|
||||||
|
expect(request.post).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not send if no webhooks are enabled', () => {
|
||||||
|
let webhooks = {
|
||||||
|
'some-id': {
|
||||||
|
sort: 0,
|
||||||
|
id: 'some-id',
|
||||||
|
enabled: false,
|
||||||
|
url: 'http://example.org/endpoint'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sendTaskWebhook(webhooks, data);
|
||||||
|
|
||||||
|
expect(request.post).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not send if webhook url is not valid', () => {
|
||||||
|
let webhooks = {
|
||||||
|
'some-id': {
|
||||||
|
sort: 0,
|
||||||
|
id: 'some-id',
|
||||||
|
enabled: true,
|
||||||
|
url: 'http://malformedurl/endpoint'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sendTaskWebhook(webhooks, data);
|
||||||
|
|
||||||
|
expect(request.post).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends task direction, task, task delta, and abridged user data', () => {
|
||||||
|
let webhooks = {
|
||||||
|
'some-id': {
|
||||||
|
sort: 0,
|
||||||
|
id: 'some-id',
|
||||||
|
enabled: true,
|
||||||
|
url: 'http://example.org/endpoint'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sendTaskWebhook(webhooks, data);
|
||||||
|
|
||||||
|
expect(request.post).to.be.calledOnce;
|
||||||
|
expect(request.post).to.be.calledWith({
|
||||||
|
url: 'http://example.org/endpoint',
|
||||||
|
body: {
|
||||||
|
direction: 'up',
|
||||||
|
task: { _id: 'task-id' },
|
||||||
|
delta: 1.4,
|
||||||
|
user: {
|
||||||
|
_id: 'user-id'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends a post request for each webhook endpoint', () => {
|
||||||
|
let webhooks = {
|
||||||
|
'some-id': {
|
||||||
|
sort: 0,
|
||||||
|
id: 'some-id',
|
||||||
|
enabled: true,
|
||||||
|
url: 'http://example.org/endpoint'
|
||||||
|
},
|
||||||
|
'second-webhook': {
|
||||||
|
sort: 1,
|
||||||
|
id: 'second-webhook',
|
||||||
|
enabled: true,
|
||||||
|
url: 'http://example.com/2/endpoint'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sendTaskWebhook(webhooks, data);
|
||||||
|
|
||||||
|
expect(request.post).to.be.calledTwice;
|
||||||
|
expect(request.post).to.be.calledWith({
|
||||||
|
url: 'http://example.org/endpoint',
|
||||||
|
body: {
|
||||||
|
direction: 'up',
|
||||||
|
task: { _id: 'task-id' },
|
||||||
|
delta: 1.4,
|
||||||
|
user: {
|
||||||
|
_id: 'user-id'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
});
|
||||||
|
expect(request.post).to.be.calledWith({
|
||||||
|
url: 'http://example.com/2/endpoint',
|
||||||
|
body: {
|
||||||
|
direction: 'up',
|
||||||
|
task: { _id: 'task-id' },
|
||||||
|
delta: 1.4,
|
||||||
|
user: {
|
||||||
|
_id: 'user-id'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -30,7 +30,7 @@ describe('analytics', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('init', function() {
|
describe('init', function() {
|
||||||
var analytics = rewire('../../website/src/libs/analytics');
|
var analytics = rewire('../../website/src/libs/api-v2/analytics');
|
||||||
|
|
||||||
it('throws an error if no options are passed in', function() {
|
it('throws an error if no options are passed in', function() {
|
||||||
expect(analytics).to.throw('No options provided');
|
expect(analytics).to.throw('No options provided');
|
||||||
@@ -62,7 +62,7 @@ describe('analytics', function() {
|
|||||||
describe('track', function() {
|
describe('track', function() {
|
||||||
|
|
||||||
var analyticsData, event_type;
|
var analyticsData, event_type;
|
||||||
var analytics = rewire('../../website/src/libs/analytics');
|
var analytics = rewire('../../website/src/libs/api-v2/analytics');
|
||||||
var initializedAnalytics;
|
var initializedAnalytics;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -370,7 +370,7 @@ describe('analytics', function() {
|
|||||||
|
|
||||||
var purchaseData;
|
var purchaseData;
|
||||||
|
|
||||||
var analytics = rewire('../../website/src/libs/analytics');
|
var analytics = rewire('../../website/src/libs/api-v2/analytics');
|
||||||
var initializedAnalytics;
|
var initializedAnalytics;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ var shared = require('../../../../common');
|
|||||||
var User = require('./../../models/user').model;
|
var User = require('./../../models/user').model;
|
||||||
var Group = require('./../../models/group').model;
|
var Group = require('./../../models/group').model;
|
||||||
var Challenge = require('./../../models/challenge').model;
|
var Challenge = require('./../../models/challenge').model;
|
||||||
var logging = require('./../../libs/logging');
|
var logging = require('./../../libs/api-v2/logging');
|
||||||
var csv = require('express-csv');
|
var csv = require('express-csv');
|
||||||
var utils = require('../../libs/utils');
|
var utils = require('../../libs/utils');
|
||||||
var api = module.exports;
|
var api = module.exports;
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ var analytics = utils.analytics;
|
|||||||
var Group = require('./../../models/group').model;
|
var Group = require('./../../models/group').model;
|
||||||
var Challenge = require('./../../models/challenge').model;
|
var Challenge = require('./../../models/challenge').model;
|
||||||
var moment = require('moment');
|
var moment = require('moment');
|
||||||
var logging = require('./../../libs/logging');
|
var logging = require('./../../libs/api-v2/logging');
|
||||||
var acceptablePUTPaths;
|
var acceptablePUTPaths;
|
||||||
var api = module.exports;
|
var api = module.exports;
|
||||||
var firebase = require('../../libs/firebase');
|
var firebase = require('../../libs/firebase');
|
||||||
var webhook = require('../../libs/webhook');
|
var webhook = require('../../libs/api-v2/webhook');
|
||||||
|
|
||||||
// api.purchase // Shared.ops
|
// api.purchase // Shared.ops
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ var _ = require('lodash');
|
|||||||
var url = require('url');
|
var url = require('url');
|
||||||
var User = require('mongoose').model('User');
|
var User = require('mongoose').model('User');
|
||||||
var payments = require('./index');
|
var payments = require('./index');
|
||||||
var logger = require('../../libs/logging');
|
var logger = require('../../libs/api-v2/logging');
|
||||||
var ipn = require('paypal-ipn');
|
var ipn = require('paypal-ipn');
|
||||||
var paypal = require('paypal-rest-sdk');
|
var paypal = require('paypal-rest-sdk');
|
||||||
var shared = require('../../../../common');
|
var shared = require('../../../../common');
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ require('coffee-script');
|
|||||||
// Only do the minimal amount of work before forking just in case of a dyno restart
|
// Only do the minimal amount of work before forking just in case of a dyno restart
|
||||||
var cluster = require('cluster');
|
var cluster = require('cluster');
|
||||||
var nconf = require('nconf');
|
var nconf = require('nconf');
|
||||||
var logging = require('./libs/logging');
|
var logging = require('./libs/api-v2/logging');
|
||||||
|
|
||||||
// Initialize configuration
|
// Initialize configuration
|
||||||
var setupNconf = require('./libs/api-v3/setupNconf');
|
var setupNconf = require('./libs/api-v3/setupNconf');
|
||||||
|
|||||||
30
website/src/libs/api-v3/webhook.js
Normal file
30
website/src/libs/api-v3/webhook.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { each } from 'lodash';
|
||||||
|
import { post } from 'request';
|
||||||
|
import { isURL } from 'validator';
|
||||||
|
|
||||||
|
let _sendWebhook = (url, body) => {
|
||||||
|
post({
|
||||||
|
url,
|
||||||
|
body,
|
||||||
|
json: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let _isInvalidWebhook = (hook) => {
|
||||||
|
return !hook.enabled || !isURL(hook.url);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function sendTaskWebhook (webhooks, data) {
|
||||||
|
each(webhooks, (hook) => {
|
||||||
|
if (_isInvalidWebhook(hook)) return;
|
||||||
|
|
||||||
|
let body = {
|
||||||
|
direction: data.task.direction,
|
||||||
|
task: data.task.details,
|
||||||
|
delta: data.task.delta,
|
||||||
|
user: data.user,
|
||||||
|
};
|
||||||
|
|
||||||
|
_sendWebhook(hook.url, body);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ module.exports.sendEmail = function(mailData) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
smtpTransport.sendMail(mailData, function(error, response){
|
smtpTransport.sendMail(mailData, function(error, response){
|
||||||
var logging = require('./logging');
|
var logging = require('./api-v2/logging');
|
||||||
if(error) logging.error(error);
|
if(error) logging.error(error);
|
||||||
else logging.info("Message sent: " + response.message);
|
else logging.info("Message sent: " + response.message);
|
||||||
smtpTransport.close(); // shut down the connection pool, no more messages
|
smtpTransport.close(); // shut down the connection pool, no more messages
|
||||||
@@ -172,7 +172,7 @@ module.exports.setupConfig = function(){
|
|||||||
//if (nconf.get('IS_PROD'))
|
//if (nconf.get('IS_PROD'))
|
||||||
//require('newrelic');
|
//require('newrelic');
|
||||||
|
|
||||||
var analytics = IS_PROD && require('./analytics');
|
var analytics = IS_PROD && require('./api-v2/analytics');
|
||||||
var analyticsTokens = {
|
var analyticsTokens = {
|
||||||
amplitudeToken: nconf.get('AMPLITUDE_KEY'),
|
amplitudeToken: nconf.get('AMPLITUDE_KEY'),
|
||||||
googleAnalytics: nconf.get('GA_ID')
|
googleAnalytics: nconf.get('GA_ID')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var logging = require('../libs/logging');
|
var logging = require('../libs/api-v2/logging');
|
||||||
|
|
||||||
module.exports = function(err, req, res, next) {
|
module.exports = function(err, req, res, next) {
|
||||||
//res.locals.domain.emit('error', err);
|
//res.locals.domain.emit('error', err);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ var User = require('./user').model;
|
|||||||
var shared = require('../../../common');
|
var shared = require('../../../common');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var logging = require('../libs/logging');
|
var logging = require('../libs/api-v2/logging');
|
||||||
var Challenge = require('./../models/challenge').model;
|
var Challenge = require('./../models/challenge').model;
|
||||||
var firebase = require('../libs/firebase');
|
var firebase = require('../libs/firebase');
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// TODO cleanup all comments when finished API v3
|
// TODO cleanup all comments when finished API v3
|
||||||
|
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import logging from './libs/logging';
|
import logging from './libs/api-v2/logging';
|
||||||
import utils from './libs/utils';
|
import utils from './libs/utils';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
|
|||||||
Reference in New Issue
Block a user