diff --git a/common/doordeck.js b/common/doordeck.js index b4ef37b..9e0e823 100644 --- a/common/doordeck.js +++ b/common/doordeck.js @@ -1,4 +1,4 @@ -import { AUTH_TOKEN } from './constants' +import { AUTH_TOKEN, EPHEMERAL_PUBKEY, EPHEMERAL_PRIKEY, CERT } from './constants' import ephemaralKeyGenerator from './services/ephemeralKeyGenerator' import certificate from './services/certificate' import libSodium from 'libsodium-wrappers' @@ -14,20 +14,29 @@ const isLoaded = function (authToken) { } else return false } -const doordeckInit = function (authToken) { +const doordeckInit = function (authToken, reset = false) { + if (reset) { + doordeckReset(); + } return new Promise (function(resolve, reject) { libSodium.ready.then(function () { - if (isLoaded()) resolve({state: 'success', message: 'Doordeck is already initialised.'}) - if (authToken !== null && authToken !== undefined) { - storeAuthToken(authToken) - ephemaralKeyGenerator.generateKeys().then(keys => { - certificate.getCertificate(keys).then(response => { - resolve(response) - }, fail => { - reject(fail) + if (isLoaded(authToken)) { + resolve({state: 'success', message: 'Doordeck is already initialised.'}); + } else { + if (authToken !== null && authToken !== undefined) { + storeAuthToken(authToken) + certificate.resetCert(); + ephemaralKeyGenerator.generateKeys().then(keys => { + certificate.getCertificate(keys).then(response => { + resolve(response) + }, fail => { + reject(fail) + }) }) - }) - } else reject({state: 'error', message: 'No Auth Token provided.'}) + } else { + reject({state: 'error', message: 'No Auth Token provided.'}); + } + } }) }) } @@ -64,11 +73,17 @@ const getStoredAuthToken = function () { return localStorage[AUTH_TOKEN] } - const verifyCode = function (code) { return certificate.verifyCode(code, ephemaralKeyGenerator.retrieveSavedKeys()) } +const doordeckReset = function () { + localStorage.removeItem(AUTH_TOKEN); + localStorage.removeItem(CERT); + localStorage.removeItem(EPHEMERAL_PRIKEY); + localStorage.removeItem(EPHEMERAL_PUBKEY); +} + export default { doordeckInit, verifyCode, diff --git a/common/services/certificate.js b/common/services/certificate.js index cf536f6..b84dca5 100644 --- a/common/services/certificate.js +++ b/common/services/certificate.js @@ -9,6 +9,9 @@ const retrieveSavedCert = function () { const storeCert = function (cert) { localStorage[CERT] = JSON.stringify(cert) } +const resetCert = function () { + localStorage[CERT] = null; +} const registerCertificate = function (pubKey) { var ephKey = doordeck.libSodium.to_base64(pubKey, doordeck.libSodium.base64_variants.ORIGINAL) return axios.post(BASE_URL + '/auth/certificate', { @@ -53,6 +56,12 @@ export default { if (response.data.method !== undefined && response.data.method !== null) { reject({state: 'verify', method: response.data.method}) } else reject({state: 'error', message: 'Failed to send 2FA request'}) + }, fail => { + if (fail.response.status === 429) { + reject({state: 'error', message: 'Too many current pending verifications', code: 429}); + } else { + reject({state: 'error', message: 'Failed to send 2FA request'}); + } }) } else { reject({state: 'error', message: 'Failed to get certificate'}) @@ -74,5 +83,6 @@ export default { }) }) }, - retrieveSavedCert + retrieveSavedCert, + resetCert } diff --git a/common/services/deviceOperation.js b/common/services/deviceOperation.js index 1069019..bcc99b1 100644 --- a/common/services/deviceOperation.js +++ b/common/services/deviceOperation.js @@ -1,5 +1,5 @@ import axios from 'axios' -import { BASE_URL, CERT } from '../constants' +import { BASE_URL, CERT, AUTH_TOKEN } from '../constants' import ephemaralKeyGenerator from './ephemeralKeyGenerator' import doordeck from '../doordeck' @@ -34,8 +34,8 @@ var executor = function (deviceId, operation) { { skipAuthorization: true, headers: { - 'Authorization': 'Bearer ' + localStorage.token, - 'Content-Type': 'application/json' + 'Authorization': 'Bearer ' + localStorage[AUTH_TOKEN], + 'Content-Type': 'application/jwt' }, timeout: 10000 } @@ -44,7 +44,7 @@ var executor = function (deviceId, operation) { var getDoordeckUserByEmail = function (userEmail, visitor) { return axios.post(baseUrl + '/share/invite/' + userEmail + '?visitor=' + visitor, null, { headers: { - 'Authorization': 'Bearer ' + localStorage.token, + 'Authorization': 'Bearer ' + localStorage[AUTH_TOKEN], 'Content-Type': 'application/json' } }).then(response => { @@ -54,7 +54,7 @@ var getDoordeckUserByEmail = function (userEmail, visitor) { var getUserByEmail = function (email) { return axios.post(baseUrl + '/directory/query', {'email': email}, { headers: { - 'Authorization': 'Bearer ' + localStorage.token, + 'Authorization': 'Bearer ' + localStorage[AUTH_TOKEN], 'Content-Type': 'application/json' } }).then(response => { @@ -64,7 +64,7 @@ var getUserByEmail = function (email) { var getUserById = function (id) { return axios.post(baseUrl + '/directory/query', {'localKey': id}, { headers: { - 'Authorization': 'Bearer ' + localStorage.token, + 'Authorization': 'Bearer ' + localStorage[AUTH_TOKEN], 'Content-Type': 'application/json' } }).then(response => { @@ -200,7 +200,7 @@ export default { return axios.get(baseUrl + '/tile/' + tileId, { headers: { 'Accept': 'application/vnd.doordeck.api-v3+json', - 'Authorization': 'Bearer ' + localStorage.token, + 'Authorization': 'Bearer ' + localStorage[AUTH_TOKEN], 'Content-Type': 'application/json' } }) @@ -208,7 +208,7 @@ export default { link (deviceId, tileId) { return axios.put(baseUrl + '/device/' + deviceId + '/tile/' + tileId, null, { headers: { - 'Authorization': 'Bearer ' + localStorage.token, + 'Authorization': 'Bearer ' + localStorage[AUTH_TOKEN], 'Content-Type': 'application/json' } }) @@ -216,7 +216,7 @@ export default { delink (deviceId, tileId) { return axios.delete(baseUrl + '/device/' + deviceId + '/tile/' + tileId, { headers: { - 'Authorization': 'Bearer ' + localStorage.token, + 'Authorization': 'Bearer ' + localStorage[AUTH_TOKEN], 'Content-Type': 'application/json' } })