ducky/web

Paddy 2015-07-07 Parent:3bdc03963abe

18:9b97c908a706 Go to Latest

ducky/web/src/helpers/oauth-refresh.js

Fix bug in oauth-refresh, update for hosted path. Our nginx-fronted path has changed, so update the helper to hit the right URL. Also, fix a bug that would cause every failed request to be retried, which was suboptimal.

History
paddy@11 1 import app from 'ampersand-app'
paddy@11 2 import xhr from 'xhr'
paddy@11 3 import qs from 'qs'
paddy@11 4 import Sync from 'ampersand-sync'
paddy@11 5 import config from '../config'
paddy@11 6
paddy@11 7 const getRefresh = (opts, callback) => {
paddy@11 8 const refreshOpts = {
paddy@18 9 url: config.urlBase + '/auth/token',
paddy@11 10 method: 'POST',
paddy@11 11 headers: {
paddy@11 12 'Content-Type': 'application/x-www-form-urlencoded',
paddy@11 13 'Authorization': 'Basic ' + btoa(config.clientID + ':' + config.clientSecret),
paddy@11 14 },
paddy@11 15 data: qs.stringify({
paddy@11 16 'grant_type': 'refresh_token',
paddy@11 17 'refresh_token': app.me.refresh_token
paddy@11 18 }),
paddy@11 19 }
paddy@11 20 xhr(refreshOpts, function(err, resp, body) {
paddy@11 21 if (resp.statusCode != 200) {
paddy@11 22 callback(err, resp, body)
paddy@11 23 return
paddy@11 24 }
paddy@11 25 if (body && resp.headers['content-type'] == 'application/json') {
paddy@11 26 try {
paddy@11 27 body = JSON.parse(body)
paddy@11 28 } catch (err) {
paddy@11 29 app.trigger('token:refreshError', body)
paddy@11 30 callback(err, resp, body)
paddy@11 31 }
paddy@11 32 }
paddy@11 33 if (body.access_token) {
paddy@11 34 app.me.set(body)
paddy@11 35 } else {
paddy@11 36 app.trigger('token:refreshError', body)
paddy@11 37 }
paddy@11 38 callback(err, resp, body)
paddy@11 39 })
paddy@11 40 }
paddy@11 41
paddy@11 42 const shouldRefreshXHR = (err, resp, body) => {
paddy@11 43 if(body && resp.headers['Content-Type'] == 'application/json') {
paddy@11 44 try {
paddy@11 45 body = JSON.parse(body)
paddy@11 46 } catch (err) {
paddy@11 47 return false
paddy@11 48 }
paddy@11 49 }
paddy@11 50 if (resp.statusCode == 401 && body.errors && body.errors[0]
paddy@11 51 && body.errors[0].header == 'authorization' && body.errors[0].error == 'access_denied') {
paddy@11 52 return true
paddy@11 53 }
paddy@11 54 return false
paddy@11 55 }
paddy@11 56
paddy@11 57 const doRefreshXHR = (opts, callback) => {
paddy@11 58 opts.noRefresh = true
paddy@11 59 getRefresh(opts, function(err, resp, body) {
paddy@11 60 if (body.access_token) {
paddy@11 61 opts.headers['Authorization'] = 'Bearer '+body.access_token
paddy@11 62 xhr(opts, callback)
paddy@11 63 }
paddy@11 64 })
paddy@11 65 }
paddy@11 66
paddy@11 67 const refreshXHR = (opts, callback) => {
paddy@11 68 return xhr(opts, function(err, resp, body) {
paddy@11 69 if (opts.noRefresh || !shouldRefreshXHR(err, resp, body)) {
paddy@11 70 callback(err, resp, body)
paddy@11 71 return
paddy@11 72 }
paddy@11 73 doRefreshXHR(opts, callback)
paddy@11 74 })
paddy@11 75 xhr(opts, callback)
paddy@11 76 }
paddy@11 77
paddy@11 78 const shouldRefreshSync = (resp) => {
paddy@11 79 if (resp && resp.errors && resp.errors[0]
paddy@11 80 && resp.errors[0].header == 'authorization' && resp.errors[0].error == 'access_denied') {
paddy@11 81 return true
paddy@11 82 }
paddy@11 83 return false
paddy@11 84 }
paddy@11 85
paddy@11 86 const doRefreshSync = (action, moc, opts) => {
paddy@11 87 opts.noRefresh = true
paddy@11 88 getRefresh(opts, function(err, resp, body) {
paddy@11 89 if (body.access_token) {
paddy@11 90 Sync(action, moc, opts)
paddy@11 91 }
paddy@11 92 })
paddy@11 93 }
paddy@11 94
paddy@11 95 const refreshSync = (action, moc, opts) => {
paddy@11 96 const oldError = opts.error
paddy@11 97 opts.error = function(resp) {
paddy@18 98 if(opts.noRefresh || !shouldRefreshSync(resp)) {
paddy@11 99 oldError(resp)
paddy@11 100 return
paddy@11 101 }
paddy@11 102 doRefreshSync(action, moc, opts)
paddy@11 103 }
paddy@11 104 Sync(action, moc, opts)
paddy@11 105 }
paddy@11 106
paddy@11 107 const refresh = {
paddy@11 108 Sync: refreshSync,
paddy@11 109 XHR: refreshXHR,
paddy@11 110 }
paddy@11 111
paddy@11 112 export default refresh