diff --git a/config/firebase/keys.json b/config/firebase/keys.json new file mode 100644 index 0000000..51d5a14 --- /dev/null +++ b/config/firebase/keys.json @@ -0,0 +1,3 @@ +{ + "SERVER_KEY": "" +} diff --git a/models/user/index.js b/models/user/index.js index 45ef318..96c4674 100755 --- a/models/user/index.js +++ b/models/user/index.js @@ -8,6 +8,30 @@ const User = require('../../services/mongo').registerModel(__dirname, 'User'); export default User; export const createUser = async (params: any = {}) => new User(params).save(); +/** + * Returns an Array of distinct values of the field passed. + * @param {String} field -The field whose distinct values are to be find. + * @param {Object={}} filter -Filter for the query on whose distinct value is to be find. + */ +export const getDistinctUserFields = async ( + field: string, + filter: object = {} +) => { + const { promise, resolve, reject } = $q.defer(); + User.distinct(field, filter, (err, res) => { + if (err) { + return reject(new ServerError(err)); + } else if (!res.length) { + return reject( + new ResourceNotFoundError('No value exists for the field.') + ); + } + + return resolve(res); + }); + + return promise; +}; export const findUserByEmail = (email: string) => { const { promise, resolve, reject } = $q.defer(); diff --git a/models/user/src/user.js b/models/user/src/user.js index b91944b..ceed8e1 100755 --- a/models/user/src/user.js +++ b/models/user/src/user.js @@ -71,6 +71,10 @@ const User = new mongoose.Schema({ vendor: { type: ObjectId, ref: 'Vendor' + }, + deviceId: { + type: ['string'], + default: [] } }); diff --git a/package.json b/package.json index d12c1b8..42da15d 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,12 @@ "cities": "^1.1.2", "crypto-js": "^3.1.9-1", "geocoder": "^0.2.3", - "grunt-cli": "0.1.13", "grunt": "~0.4.5", + "grunt-cli": "0.1.13", "https-proxy-agent": "^2.2.1", "mongoose": "^5.1.0", "node-fetch": "^2.1.2", + "node-gcm": "^1.0.2", "q": "^1.5.1" }, "devDependencies": { diff --git a/routes/user/update.js b/routes/user/update.js index 850f985..3cdb222 100755 --- a/routes/user/update.js +++ b/routes/user/update.js @@ -41,6 +41,12 @@ module.exports = { city: { type: 'string', trim: true + }, + deviceId: { + type: 'string' + }, + newDeviceId: { + type: 'string' } } }, @@ -59,7 +65,25 @@ module.exports = { }, async run(req: $Request, res: $Response) { try { - const user = await findAndUpdateUser({ _id: req.params.id }, req.body); + const query = { + _id: req.params.id + }; + const updateQuery = {}; + if (req.body.deviceId) { + query.deviceId = req.body.deviceId; + delete req.body.deviceId; + const newDeviceId = req.body.newDeviceId; + delete req.body.newDeviceId; + updateQuery.$set = Object.assign( + { + 'deviceId.$': newDeviceId + }, + req.body + ); + } else { + updateQuery.$set = Object.assign(req.body); + } + const user = await findAndUpdateUser(query, updateQuery); res.$end(user); } catch (e) { log.warn('Failed to update user.', e); diff --git a/services/firebase/index.js b/services/firebase/index.js new file mode 100644 index 0000000..525789e --- /dev/null +++ b/services/firebase/index.js @@ -0,0 +1 @@ +module.exports = require('./src/firebase'); diff --git a/services/firebase/src/firebase.js b/services/firebase/src/firebase.js new file mode 100644 index 0000000..0f5ecab --- /dev/null +++ b/services/firebase/src/firebase.js @@ -0,0 +1,49 @@ +import configLoader from 'alfred/services/configLoader'; +import { ServerError } from 'alfred/core/errors'; +import firebase from 'node-gcm'; + +const config = {}; +const initialize = async () => { + await configLoader.init(); + const firebaseConfig = configLoader.get('firebase'); + config.serverKey = firebaseConfig.SERVER_KEY; +}; + +initialize(); +/** + * Sends push notification to the user for the registration IDs passed. + * @param {Object} data = {} -This parameter specifies the custom key-value pairs of the message's payload. + * @param {Object} notification={} -This parameter specifies the predefined, user-visible key-value pairs of the notification payload. + * @param {Array} registrationTokens=[] -A list of registration tokens Must contain at least 1 and at most 1000 registration tokens. + */ +const notify = async ( + data = {}, + notification = {}, + registrationTokens = [] +) => { + // Prepare a message to be sent. + const sender = new firebase.Sender(config.serverKey); + const message = new firebase.Message({ + data, + notification, + priority: 'high' + }); + return new Promise((resolve, reject) => { + sender.send( + message, + { + registrationTokens + }, + 10, // Retrying a specific number of times (10) + (err, response) => { + if (err) { + reject(new ServerError(err)); + } else { + resolve(response); + } + } + ); + }); +}; + +export { notify }; diff --git a/yarn.lock b/yarn.lock index 9636bb4..45e919f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -191,7 +191,7 @@ ajv-keywords@^3.0.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= -ajv@^5.2.3, ajv@^5.3.0: +ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= @@ -569,7 +569,7 @@ aws-sign2@~0.7.0: resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= -aws4@^1.2.1, aws4@^1.8.0: +aws4@^1.2.1, aws4@^1.6.0, aws4@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== @@ -3007,7 +3007,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@3, extend@~3.0.0, extend@~3.0.2: +extend@3, extend@~3.0.0, extend@~3.0.1, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -3313,7 +3313,7 @@ form-data@~0.1.0: combined-stream "~0.0.4" mime "~1.2.11" -form-data@~2.3.2: +form-data@~2.3.1, form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== @@ -3817,6 +3817,14 @@ har-validator@~2.0.6: is-my-json-valid "^2.12.4" pinkie-promise "^2.0.0" +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + har-validator@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" @@ -5310,7 +5318,7 @@ micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== -mime-types@^2.1.11, mime-types@^2.1.12, mime-types@^2.1.3, mime-types@~2.1.18, mime-types@~2.1.19, mime-types@~2.1.6, mime-types@~2.1.7, mime-types@~2.1.9: +mime-types@^2.1.11, mime-types@^2.1.12, mime-types@^2.1.3, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19, mime-types@~2.1.6, mime-types@~2.1.7, mime-types@~2.1.9: version "2.1.21" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== @@ -5651,6 +5659,15 @@ node-forge@^0.6.20: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.6.49.tgz#f1ee95d5d74623938fe19d698aa5a26d54d2f60f" integrity sha1-8e6V1ddGI5OP4Z1piqWibVTS9g8= +node-gcm@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/node-gcm/-/node-gcm-1.0.2.tgz#4e5828b9c92a7635302e0a5ff0952146299f9771" + integrity sha512-NEVb5jB06I/e9ZfJGWhHsRhJQLk1zO5iZjbQJ7su8j9vhHrpxc7KJHyBxWbv28+4uWFZ0AfTVHoMIyRpEVISUQ== + dependencies: + debug "^3.1.0" + lodash "^4.17.10" + request "2.87.0" + node-pre-gyp@0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz#f11c07516dd92f87199dbc7e1838eab7cd56c9e0" @@ -5855,7 +5872,7 @@ oauth-sign@~0.3.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.3.0.tgz#cb540f93bb2b22a7d5941691a288d60e8ea9386e" integrity sha1-y1QPk7srIqfVlBaRoojWDo6pOG4= -oauth-sign@~0.8.1: +oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= @@ -6436,7 +6453,7 @@ qs@4.0.0: resolved "https://registry.yarnpkg.com/qs/-/qs-4.0.0.tgz#c31d9b74ec27df75e543a86c78728ed8d4623607" integrity sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc= -qs@6.5.2, qs@~6.5.2: +qs@6.5.2, qs@~6.5.1, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== @@ -6820,6 +6837,32 @@ request@2.74.x: tough-cookie "~2.3.0" tunnel-agent "~0.4.1" +request@2.87.0: + version "2.87.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" + integrity sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + request@^2.55.0, request@^2.75.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" @@ -6990,7 +7033,7 @@ rxjs@^6.1.0: dependencies: tslib "^1.9.0" -safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -7836,7 +7879,7 @@ tough-cookie@>=0.12.0, tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" -tough-cookie@~2.3.0: +tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== @@ -8159,7 +8202,7 @@ uuid@^2.0.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" integrity sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho= -uuid@^3.3.2: +uuid@^3.1.0, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==