From ab8e981d60ee769ec42ed48e9ffbbe438ae7e3c7 Mon Sep 17 00:00:00 2001 From: Vincent Lefebvre Date: Wed, 10 Dec 2014 15:58:21 +0100 Subject: [PATCH 1/7] Update handling of special parameters mobile in providers conf to handle a field mobile.url which will replace the first part of the actual url if the opts mobile is set on true in popup firing method. --- providers/tripit/conf.json | 3 +++ src/presentationLayer/auth/index.coffee | 24 +++++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/providers/tripit/conf.json b/providers/tripit/conf.json index 350efc39e..5d43e2786 100644 --- a/providers/tripit/conf.json +++ b/providers/tripit/conf.json @@ -2,6 +2,9 @@ "name": "Tripit", "desc": "The TripIt API allows users to access the TripIt's information about travel and itineraries. TripIt facilitates integration and organization of travel information from many different sources. The TripIt API allows third parties to easily interface with this platform.", "url": "https://api.tripit.com", + "mobile": { + "url": "https://m.tripit.com" + }, "oauth1": { "request_token": "/oauth/request_token", "authorize": { diff --git a/src/presentationLayer/auth/index.coffee b/src/presentationLayer/auth/index.coffee index 0eaad65eb..eb072966b 100644 --- a/src/presentationLayer/auth/index.coffee +++ b/src/presentationLayer/auth/index.coffee @@ -266,15 +266,21 @@ module.exports = (env) -> ], (err, url) -> return callback err if err - #Fitbit needs this for mobile - if provider_conf.mobile?.params? and req.params.mobile == 'true' - for k,v of provider_conf.mobile.params - if url.indexOf('?') == -1 - url += '?' - else - url += '&' - url += k + '=' + v - + #Fitbit and tripit needs this for mobile + if provider_conf.mobile? + if provider_conf.mobile?.params? and req.params.mobile == 'true' + for k,v of provider_conf.mobile.params + if url.indexOf('?') == -1 + url += '?' + else + url += '&' + url += k + '=' + v + opts = JSON.parse(req.params.opts) + if opts.mobile is 'true' and provider_conf.mobile?.url? + url_split = url.split("/oauth/") + if url_split.length is 2 + url = provider_conf.mobile.url + '/oauth/' + url_split[1] + res.setHeader 'Location', url res.send 302 next() From 7696c34426bc4f418545202da008de969bf2f6c5 Mon Sep 17 00:00:00 2001 From: Vincent Lefebvre Date: Wed, 10 Dec 2014 16:31:09 +0100 Subject: [PATCH 2/7] specify url replacement for mobile only on oauth/authorize urls to match tripit provider requirement. --- src/presentationLayer/auth/index.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/presentationLayer/auth/index.coffee b/src/presentationLayer/auth/index.coffee index eb072966b..0d1e1a99a 100644 --- a/src/presentationLayer/auth/index.coffee +++ b/src/presentationLayer/auth/index.coffee @@ -277,7 +277,7 @@ module.exports = (env) -> url += k + '=' + v opts = JSON.parse(req.params.opts) if opts.mobile is 'true' and provider_conf.mobile?.url? - url_split = url.split("/oauth/") + url_split = url.split("/oauth/authorize") if url_split.length is 2 url = provider_conf.mobile.url + '/oauth/' + url_split[1] From 0e1d3fc67e05f7ad70cad59d8a2e07348381ddfe Mon Sep 17 00:00:00 2001 From: Vincent Lefebvre Date: Wed, 10 Dec 2014 16:33:08 +0100 Subject: [PATCH 3/7] fix on mobile url build. --- src/presentationLayer/auth/index.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/presentationLayer/auth/index.coffee b/src/presentationLayer/auth/index.coffee index 0d1e1a99a..1a3864865 100644 --- a/src/presentationLayer/auth/index.coffee +++ b/src/presentationLayer/auth/index.coffee @@ -279,7 +279,7 @@ module.exports = (env) -> if opts.mobile is 'true' and provider_conf.mobile?.url? url_split = url.split("/oauth/authorize") if url_split.length is 2 - url = provider_conf.mobile.url + '/oauth/' + url_split[1] + url = provider_conf.mobile.url + '/oauth/authorize/' + url_split[1] res.setHeader 'Location', url res.send 302 From 407a0d3f3eb6dca9bb325bd71a9c23e8542fdb9f Mon Sep 17 00:00:00 2001 From: Antoine Jackson Date: Fri, 12 Dec 2014 14:43:38 +0100 Subject: [PATCH 4/7] Added index management in base entity --- src/data/base-entity.coffee | 147 ++++++++++++++++++++++++++---------- 1 file changed, 108 insertions(+), 39 deletions(-) diff --git a/src/data/base-entity.coffee b/src/data/base-entity.coffee index deef4cebd..134958a70 100644 --- a/src/data/base-entity.coffee +++ b/src/data/base-entity.coffee @@ -7,6 +7,7 @@ module.exports = (env) -> class Entity @prefix: '' @incr: '' + @indexes: [] @findById: (id) -> defer = Q.defer() lapin = new @(id) @@ -16,6 +17,18 @@ module.exports = (env) -> .fail (e) -> defer.reject e defer.promise + @findByIndex: (field, index) -> + defer = Q.defer() + # looking for id + env.data.redis.hget @indexes[field], index, (err, id) => + return defer.reject err if err + entity = new @(id) + entity.load() + .then () -> + defer.resolve entity + .fail (e) -> + defer.reject e + defer.promise @onCreate: (entity) -> # creation additional operations @onUpdate: (entity) -> @@ -37,11 +50,12 @@ module.exports = (env) -> # asunc removal additional operations done() id: 0 # represents the entity in db + oldIndexesValues: {} props: {} # the entity's properties prefix: () -> # the prefix of the entity, e.g. user:23: @constructor.prefix + ':' + @id + ':' constructor: (id) -> - @id = id + @id = id keys: () -> defer = Q.defer() keys = {} @@ -100,18 +114,29 @@ module.exports = (env) -> defer = Q.defer() @getAll() .then (data) => - @props = data - defer.resolve(data) + if Object.keys(data).length > 0 + @props = data + defer.resolve(data) + else + defer.reject new Error('Data not found') .fail (e) -> defer.reject(e) defer.promise - save: (overwrite, delete_unknown_keys) -> - overwrite ?= true - delete_unknown_keys ?= false + # accepted values for opts: + # - overwrite: boolean - overwrite values, default true + # - del_unset - delete not set values, default false + # - ttl: time to live for entry, in seconds (from creation or update time) + save: (opts) -> + opts = opts || {} + overwrite = opts.overwrite + overwrite ?= true + + delete_unknown_keys = opts.del_unset + delete_unknown_keys ?= false defer = Q.defer() - + # hat function that actually saves _save = (done) => multi = env.data.redis.multi() @@ -125,25 +150,52 @@ module.exports = (env) -> for key in keys if key not in prefixedProps multi.del key - for key, value of @props - if typeof value == 'string' or typeof value == 'number' - multi.set @prefix() + key, value - else if typeof value == 'object' and Array.isArray(value) - multi.del @prefix() + key - for k, v of value - multi.sadd @prefix() + key, v - else if value? and typeof value == 'object' - if overwrite - multi.del @prefix() + key - multi.hmset @prefix() + key, value - else - # TODO (value instanceof Boolean || typeof value == 'boolean') - console.log "not saved: type not found" - - # actual save - multi.exec (e, res) => - return done e if e - done() + async.waterfall [ + # Managing indexes, removing unused values, and adding new values + (cb) => + index_keys = Object.keys(@constructor.indexes) + async.eachSeries index_keys, (key, ccb) => + index_key = key + index_field = @constructor.indexes[key] + env.data.redis.get @prefix() + index_key, (err, value) => + if not err and @props[index_key]? and value? != @props[index_key] + multi.hdel index_field, value + multi.hset index_field, @props[index_key], @id + if not value + multi.set @prefix() + index_key, @props[index_key] + ccb() + , () => + cb() + # Saving normal keys + (cb) => + for key, value of @props + # check if key is an index + index_field = @constructor.indexes[key] + if index_field? + if @oldIndexesValues[key]? and @oldIndexesValues[key] != value + multi.hdel index_field, @oldIndexesValues[key] + if typeof value == 'string' or typeof value == 'number' + multi.set @prefix() + key, value + else if typeof value == 'object' and Array.isArray(value) + multi.del @prefix() + key + for k, v of value + multi.sadd @prefix() + key, v + else if value? and typeof value == 'object' + if overwrite + multi.del @prefix() + key + multi.hmset @prefix() + key, value + else + # TODO (value instanceof Boolean || typeof value == 'boolean') + console.log "not saved: type not found" + if opts.ttl? + multi.expire @prefix() + key, opts.ttl + + cb() + ], () => + # Actual execution of the db access + multi.exec (e, res) => + return done e if e + done() .fail (e) => return done e if e @@ -171,22 +223,39 @@ module.exports = (env) -> return defer.reject e if e defer.resolve() - + defer.promise remove: () -> defer = Q.defer() multi = env.data.redis.multi() - @keys() - .then (keys) => - for key in keys - multi.del key - multi.exec (e) => - return defer.reject e if e - @constructor.onRemoveAsync @, (e) -> - return defer.reject e if e - defer.resolve() - .fail (e) => - defer.reject e + + async.waterfall [ + # first delete indexes + (next) => + index_keys = Object.keys @constructor.indexes + async.eachSeries index_keys, (key, next2) => + env.data.redis.get @prefix() + key, (err, index_value) => + if not err? and index_value? + multi.hdel @constructor.indexes[key], index_value + next2() + , () => + next() + # then delete normal keys + (next) => + @keys() + .then (keys) => + for key in keys + multi.del key + multi.exec (e) => + return defer.reject e if e + @constructor.onRemoveAsync @, (e) => + return defer.reject e if e + defer.resolve() + next() + .fail (e) => + defer.reject e + next() + ] defer.promise - Entity \ No newline at end of file + Entity From 6c0f1cadb3c42b4955c2d8cfd0d343a59f43be2d Mon Sep 17 00:00:00 2001 From: Antoine Jackson Date: Fri, 12 Dec 2014 14:44:27 +0100 Subject: [PATCH 5/7] Made return format to return error when code is not 2xx --- src/core/utilities/formatters.coffee | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/utilities/formatters.coffee b/src/core/utilities/formatters.coffee index a307a275c..656e17df9 100644 --- a/src/core/utilities/formatters.coffee +++ b/src/core/utilities/formatters.coffee @@ -17,7 +17,7 @@ restify = require 'restify' module.exports = (env) -> - + check = env.utilities.check config = env.config @@ -50,6 +50,8 @@ module.exports = (env) -> result.message = res.message result.data = body if typeof body == 'object' && Object.keys(body).length else + if res.statusCode < 200 or res.statusCode >= 300 + result.status = 'error' body = null if not body? result.data = body body = result @@ -96,4 +98,4 @@ module.exports = (env) -> formatters: formatters build: (e,r) -> buildReply e || r, buildJsend: true } - \ No newline at end of file + From f21b0c0987e278f4a6d77e453662c616bbd15852 Mon Sep 17 00:00:00 2001 From: Vincent Lefebvre Date: Wed, 17 Dec 2014 19:09:30 +0100 Subject: [PATCH 6/7] fix list command display bug. --- src/cli/plugins.coffee | 87 +++++++++++++++-------------- src/scaffolding/plugins/info.coffee | 5 +- 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/cli/plugins.coffee b/src/cli/plugins.coffee index 53c7f1d53..6af79f0ca 100644 --- a/src/cli/plugins.coffee +++ b/src/cli/plugins.coffee @@ -81,8 +81,8 @@ module.exports = (args, options) -> installed = _installed console.log 'This instance has ' + (installed.length + ' installed plugin(s):').white - console.log (active.length + ' active plugin(s)').green - for name in active + console.log ((Object.keys(active)).length + ' active plugin(s)').green + for name, value of active console.log '- ' + name console.log (inactive.length + ' inactive plugin(s)').yellow for name in inactive @@ -249,50 +249,52 @@ module.exports = (args, options) -> if !plugin_data.name? return done null, null, true title = plugin_data.name?.white + ' ' - plugin_git = scaffolding.plugins.git(plugin_data.name, fetch) - text = plugin_data.description + "\n" if plugin_data.description? && plugin_data.description != "" - if not text? - text = 'No description\n' - plugin_git.getCurrentVersion() - .then (current_version) -> - if current_version.type == 'branch' - plugin_git.getVersionMask() - .then (mask) -> - update = '' - if not current_version.uptodate - update = ' (' + 'Updates available'.green + ')' - - if mask != current_version.version - update += ' (plugins.json points \'' + mask + '\')' - title += '(' +current_version.version + ')' + update + "" - - done(title, text) - else if current_version.type == 'tag_n' - plugin_git.getVersionMask() - .then (mask) -> - plugin_git.getLatestVersion(mask) - .then (latest_version) -> - + scaffolding.plugins.git(plugin_data.name, fetch) + .then (plugin_git) -> + text = plugin_data.description + "\n" if plugin_data.description? && plugin_data.description != "" + if not text? + text = 'No description\n' + plugin_git.getCurrentVersion() + .then (current_version) -> + if current_version.type == 'branch' + plugin_git.getVersionMask() + .then (mask) -> update = '' - if plugin_git.isNumericalVersion(latest_version) - if plugin_git.compareVersions(latest_version, current_version.version) > 0 - update = ' (' + latest_version.green + ' is available)' - else - update = ' (plugins.json points \'' + latest_version + '\')' + if not current_version.uptodate + update = ' (' + 'Updates available'.green + ')' + + if mask != current_version.version + update += ' (plugins.json points \'' + mask + '\')' title += '(' +current_version.version + ')' + update + "" done(title, text) - else if current_version.type == 'tag_a' - plugin_git.getVersionMask() - .then (mask) -> - title += '(tag ' + current_version.version + ')' - if (mask != current_version.version) - title += ' (plugins.json points \'' + mask + '\')' + else if current_version.type == 'tag_n' + plugin_git.getVersionMask() + .then (mask) -> + plugin_git.getLatestVersion(mask) + .then (latest_version) -> + update = '' + if plugin_git.isNumericalVersion(latest_version) + if plugin_git.compareVersions(latest_version, current_version.version) > 0 + update = ' (' + latest_version.green + ' is available)' + else + update = ' (plugins.json points \'' + latest_version + '\')' + title += '(' +current_version.version + ')' + update + "" + done(title, text) + else if current_version.type == 'tag_a' + plugin_git.getVersionMask() + .then (mask) -> + title += '(tag ' + current_version.version + ')' + if (mask != current_version.version) + title += ' (plugins.json points \'' + mask + '\')' + done(title, text) + else if current_version.type == 'unversionned' + title += "(unversionned)" done(title, text) - else if current_version.type == 'unversionned' - title += "(unversionned)" - done(title, text) + .fail (e) -> + done(title, text) .fail (e) -> - done(title, text) + if verbose + console.log 'Error with plugin \'' + name.white + '\':', e.message .fail (e) -> if verbose console.log 'Error with plugin \'' + name.white + '\':', e.message @@ -315,7 +317,8 @@ module.exports = (args, options) -> , options.fetch else scaffolding.plugins.info.getActive() - .then (names) -> + .then (plugins) -> + names = Object.keys plugins errors_found = false async.eachSeries names, (n, next) -> doGetInfo n, options.verbose?, (title, text, e) -> diff --git a/src/scaffolding/plugins/info.coffee b/src/scaffolding/plugins/info.coffee index bdbbfb96a..aa288469e 100644 --- a/src/scaffolding/plugins/info.coffee +++ b/src/scaffolding/plugins/info.coffee @@ -76,7 +76,7 @@ module.exports = (env) -> info.getPluginsJson { activeOnly: true } .then (plugins) -> - defer.resolve Object.keys plugins + defer.resolve plugins .fail (e) -> defer.reject e @@ -111,8 +111,7 @@ module.exports = (env) -> installed_plugins = _installed return info.getActive() .then (_active) -> - active_plugins = _active - + active_plugins = Object.keys _active inactive_plugins = [] for plugin in installed_plugins if plugin not in active_plugins From 10a1d358ce318bda4244ffa1bb29ec1348994bb7 Mon Sep 17 00:00:00 2001 From: Vincent Lefebvre Date: Wed, 17 Dec 2014 19:21:32 +0100 Subject: [PATCH 7/7] bump to version 1.0.0-alpha.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bfa0e9619..fd234b5f0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "oauthd", "description": "OAuth that just works.", - "version": "1.0.0-alpha.8", + "version": "1.0.0-alpha.9", "homepage": "http://oauth-io.github.io/oauthd", "author": "OAuth team ", "repository": {