Blame view
node_modules/loopback/common/models/application.js
6.86 KB
f7563de62
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Node module: loopback // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT var assert = require('assert'); var utils = require('../../lib/utils'); /*! * Application management functions */ var crypto = require('crypto'); function generateKey(hmacKey, algorithm, encoding) { hmacKey = hmacKey || 'loopback'; algorithm = algorithm || 'sha1'; encoding = encoding || 'hex'; var hmac = crypto.createHmac(algorithm, hmacKey); var buf = crypto.randomBytes(32); hmac.update(buf); var key = hmac.digest(encoding); return key; } /** * Manage client applications and organize their users. * * @property {String} id Generated ID. * @property {String} name Name; required. * @property {String} description Text description * @property {String} icon String Icon image URL. * @property {String} owner User ID of the developer who registers the application. * @property {String} email E-mail address * @property {Boolean} emailVerified Whether the e-mail is verified. * @property {String} url OAuth 2.0 application URL. * @property {String}[] callbackUrls The OAuth 2.0 code/token callback URL. * @property {String} status Status of the application; Either `production`, `sandbox` (default), or `disabled`. * @property {Date} created Date Application object was created. Default: current date. * @property {Date} modified Date Application object was modified. Default: current date. * * @property {Object} pushSettings.apns APNS configuration, see the options * below and also * https://github.com/argon/node-apn/blob/master/doc/apn.markdown * @property {Boolean} pushSettings.apns.production Whether to use production Apple Push Notification Service (APNS) servers to send push notifications. * If true, uses `gateway.push.apple.com:2195` and `feedback.push.apple.com:2196`. * If false, uses `gateway.sandbox.push.apple.com:2195` and `feedback.sandbox.push.apple.com:2196` * @property {String} pushSettings.apns.certData The certificate data loaded from the cert.pem file (APNS). * @property {String} pushSettings.apns.keyData The key data loaded from the key.pem file (APNS). * @property {String} pushSettings.apns.pushOptions.gateway (APNS). * @property {Number} pushSettings.apns.pushOptions.port (APNS). * @property {String} pushSettings.apns.feedbackOptions.gateway (APNS). * @property {Number} pushSettings.apns.feedbackOptions.port (APNS). * @property {Boolean} pushSettings.apns.feedbackOptions.batchFeedback (APNS). * @property {Number} pushSettings.apns.feedbackOptions.interval (APNS). * @property {String} pushSettings.gcm.serverApiKey: Google Cloud Messaging API key. * * @property {Boolean} authenticationEnabled * @property {Boolean} anonymousAllowed * @property {Array} authenticationSchemes List of authentication schemes * (see below). * @property {String} authenticationSchemes.scheme Scheme name. * Supported values: `local`, `facebook`, `google`, * `twitter`, `linkedin`, `github`. * @property {Object} authenticationSchemes.credential * Scheme-specific credentials. * * @class Application * @inherits {PersistedModel} */ module.exports = function(Application) { // Workaround for https://github.com/strongloop/loopback/issues/292 Application.definition.rawProperties.created.default = Application.definition.properties.created.default = function() { return new Date(); }; // Workaround for https://github.com/strongloop/loopback/issues/292 Application.definition.rawProperties.modified.default = Application.definition.properties.modified.default = function() { return new Date(); }; /*! * A hook to generate keys before creation * @param next */ Application.observe('before save', function(ctx, next) { if (!ctx.instance) { // Partial update - don't generate new keys // NOTE(bajtos) This also means that an atomic updateOrCreate // will not generate keys when a new record is creatd return next(); } var app = ctx.instance; app.created = app.modified = new Date(); if (!app.id) { app.id = generateKey('id', 'md5'); } app.clientKey = generateKey('client'); app.javaScriptKey = generateKey('javaScript'); app.restApiKey = generateKey('restApi'); app.windowsKey = generateKey('windows'); app.masterKey = generateKey('master'); next(); }); /** * Register a new application * @param {String} owner Owner's user ID. * @param {String} name Name of the application * @param {Object} options Other options * @param {Function} callback Callback function */ Application.register = function(owner, name, options, cb) { assert(owner, 'owner is required'); assert(name, 'name is required'); if (typeof options === 'function' && !cb) { cb = options; options = {}; } cb = cb || utils.createPromiseCallback(); var props = {owner: owner, name: name}; for (var p in options) { if (!(p in props)) { props[p] = options[p]; } } this.create(props, cb); return cb.promise; }; /** * Reset keys for the application instance * @callback {Function} callback * @param {Error} err */ Application.prototype.resetKeys = function(cb) { this.clientKey = generateKey('client'); this.javaScriptKey = generateKey('javaScript'); this.restApiKey = generateKey('restApi'); this.windowsKey = generateKey('windows'); this.masterKey = generateKey('master'); this.modified = new Date(); this.save(cb); }; /** * Reset keys for a given application by the appId * @param {Any} appId * @callback {Function} callback * @param {Error} err */ Application.resetKeys = function(appId, cb) { cb = cb || utils.createPromiseCallback(); this.findById(appId, function(err, app) { if (err) { if (cb) cb(err, app); return; } app.resetKeys(cb); }); return cb.promise; }; /** * Authenticate the application id and key. * * @param {Any} appId * @param {String} key * @callback {Function} callback * @param {Error} err * @param {String} matched The matching key; one of: * - clientKey * - javaScriptKey * - restApiKey * - windowsKey * - masterKey * */ Application.authenticate = function(appId, key, cb) { cb = cb || utils.createPromiseCallback(); this.findById(appId, function(err, app) { if (err || !app) { cb(err, null); return cb.promise; } var result = null; var keyNames = ['clientKey', 'javaScriptKey', 'restApiKey', 'windowsKey', 'masterKey']; for (var i = 0; i < keyNames.length; i++) { if (app[keyNames[i]] === key) { result = { application: app, keyType: keyNames[i] }; break; } } cb(null, result); }); return cb.promise; }; }; |