Files
habitica/website/server/controllers/api-v3/pushNotifications.js
Phillip Thelen f8d315ff6e Upgrade to mongoose 7 (#14971)
* remove some unused dependencies

* update mongoose version

* make common tests pass

* Make unit tests pass

* make api v3 integration tests pass

* fix lint issues

* fix issue with package-lock

* fix(lint): we don't need no .js

* fix(lint): update to latest config-habitrpg

* chore(npm): update package locks

* fix(test): replace deprecated fn

* chore(package): update eslint-habitrpg again

* fix(lint): server linting

* fix(lint): client linting

* fix(client): correct mangled common imports

* chore(npm): update package-locks

* fix(lint): punctuation, module

---------

Co-authored-by: SabreCat <sabrecat@gmail.com>
Co-authored-by: SabreCat <sabe@habitica.com>
2024-01-16 15:18:47 -06:00

105 lines
2.8 KiB
JavaScript

import { authWithHeaders } from '../../middlewares/auth';
import {
NotFound,
} from '../../libs/errors';
import { model as PushDevice } from '../../models/pushDevice';
const api = {};
/**
* @apiIgnore
* @api {post} /api/v3/user/push-devices Add a push device to a user
* @apiName UserAddPushDevice
* @apiGroup User
*
* @apiParam (Body) {String} regId The id of the push device
* @apiParam (Body) {String} type The type of push device
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {String} message Success message
*/
api.addPushDevice = {
method: 'POST',
url: '/user/push-devices',
middlewares: [authWithHeaders()],
async handler (req, res) {
const { user } = res.locals;
req.checkBody('regId', res.t('regIdRequired')).notEmpty();
req.checkBody('type', res.t('typeRequired')).notEmpty().isIn(['ios', 'android']);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const { pushDevices } = user;
const item = {
regId: req.body.regId,
type: req.body.type,
};
// When adding a duplicate push device, fail silently instead of throwing an error
if (pushDevices.find(device => device.regId === item.regId)) {
res.respond(200, user.pushDevices, res.t('pushDeviceAdded'));
return;
}
// Concurrency safe update
const pushDevice = (new PushDevice(item)).toJSON(); // Create a mongo doc
await user.updateOne({
$push: { pushDevices: pushDevice },
}).exec();
// Update the response
user.pushDevices.push(pushDevice);
res.respond(200, user.pushDevices, res.t('pushDeviceAdded'));
},
};
/**
* @apiIgnore
* @api {delete} /api/v3/user/push-devices/:regId remove a push device from a user
* @apiName UserRemovePushDevice
* @apiGroup User
*
* @apiParam (Path) {String} regId The id of the push device
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {String} message Success message
*/
api.removePushDevice = {
method: 'DELETE',
url: '/user/push-devices/:regId',
middlewares: [authWithHeaders()],
async handler (req, res) {
const { user } = res.locals;
req.checkParams('regId', res.t('regIdRequired')).notEmpty();
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const { regId } = req.params;
const { pushDevices } = user;
const indexOfPushDevice = pushDevices.findIndex(element => element.regId === regId);
if (indexOfPushDevice === -1) {
throw new NotFound(res.t('pushDeviceNotFound'));
}
// Concurrency safe update
const pullQuery = { $pull: { pushDevices: { regId } } };
await user.updateOne(pullQuery).exec();
// Update the response
pushDevices.splice(indexOfPushDevice, 1);
res.respond(200, user.pushDevices, res.t('pushDeviceRemoved'));
},
};
export default api;