Merge pull request #424 from resin-io/improve-key-exchange

Improve key exchange by first checking if an existing device api key is valid.
This commit is contained in:
Page- 2017-04-24 12:42:51 -07:00 committed by GitHub
commit 26fb0b4f64

View File

@ -35,26 +35,38 @@ loadPreloadedApps = ->
.catch (err) -> .catch (err) ->
utils.mixpanelTrack('Loading preloaded apps failed', { error: err }) utils.mixpanelTrack('Loading preloaded apps failed', { error: err })
exchangeKey = -> fetchDevice = (apiKey) ->
resinApi.get resinApi.get
resource: 'device' resource: 'device'
options: options:
filter: filter:
uuid: userConfig.uuid uuid: userConfig.uuid
customOptions: customOptions:
apikey: userConfig.apiKey apikey: apiKey
.catchReturn([]) .get(0)
.catchReturn(null)
.timeout(config.apiTimeout) .timeout(config.apiTimeout)
.then ([ device ]) ->
if not device? exchangeKey = ->
throw new ExchangeKeyError("Couldn't fetch device with provisioning key") Promise.try ->
# We found the device, we can try to generate a working device key for it # If we have an existing device key we first check if it's valid, because if it is we can just use that
request.postAsync("#{config.apiEndpoint}/api-key/device/#{device.id}/device-key") if userConfig.deviceApiKey?
.spread (res, body) -> fetchDevice(userConfig.deviceApiKey)
if res.status != 200 .then (device) ->
throw new ExchangeKeyError("Couldn't generate device key with provisioning key") if device?
userConfig.deviceApiKey = body return device
.return(device) # If it's not valid/doesn't exist then we try to use the user/provisioning api key for the exchange
fetchDevice(userConfig.apiKey)
.then (device) ->
if not device?
throw new ExchangeKeyError("Couldn't fetch device with provisioning key")
# We found the device, we can try to generate a working device key for it
request.postAsync("#{config.apiEndpoint}/api-key/device/#{device.id}/device-key")
.spread (res, body) ->
if res.status != 200
throw new ExchangeKeyError("Couldn't generate device key with provisioning key")
userConfig.deviceApiKey = body
.return(device)
bootstrap = -> bootstrap = ->
Promise.try -> Promise.try ->
@ -73,28 +85,14 @@ bootstrap = ->
) )
.timeout(config.apiTimeout) .timeout(config.apiTimeout)
.catch DuplicateUuidError, -> .catch DuplicateUuidError, ->
console.log('UUID already registered, checking if our device key is valid for it') console.log('UUID already registered, trying a key exchange')
resinApi.get exchangeKey()
resource: 'device' .tap ->
options: console.log('Key exchange succeeded, all good')
filter: .tapCatch ExchangeKeyError, (err) ->
uuid: userConfig.uuid # If it fails we just have to reregister as a provisioning key doesn't have the ability to change existing devices
customOptions: console.log('Exchanging key failed, having to reregister')
apikey: userConfig.deviceApiKey generateRegistration(true)
.catchReturn([])
.timeout(config.apiTimeout)
.then ([ device ]) ->
if device?
console.log('Fetched device, all is good')
return device
# If we couldn't fetch with the device key then we can try to key exchange in case the provisioning key is an old 'user-api-key'
console.log("Couldn't fetch the device, trying to exchange for a valid key")
exchangeKey()
.tapCatch ExchangeKeyError, (err) ->
# If it fails we just have to reregister as a provisioning key doesn't have the ability to change existing devices
console.log('Exchanging key failed, having to reregister')
generateRegistration(true)
.then (device) ->
.then ({ id }) -> .then ({ id }) ->
userConfig.registered_at = Date.now() userConfig.registered_at = Date.now()
userConfig.deviceId = id userConfig.deviceId = id