-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
954 additions
and
546 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
export class LocalStorage { | ||
constructor (prefix = 'cozy:oauth:', getLocalStorage = () => window.localStorage) { | ||
// We try to deref the localstorage, and if it fails (because the user has | ||
// deactivated its localstorage for instance) we fallback on a memory | ||
// storage. | ||
let storage | ||
try { | ||
storage = getLocalStorage() | ||
} catch (e) { | ||
storage = memStorage | ||
} | ||
this.storage = storage | ||
this.prefix = prefix | ||
} | ||
|
||
save (key, value) { | ||
return new Promise(resolve => resolve( | ||
this.storage.setItem(this.prefix + key, JSON.stringify(value)))) | ||
} | ||
|
||
load (key) { | ||
return new Promise(resolve => { | ||
const item = this.storage.getItem(this.prefix + key) | ||
if (!item) { | ||
resolve() | ||
} else { | ||
resolve(JSON.parse(item)) | ||
} | ||
}) | ||
} | ||
|
||
delete (key) { | ||
return new Promise(resolve => resolve( | ||
this.storage.removeItem(this.prefix + key))) | ||
} | ||
|
||
clear () { | ||
return new Promise(resolve => { | ||
const storage = this.storage | ||
for (let i = 0; i < storage.length; i++) { | ||
const key = storage.key(i) | ||
if (key.indexOf(this.prefix) === 0) { | ||
storage.removeItem(key) | ||
} | ||
} | ||
resolve() | ||
}) | ||
} | ||
} | ||
|
||
export class MemoryStorage { | ||
constructor () { | ||
this.hash = {} | ||
} | ||
|
||
save (key, value) { | ||
return Promise.resolve(this.hash[key] = value) | ||
} | ||
|
||
load (key) { | ||
return Promise.resolve(this.hash[key]) | ||
} | ||
|
||
delete (key) { | ||
return Promise.resolve(delete this.hash[key]) | ||
} | ||
|
||
clear () { | ||
return Promise.resolve(this.hash = {}) | ||
} | ||
} | ||
|
||
const memStorage = { | ||
_h: {}, | ||
_k: [], | ||
length: 0, | ||
setItem (key, value) { | ||
if (!this._h.hasOwnProperty(key)) { | ||
this._k.push(key) | ||
this.length++ | ||
} | ||
this._h[key] = value | ||
}, | ||
getItem (key) { | ||
return this._h[key] | ||
}, | ||
removeItem (key) { | ||
if (delete this._h[key]) { | ||
this._k.splice(this._k.indexOf(key), 1) | ||
this.length-- | ||
return true | ||
} | ||
return false | ||
}, | ||
key (index) { | ||
return this._k[index] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* global btoa */ | ||
const V2TOKEN_ABORT_TIMEOUT = 3000 | ||
|
||
export function getAccessToken () { | ||
return new Promise(function (resolve, reject) { | ||
if (typeof window === 'undefined') { | ||
return reject(new Error('getV2Token should be used in browser')) | ||
} else if (!window.parent) { | ||
return reject(new Error('getV2Token should be used in iframe')) | ||
} else if (!window.parent.postMessage) { | ||
return reject(new Error('getV2Token should be used in modern browser')) | ||
} | ||
const origin = window.location.origin | ||
const intent = {action: 'getToken'} | ||
let timeout = null | ||
const receiver = function (event) { | ||
let token | ||
try { | ||
token = new AccessToken({ | ||
appName: event.data.appName, | ||
token: event.data.token | ||
}) | ||
} catch (e) { | ||
reject(e) | ||
return | ||
} | ||
window.removeEventListener('message', receiver) | ||
clearTimeout(timeout) | ||
resolve({ client: null, token }) | ||
} | ||
window.addEventListener('message', receiver, false) | ||
window.parent.postMessage(intent, origin) | ||
timeout = setTimeout(() => { | ||
reject(new Error('No response from parent iframe after 3s')) | ||
}, V2TOKEN_ABORT_TIMEOUT) | ||
}) | ||
} | ||
|
||
export class AccessToken { | ||
constructor (opts) { | ||
this.appName = opts.appName || '' | ||
this.token = opts.token || '' | ||
if (this.appName === '') { | ||
throw new Error('Missing appName parameter') | ||
} | ||
if (this.token === '') { | ||
throw new Error('Missing token parameter') | ||
} | ||
} | ||
|
||
toAuthHeader () { | ||
return 'Basic ' + btoa(`${this.appName}:${this.token}`) | ||
} | ||
} |
Oops, something went wrong.