mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 07:37:25 +01:00
APIv2: add paths /api/v2/* and /api/v1/*. v1 has limited deprecated routes (only the things I know currently work), and we'll notify 3rd-partyists to migrate to apiv2 once it's documented and tested
This commit is contained in:
4
API.md
Normal file
4
API.md
Normal file
@@ -0,0 +1,4 @@
|
||||
## APIv2
|
||||
|
||||
## APIv1 (Deprecated)
|
||||
Make sure to send `PUT /api/v1/user` request bodies as `{'set.this.path':value}` instead of `{set:{this:{path:value}}}`
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
habitrpg.controller("AdminCtrl", ['$scope', '$rootScope', 'User', 'Notification', 'API_URL', '$resource',
|
||||
function($scope, $rootScope, User, Notification, API_URL, $resource) {
|
||||
var Contributor = $resource(API_URL + '/api/v1/admin/members/:uid', {uid:'@_id'});
|
||||
var Contributor = $resource(API_URL + '/api/v2/admin/members/:uid', {uid:'@_id'});
|
||||
|
||||
$scope.profile = undefined;
|
||||
$scope.loadUser = function(uuid){
|
||||
|
||||
@@ -37,7 +37,7 @@ habitrpg.controller("AuthCtrl", ['$scope', '$rootScope', 'User', '$http', '$loca
|
||||
if ($scope.registrationForm.$invalid) {
|
||||
return;
|
||||
}
|
||||
$http.post(API_URL + "/api/v1/register", $scope.registerVals).success(function(data, status, headers, config) {
|
||||
$http.post(API_URL + "/api/v2/register", $scope.registerVals).success(function(data, status, headers, config) {
|
||||
runAuth(data.id, data.apiToken);
|
||||
}).error(function(data, status, headers, config) {
|
||||
if (status === 0) {
|
||||
@@ -68,7 +68,7 @@ habitrpg.controller("AuthCtrl", ['$scope', '$rootScope', 'User', '$http', '$loca
|
||||
if ($scope.useUUID) {
|
||||
runAuth($scope.loginUsername, $scope.loginPassword);
|
||||
} else {
|
||||
$http.post(API_URL + "/api/v1/user/auth/local", data)
|
||||
$http.post(API_URL + "/api/v2/user/auth/local", data)
|
||||
.success(function(data, status, headers, config) {
|
||||
runAuth(data.id, data.token);
|
||||
}).error(errorAlert);
|
||||
@@ -84,7 +84,7 @@ habitrpg.controller("AuthCtrl", ['$scope', '$rootScope', 'User', '$http', '$loca
|
||||
}
|
||||
|
||||
$scope.passwordReset = function(email){
|
||||
$http.post(API_URL + '/api/v1/user/reset-password', {email:email})
|
||||
$http.post(API_URL + '/api/v2/user/reset-password', {email:email})
|
||||
.success(function(){
|
||||
alert('New password sent.');
|
||||
})
|
||||
|
||||
@@ -51,7 +51,7 @@ habitrpg.controller("FooterCtrl", ['$scope', '$rootScope', 'User', '$http', 'Not
|
||||
Notification.text('-1 day, remember to refresh');
|
||||
}
|
||||
$scope.addTenGems = function(){
|
||||
$http.post(API_URL + '/api/v1/user/addTenGems').success(function(){
|
||||
$http.post(API_URL + '/api/v2/user/addTenGems').success(function(){
|
||||
User.log({});
|
||||
})
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
|
||||
panelLabel: "Checkout",
|
||||
token: function(data) {
|
||||
$scope.$apply(function(){
|
||||
$http.post("/api/v1/user/buy-gems", data)
|
||||
$http.post("/api/v2/user/buy-gems", data)
|
||||
.success(function() {
|
||||
window.location.href = "/";
|
||||
}).error(function(err) {
|
||||
@@ -158,7 +158,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
|
||||
$scope.castEnd = function(target, type, $event){
|
||||
if ($scope.spell.target != type) return Notification.text("Invalid target");
|
||||
$scope.spell.cast(User.user, target);
|
||||
$http.post('/api/v1/user/cast/' + $scope.spell.name, {target:target, type:type}).success(function(){
|
||||
$http.post('/api/v2/user/cast/' + $scope.spell.name, {target:target, type:type}).success(function(){
|
||||
var msg = "You cast " + $scope.spell.text;
|
||||
switch (type) {
|
||||
case 'task': msg += ' on ' + target.text;break;
|
||||
|
||||
@@ -54,7 +54,7 @@ habitrpg.controller('SettingsCtrl',
|
||||
if (!changePass.oldPassword || !changePass.newPassword || !changePass.confirmNewPassword) {
|
||||
return alert("Please fill out all fields");
|
||||
}
|
||||
$http.post(API_URL + '/api/v1/user/change-password', changePass)
|
||||
$http.post(API_URL + '/api/v2/user/change-password', changePass)
|
||||
.success(function(){
|
||||
alert("Password successfully changed");
|
||||
$scope.changePass = {};
|
||||
@@ -92,7 +92,7 @@ habitrpg.controller('SettingsCtrl',
|
||||
}
|
||||
|
||||
$scope['delete'] = function(){
|
||||
$http['delete'](API_URL + '/api/v1/user')
|
||||
$http['delete'](API_URL + '/api/v2/user')
|
||||
.success(function(){
|
||||
localStorage.clear();
|
||||
window.location.href = '/logout';
|
||||
|
||||
@@ -64,7 +64,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
|
||||
|
||||
$scope.unlink = function(task, keep) {
|
||||
// TODO move this to userServices, turn userSerivces.user into ng-resource
|
||||
$http.post(API_URL + '/api/v1/user/tasks/' + task.id + '/unlink?keep=' + keep)
|
||||
$http.post(API_URL + '/api/v2/user/tasks/' + task.id + '/unlink?keep=' + keep)
|
||||
.success(function(){
|
||||
User.log({});
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ factory('Facebook',
|
||||
email: response.email
|
||||
}
|
||||
|
||||
$http.post(API_URL + '/api/v1/user/auth/facebook', data).success(function(data, status, headers, config) {
|
||||
$http.post(API_URL + '/api/v2/user/auth/facebook', data).success(function(data, status, headers, config) {
|
||||
User.authenticate(data.id, data.token, function(err) {
|
||||
if (!err) {
|
||||
alert('Login successful!');
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
angular.module('challengeServices', ['ngResource']).
|
||||
factory('Challenges', ['API_URL', '$resource', 'User', '$q', 'Members',
|
||||
function(API_URL, $resource, User, $q, Members) {
|
||||
var Challenge = $resource(API_URL + '/api/v1/challenges/:cid',
|
||||
var Challenge = $resource(API_URL + '/api/v2/challenges/:cid',
|
||||
{cid:'@_id'},
|
||||
{
|
||||
//'query': {method: "GET", isArray:false}
|
||||
join: {method: "POST", url: API_URL + '/api/v1/challenges/:cid/join'},
|
||||
leave: {method: "POST", url: API_URL + '/api/v1/challenges/:cid/leave'},
|
||||
close: {method: "POST", params: {uid:''}, url: API_URL + '/api/v1/challenges/:cid/close'},
|
||||
getMember: {method: "GET", url: API_URL + '/api/v1/challenges/:cid/member/:uid'}
|
||||
join: {method: "POST", url: API_URL + '/api/v2/challenges/:cid/join'},
|
||||
leave: {method: "POST", url: API_URL + '/api/v2/challenges/:cid/leave'},
|
||||
close: {method: "POST", params: {uid:''}, url: API_URL + '/api/v2/challenges/:cid/close'},
|
||||
getMember: {method: "GET", url: API_URL + '/api/v2/challenges/:cid/member/:uid'}
|
||||
});
|
||||
|
||||
//var challenges = [];
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
angular.module('groupServices', ['ngResource']).
|
||||
factory('Groups', ['API_URL', '$resource', '$q',
|
||||
function(API_URL, $resource, $q) {
|
||||
var Group = $resource(API_URL + '/api/v1/groups/:gid',
|
||||
var Group = $resource(API_URL + '/api/v2/groups/:gid',
|
||||
{gid:'@_id', messageId: '@_messageId'},
|
||||
{
|
||||
//query: {method: "GET", isArray:false},
|
||||
postChat: {method: "POST", url: API_URL + '/api/v1/groups/:gid/chat'},
|
||||
deleteChatMessage: {method: "DELETE", url: API_URL + '/api/v1/groups/:gid/chat/:messageId'},
|
||||
join: {method: "POST", url: API_URL + '/api/v1/groups/:gid/join'},
|
||||
leave: {method: "POST", url: API_URL + '/api/v1/groups/:gid/leave'},
|
||||
invite: {method: "POST", url: API_URL + '/api/v1/groups/:gid/invite'},
|
||||
removeMember: {method: "POST", url: API_URL + '/api/v1/groups/:gid/removeMember'}
|
||||
postChat: {method: "POST", url: API_URL + '/api/v2/groups/:gid/chat'},
|
||||
deleteChatMessage: {method: "DELETE", url: API_URL + '/api/v2/groups/:gid/chat/:messageId'},
|
||||
join: {method: "POST", url: API_URL + '/api/v2/groups/:gid/join'},
|
||||
leave: {method: "POST", url: API_URL + '/api/v2/groups/:gid/leave'},
|
||||
invite: {method: "POST", url: API_URL + '/api/v2/groups/:gid/invite'},
|
||||
removeMember: {method: "POST", url: API_URL + '/api/v2/groups/:gid/removeMember'}
|
||||
});
|
||||
|
||||
// Defer loading everything until they're requested
|
||||
|
||||
@@ -8,7 +8,7 @@ angular.module('memberServices', ['ngResource']).
|
||||
factory('Members', ['$rootScope', 'API_URL', '$resource',
|
||||
function($rootScope, API_URL, $resource) {
|
||||
var members = {};
|
||||
var Member = $resource(API_URL + '/api/v1/members/:uid', {uid:'@_id'});
|
||||
var Member = $resource(API_URL + '/api/v2/members/:uid', {uid:'@_id'});
|
||||
var memberServices = {
|
||||
|
||||
Member: Member,
|
||||
|
||||
@@ -56,7 +56,7 @@ angular.module('userServices', []).
|
||||
sent.push(queue.shift());
|
||||
});
|
||||
|
||||
$http.post(API_URL + '/api/v1/user/batch-update', sent, {params: {data:+new Date, _v:user._v, siteVersion: $window.env && $window.env.siteVersion}})
|
||||
$http.post(API_URL + '/api/v2/user/batch-update', sent, {params: {data:+new Date, _v:user._v, siteVersion: $window.env && $window.env.siteVersion}})
|
||||
.success(function (data, status, heacreatingders, config) {
|
||||
//make sure there are no pending actions to sync. If there are any it is not safe to apply model from server as we may overwrite user data.
|
||||
if (!queue.length) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
window.habitrpg = angular.module('habitrpg', ['userServices', 'chieffancypants.loadingBar'])
|
||||
window.habitrpg = angular.module('habitrpg', ['notificationServices', 'userServices', 'chieffancypants.loadingBar'])
|
||||
.constant("API_URL", "")
|
||||
.constant("STORAGE_USER_ID", 'habitrpg-user')
|
||||
.constant("STORAGE_SETTINGS_ID", 'habit-mobile-settings')
|
||||
@@ -72,8 +72,8 @@
|
||||
|
||||
"bower_components/angular-loading-bar/build/loading-bar.js",
|
||||
"js/static.js",
|
||||
"js/services/userServices.js",
|
||||
"js/services/notificationServices.js",
|
||||
"js/services/userServices.js",
|
||||
"js/controllers/authCtrl.js"
|
||||
],
|
||||
"css": [
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
var express = require('express');
|
||||
var router = new express.Router();
|
||||
var _ = require('lodash');
|
||||
var icalendar = require('icalendar');
|
||||
var api = require('./user');
|
||||
var auth = require('./auth');
|
||||
|
||||
/* ---------- Deprecated Paths ------------*/
|
||||
|
||||
|
||||
var deprecatedMessage = 'This API is no longer supported, see https://github.com/lefnire/habitrpg/wiki/API for new protocol';
|
||||
|
||||
router.get('/:uid/up/:score?', function(req, res) {
|
||||
return res.send(500, deprecatedMessage);
|
||||
});
|
||||
|
||||
router.get('/:uid/down/:score?', function(req, res) {
|
||||
return res.send(500, deprecatedMessage);
|
||||
});
|
||||
|
||||
router.post('/users/:uid/tasks/:taskId/:direction', function(req, res) {
|
||||
return res.send(500, deprecatedMessage);
|
||||
});
|
||||
|
||||
/* Redirect to new API*/
|
||||
|
||||
|
||||
var initDeprecated = function(req, res, next) {
|
||||
req.headers['x-api-user'] = req.params.uid;
|
||||
req.headers['x-api-key'] = req.body.apiToken;
|
||||
return next();
|
||||
};
|
||||
|
||||
router.post('/v1/users/:uid/tasks/:taskId/:direction', initDeprecated, auth.auth, api.score);
|
||||
|
||||
router.get('/v1/users/:uid/calendar.ics', function(req, res, next) {
|
||||
return next() //disable for now
|
||||
|
||||
var apiToken, model, query, uid;
|
||||
uid = req.params.uid;
|
||||
apiToken = req.query.apiToken;
|
||||
model = req.getModel();
|
||||
query = model.query('users').withIdAndToken(uid, apiToken);
|
||||
return query.fetch(function(err, result) {
|
||||
var formattedIcal, ical, tasks, tasksWithDates;
|
||||
if (err) {
|
||||
return res.send(500, err);
|
||||
}
|
||||
tasks = result.get('tasks');
|
||||
/* tasks = result[0].tasks*/
|
||||
|
||||
tasksWithDates = _.filter(tasks, function(task) {
|
||||
return !!task.date;
|
||||
});
|
||||
if (_.isEmpty(tasksWithDates)) {
|
||||
return res.send(500, "No events found");
|
||||
}
|
||||
ical = new icalendar.iCalendar();
|
||||
ical.addProperty('NAME', 'HabitRPG');
|
||||
_.each(tasksWithDates, function(task) {
|
||||
var d, event;
|
||||
event = new icalendar.VEvent(task.id);
|
||||
event.setSummary(task.text);
|
||||
d = new Date(task.date);
|
||||
d.date_only = true;
|
||||
event.setDate(d);
|
||||
ical.addComponent(event);
|
||||
return true;
|
||||
});
|
||||
res.type('text/calendar');
|
||||
formattedIcal = ical.toString().replace(/DTSTART\:/g, 'DTSTART;VALUE=DATE:');
|
||||
return res.send(200, formattedIcal);
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -43,19 +43,16 @@ findTask = function(req, res) {
|
||||
Export it also so we can call it from deprecated.coffee
|
||||
*/
|
||||
api.score = function(req, res, next) {
|
||||
var task = findTask(req,res);
|
||||
if (!task) return res.json(404, {err: "No task found."});
|
||||
|
||||
var id = req.params.id,
|
||||
direction = req.params.direction,
|
||||
user = res.locals.user,
|
||||
task;
|
||||
|
||||
// Send error responses for improper API call
|
||||
if (!id) return res.json(500, {err: ':id required'});
|
||||
if (!id) return res.json(400, {err: ':id required'});
|
||||
if (direction !== 'up' && direction !== 'down') {
|
||||
if (direction == 'unlink') return next();
|
||||
return res.json(500, {err: ":direction must be 'up' or 'down'"});
|
||||
return res.json(400, {err: ":direction must be 'up' or 'down'"});
|
||||
}
|
||||
// If exists already, score it
|
||||
if (task = user.tasks[id]) {
|
||||
@@ -181,7 +178,7 @@ api.update = function(req, res, next) {
|
||||
if (acceptablePUTPaths[k])
|
||||
user.fns.dotSet(k, v);
|
||||
else
|
||||
errors.push("path `" + k + "` was not saved, as it's a protected path. Make sure to send `PUT /api/v1/user` request bodies as `{'set.this.path':value}` instead of `{set:{this:{path:value}}}`");
|
||||
errors.push("path `" + k + "` was not saved, as it's a protected path. See https://github.com/HabitRPG/habitrpg/blob/develop/API.md for PUT /api/v2/user.");
|
||||
return true;
|
||||
});
|
||||
user.save(function(err) {
|
||||
|
||||
171
src/routes/apiv1.js
Normal file
171
src/routes/apiv1.js
Normal file
@@ -0,0 +1,171 @@
|
||||
var express = require('express');
|
||||
var router = new express.Router();
|
||||
var _ = require('lodash');
|
||||
var async = require('async');
|
||||
var icalendar = require('icalendar');
|
||||
var api = require('./../controllers/user');
|
||||
var auth = require('./../controllers/auth');
|
||||
var middleware = require('../middleware');
|
||||
|
||||
/* ---------- Deprecated API ------------*/
|
||||
|
||||
var initDeprecated = function(req, res, next) {
|
||||
req.headers['x-api-user'] = req.params.uid;
|
||||
req.headers['x-api-key'] = req.body.apiToken;
|
||||
return next();
|
||||
};
|
||||
|
||||
router.post('/v1/users/:uid/tasks/:taskId/:direction', initDeprecated, auth.auth, api.score);
|
||||
|
||||
// FIXME add this back in
|
||||
router.get('/v1/users/:uid/calendar.ics', function(req, res, next) {
|
||||
return next() //disable for now
|
||||
|
||||
var apiToken, model, query, uid;
|
||||
uid = req.params.uid;
|
||||
apiToken = req.query.apiToken;
|
||||
model = req.getModel();
|
||||
query = model.query('users').withIdAndToken(uid, apiToken);
|
||||
return query.fetch(function(err, result) {
|
||||
var formattedIcal, ical, tasks, tasksWithDates;
|
||||
if (err) {
|
||||
return res.send(500, err);
|
||||
}
|
||||
tasks = result.get('tasks');
|
||||
/* tasks = result[0].tasks*/
|
||||
|
||||
tasksWithDates = _.filter(tasks, function(task) {
|
||||
return !!task.date;
|
||||
});
|
||||
if (_.isEmpty(tasksWithDates)) {
|
||||
return res.send(500, "No events found");
|
||||
}
|
||||
ical = new icalendar.iCalendar();
|
||||
ical.addProperty('NAME', 'HabitRPG');
|
||||
_.each(tasksWithDates, function(task) {
|
||||
var d, event;
|
||||
event = new icalendar.VEvent(task.id);
|
||||
event.setSummary(task.text);
|
||||
d = new Date(task.date);
|
||||
d.date_only = true;
|
||||
event.setDate(d);
|
||||
ical.addComponent(event);
|
||||
return true;
|
||||
});
|
||||
res.type('text/calendar');
|
||||
formattedIcal = ical.toString().replace(/DTSTART\:/g, 'DTSTART;VALUE=DATE:');
|
||||
return res.send(200, formattedIcal);
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------
|
||||
Batch Update
|
||||
This is super-deprecated, and will be removed once apiv2 is running against mobile for a while
|
||||
------------------------------------------------------------------------
|
||||
*/
|
||||
var batchUpdate = function(req, res, next) {
|
||||
var user = res.locals.user;
|
||||
var oldSend = res.send;
|
||||
var oldJson = res.json;
|
||||
var performAction = function(action, cb) {
|
||||
|
||||
// req.body=action.data; delete action.data; _.defaults(req.params, action)
|
||||
// Would require changing action.dir on mobile app
|
||||
req.params.id = action.data && action.data.id;
|
||||
req.params.direction = action.dir;
|
||||
req.params.type = action.type;
|
||||
req.body = action.data;
|
||||
res.send = res.json = function(code, data) {
|
||||
if (_.isNumber(code) && code >= 400) {
|
||||
console.error({
|
||||
code: code,
|
||||
data: data
|
||||
});
|
||||
}
|
||||
//FIXME send error messages down
|
||||
return cb();
|
||||
};
|
||||
switch (action.op) {
|
||||
case "score":
|
||||
api.score(req, res);
|
||||
break;
|
||||
case "addTask":
|
||||
api.addTask(req, res);
|
||||
break;
|
||||
case "delTask":
|
||||
api.deleteTask(req, res);
|
||||
break;
|
||||
case "revive":
|
||||
api.revive(req, res);
|
||||
break;
|
||||
default:
|
||||
cb();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Setup the array of functions we're going to call in parallel with async
|
||||
var actions = _.transform(req.body || [], function(result, action) {
|
||||
if (!_.isEmpty(action)) {
|
||||
result.push(function(cb) {
|
||||
performAction(action, cb);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// call all the operations, then return the user object to the requester
|
||||
async.series(actions, function(err) {
|
||||
res.json = oldJson;
|
||||
res.send = oldSend;
|
||||
if (err) return res.json(500, {err: err});
|
||||
var response = user.toJSON();
|
||||
response.wasModified = res.locals.wasModified;
|
||||
if (response._tmp && response._tmp.drop){
|
||||
res.json(200, {_tmp: {drop: response._tmp.drop}, _v: response._v});
|
||||
}else if(response.wasModified){
|
||||
res.json(200, response);
|
||||
}else{
|
||||
res.json(200, {_v: response._v});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------
|
||||
API v1 Routes
|
||||
------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
var cron = api.cron;
|
||||
|
||||
router.get('/status', function(req, res) {
|
||||
return res.json({
|
||||
status: 'up'
|
||||
});
|
||||
});
|
||||
|
||||
// Scoring
|
||||
router.post('/user/task/:id/:direction', auth.auth, cron, api.score);
|
||||
router.post('/user/tasks/:id/:direction', auth.auth, cron, api.score);
|
||||
|
||||
// Tasks
|
||||
router.get('/user/tasks', auth.auth, cron, api.getTasks);
|
||||
router.get('/user/task/:id', auth.auth, cron, api.getTask);
|
||||
router["delete"]('/user/task/:id', auth.auth, cron, api.deleteTask);
|
||||
router.post('/user/task', auth.auth, cron, api.addTask);
|
||||
|
||||
// User
|
||||
router.get('/user', auth.auth, cron, api.getUser);
|
||||
router.post('/user/revive', auth.auth, cron, api.revive);
|
||||
router.post('/user/batch-update', middleware.forceRefresh, auth.auth, cron, batchUpdate);
|
||||
|
||||
function deprecated(req, res) {
|
||||
res.json(404, {err:'API v1 is no longer supported, please use API v2 instead (https://github.com/HabitRPG/habitrpg/blob/develop/API.md)'});
|
||||
}
|
||||
router.get('*', deprecated);
|
||||
router.post('*', deprecated);
|
||||
router.put('*', deprecated);
|
||||
|
||||
module.exports = router;
|
||||
@@ -4,10 +4,10 @@ var router = new express.Router();
|
||||
|
||||
/* auth.auth*/
|
||||
auth.setupPassport(router); //FIXME make this consistent with the others
|
||||
router.post('/api/v1/register', auth.registerUser);
|
||||
router.post('/api/v1/user/auth/local', auth.loginLocal);
|
||||
router.post('/api/v1/user/auth/facebook', auth.loginFacebook);
|
||||
router.post('/api/v1/user/reset-password', auth.resetPassword);
|
||||
router.post('/api/v1/user/change-password', auth.auth, auth.changePassword);
|
||||
router.post('/api/v2/register', auth.registerUser);
|
||||
router.post('/api/v2/user/auth/local', auth.loginLocal);
|
||||
router.post('/api/v2/user/auth/facebook', auth.loginFacebook);
|
||||
router.post('/api/v2/user/reset-password', auth.resetPassword);
|
||||
router.post('/api/v2/user/change-password', auth.auth, auth.changePassword);
|
||||
|
||||
module.exports = router;
|
||||
@@ -113,9 +113,9 @@ if ("development" === app.get("env")) {
|
||||
// Custom Directives
|
||||
app.use(require('./routes/pages').middleware);
|
||||
app.use(require('./routes/auth').middleware);
|
||||
app.use('/api/v1', require('./routes/api').middleware);
|
||||
app.use('/api/v2', require('./routes/apiv2').middleware);
|
||||
app.use('/api/v1', require('./routes/apiv1').middleware);
|
||||
app.use('/export', require('./routes/dataexport').middleware);
|
||||
app.use(require('./controllers/deprecated').middleware);
|
||||
server = http.createServer(app).listen(app.get("port"), function() {
|
||||
return console.log("Express server listening on port " + app.get("port"));
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ div(modal='modals.buyGems')
|
||||
.btn.btn-primary(ng-click='showStripe()') Pay with Card
|
||||
.span6.well
|
||||
h3 Pay with PayPal
|
||||
script(src='/bower_components/JavaScriptButtons/dist/paypal-button.min.js?merchant=#{env.PAYPAL_MERCHANT}', data-button='buynow', data-name='20 Gems, Disable Ads, Donation to the Developers', data-quantity='1', data-amount='5', data-currency='USD', data-tax='0', data-callback='#{env.BASE_URL}/api/v1/user/buy-gems/paypal-ipn', data-env="#{env.NODE_ENV == 'production' ? '' : 'sandbox'}", data-custom='?uid={{user._id}}&apiToken={{user.apiToken}}', data-return='#{env.BASE_URL}', data-rm='1', data-no_shipping='1')
|
||||
script(src='/bower_components/JavaScriptButtons/dist/paypal-button.min.js?merchant=#{env.PAYPAL_MERCHANT}', data-button='buynow', data-name='20 Gems, Disable Ads, Donation to the Developers', data-quantity='1', data-amount='5', data-currency='USD', data-tax='0', data-callback='#{env.BASE_URL}/api/v2/user/buy-gems/paypal-ipn', data-env="#{env.NODE_ENV == 'production' ? '' : 'sandbox'}", data-custom='?uid={{user._id}}&apiToken={{user.apiToken}}', data-return='#{env.BASE_URL}', data-rm='1', data-no_shipping='1')
|
||||
|
||||
.modal-footer
|
||||
button.btn.btn-default.cancel(ng-click='modals.buyGems = false') Cancel
|
||||
Reference in New Issue
Block a user