diff --git a/oauth3.core.js b/oauth3.core.js index 02085a1..2a3c75f 100644 --- a/oauth3.core.js +++ b/oauth3.core.js @@ -487,42 +487,44 @@ } } , hooks: { - directives: { - get: function (providerUri) { - providerUri = OAUTH3.uri.normalize(providerUri); - return OAUTH3.PromiseA.resolve(OAUTH3.hooks.directives._getCached(providerUri) - || OAUTH3.hooks.directives._get(providerUri)) - .then(function (directives) { - // or do .then(this._set) to keep DRY? - OAUTH3.hooks.directives._cache[providerUri] = directives; - return directives; - }); + _checkStorage: function (grpName, funcName) { + if (!OAUTH3._hooks) { + OAUTH3._hooks = {}; } - , _getCached: function (providerUri) { - providerUri = OAUTH3.uri.normalize(providerUri); - if (!OAUTH3.hooks.directives._cache) { OAUTH3.hooks.directives._cache = {}; } - return OAUTH3.hooks.directives._cache[providerUri]; + if (!OAUTH3._hooks[grpName]) { + console.log('using default storage for '+grpName+', set OAUTH3._hooks.'+grpName+' for custom storage'); + OAUTH3._hooks[grpName] = OAUTH3._defaultStorage[grpName]; + } + if (!OAUTH3._hooks[grpName][funcName]) { + throw new Error("'"+funcName+"' is not defined for custom "+grpName+" storage"); + } + } + , directives: { + get: function (providerUri) { + OAUTH3.hooks._checkStorage('directives', 'get'); + + if (!providerUri) { + throw new Error("providerUri is not set"); + } + return OAUTH3.PromiseA.resolve(OAUTH3._hooks.directives.get(OAUTH3.uri.normalize(providerUri))); } , set: function (providerUri, directives) { - providerUri = OAUTH3.uri.normalize(providerUri); - if (!OAUTH3.hooks.directives._cache) { OAUTH3.hooks.directives._cache = {}; } - OAUTH3.hooks.directives._cache[providerUri] = directives; - return OAUTH3.PromiseA.resolve(OAUTH3.hooks.directives._set(providerUri, directives)); - } - , _get: function (providerUri) { - if (!OAUTH3._hooks || !OAUTH3._hooks.directives || !OAUTH3._hooks.directives.get) { - console.warn('[Warn] Please implement OAUTH3._hooks.directives.get = function (providerUri) { return PromiseA; }'); - return JSON.parse(window.localStorage.getItem('directives-' + providerUri) || '{}'); + OAUTH3.hooks._checkStorage('directives', 'set'); + + if (!providerUri) { + throw new Error("providerUri is not set"); } - return OAUTH3._hooks.directives.get(providerUri); + return OAUTH3.PromiseA.resolve(OAUTH3._hooks.directives.set(OAUTH3.uri.normalize(providerUri), directives)); } - , _set: function (providerUri, directives) { - if (!OAUTH3._hooks || !OAUTH3._hooks.directives || !OAUTH3._hooks.directives.set) { - console.warn('[Warn] Please implement OAUTH3._hooks.directives.set = function (providerUri, directives) { return PromiseA; }'); - window.localStorage.setItem('directives-' + providerUri, JSON.stringify(directives)); - return directives; - } - return OAUTH3._hooks.directives.set(providerUri, directives); + , all: function () { + OAUTH3.hooks._checkStorage('directives', 'all'); + + return OAUTH3.PromiseA.resolve(OAUTH3._hooks.directives.all()); + } + , clear: function () { + OAUTH3.hooks._checkStorage('directives', 'clear'); + + return OAUTH3.PromiseA.resolve(OAUTH3._hooks.directives.clear()); } } , session: { @@ -563,7 +565,7 @@ } // set for a set of audiences - return OAUTH3.PromiseA.resolve(OAUTH3.hooks.session.set(providerUri, oldSession)); + return OAUTH3.hooks.session.set(providerUri, oldSession); } , check: function (preq, opts) { opts = opts || {}; @@ -616,62 +618,40 @@ return newSession; // oauth3.hooks.refreshSession(expiredSession, newSession); }); } - , _getCached: function (providerUri, id) { - providerUri = OAUTH3.uri.normalize(providerUri); - if (!OAUTH3.hooks.session._cache) { OAUTH3.hooks.session._cache = {}; } - if (id) { - return OAUTH3.hooks.session._cache[providerUri + id]; - } - return OAUTH3.hooks.session._cache[providerUri]; - } , set: function (providerUri, newSession, id) { + OAUTH3.hooks._checkStorage('sessions', 'set'); + if (!providerUri) { console.error(new Error('no providerUri').stack); throw new Error("providerUri is not set"); } providerUri = OAUTH3.uri.normalize(providerUri); - if (!OAUTH3.hooks.session._cache) { OAUTH3.hooks.session._cache = {}; } - OAUTH3.hooks.session._cache[providerUri + (id || newSession.id || newSession.token.id || '')] = newSession; - if (!id) { - OAUTH3.hooks.session._cache[providerUri] = newSession; - } - return OAUTH3.PromiseA.resolve(OAUTH3.hooks.session._set(providerUri, newSession)); + return OAUTH3.PromiseA.resolve(OAUTH3._hooks.sessions.set(providerUri, newSession, id)); } , get: function (providerUri, id) { - providerUri = OAUTH3.uri.normalize(providerUri); + OAUTH3.hooks._checkStorage('sessions', 'get'); + if (!providerUri) { throw new Error("providerUri is not set"); } + providerUri = OAUTH3.uri.normalize(providerUri); + return OAUTH3.PromiseA.resolve(OAUTH3._hooks.sessions.get(providerUri, id)); + } + , all: function (providerUri) { + OAUTH3.hooks._checkStorage('sessions', 'all'); - return OAUTH3.PromiseA.resolve( - OAUTH3.hooks.session._getCached(providerUri, id) || OAUTH3.hooks.session._get(providerUri, id) - ).then(function (session) { - var s = session || { token: {} }; - OAUTH3.hooks.session._cache[providerUri + (id || s.id || s.token.id || '')] = session; - if (!id) { - OAUTH3.hooks.session._cache[providerUri] = session; - } - return session; - }); + if (providerUri) { + providerUri = OAUTH3.uri.normalize(providerUri); + } + return OAUTH3.PromiseA.resolve(OAUTH3._hooks.sessions.all(providerUri)); } - , _get: function (providerUri, id) { - if (!OAUTH3._hooks || !OAUTH3._hooks.sessions || !OAUTH3._hooks.sessions.all) { - console.warn('[Warn] Please implement OAUTH3._hooks.sessions.all = function ([providerUri]) { return PromiseA; }'); + , clear: function (providerUri) { + OAUTH3.hooks._checkStorage('sessions', 'clear'); + + if (providerUri) { + providerUri = OAUTH3.uri.normalize(providerUri); } - if (!OAUTH3._hooks || !OAUTH3._hooks.sessions || !OAUTH3._hooks.sessions.get) { - console.warn('[Warn] Please implement OAUTH3._hooks.sessions.get = function (providerUri[, id]) { return PromiseA; }'); - return JSON.parse(window.sessionStorage.getItem('session-' + providerUri + (id || '')) || 'null'); - } - return OAUTH3._hooks.sessions.get(providerUri, id); - } - , _set: function (providerUri, newSession, id) { - if (!OAUTH3._hooks || !OAUTH3._hooks.sessions || !OAUTH3._hooks.sessions.set) { - console.warn('[Warn] Please implement OAUTH3._hooks.sessions.set = function (providerUri, newSession[, id]) { return PromiseA; }'); - window.sessionStorage.setItem('session-' + providerUri, JSON.stringify(newSession)); - window.sessionStorage.setItem('session-' + providerUri + (id || newSession.id || newSession.token.id || ''), JSON.stringify(newSession)); - return newSession; - } - return OAUTH3._hooks.sessions.set(providerUri, newSession, id); + return OAUTH3.PromiseA.resolve(OAUTH3._hooks.sessions.clear(providerUri)); } } } @@ -844,7 +824,7 @@ return OAUTH3.PromiseA.reject(OAUTH3.error.parse(directives.issuer /*providerUri*/, params)); } - OAUTH3.hooks.session._cache = {}; + OAUTH3.hooks.session.clear(); return params; }); } @@ -1119,6 +1099,82 @@ }; OAUTH3.login = OAUTH3.implicitGrant; + OAUTH3._defaultStorage = { + _getStorageKeys: function (prefix, storage) { + storage = storage || window.localStorage; + var matching = []; + var ind, key; + for (ind = 0; ind < storage.length; ind++) { + key = storage.key(ind); + if (key.indexOf(prefix || '') === 0) { + matching.push(key); + } + } + return matching; + } + , directives: { + prefix: 'directives-' + , get: function (providerUri) { + var result = JSON.parse(window.localStorage.getItem(this.prefix + providerUri) || '{}'); + return OAUTH3.PromiseA.resolve(result); + } + , set: function (providerUri, directives) { + window.localStorage.setItem(this.prefix + providerUri, JSON.stringify(directives)); + return this.get(providerUri); + } + , all: function () { + var prefix = this.prefix; + var result = {}; + OAUTH3._defaultStorage._getStorageKeys(prefix).forEach(function (key) { + result[key.replace(prefix, '')] = JSON.parse(window.localStorage.getItem(key) || '{}'); + }); + return OAUTH3.PromiseA.resolve(result); + } + , clear: function () { + OAUTH3._defaultStorage._getStorageKeys(this.prefix).forEach(function (key) { + window.localStorage.removeItem(key); + }); + return OAUTH3.PromiseA.resolve(); + } + } + , sessions: { + prefix: 'session-' + , get: function (providerUri, id) { + var result; + if (id) { + result = JSON.parse(window.sessionStorage.getItem(this.prefix + providerUri+id) || 'null'); + } else { + result = JSON.parse(window.sessionStorage.getItem(this.prefix + providerUri) || 'null'); + } + return OAUTH3.PromiseA.resolve(result); + } + , set: function (providerUri, newSession, id) { + var str = JSON.stringify(newSession); + window.sessionStorage.setItem(this.prefix + providerUri, str); + id = id || newSession.id || newSession.token.token.id; + if (id) { + window.sessionStorage.setItem(this.prefix + providerUri + id, str); + } + return this.get(providerUri, id); + } + , all: function (providerUri) { + var prefix = this.prefix + (providerUri || ''); + var result = {}; + OAUTH3._defaultStorage._getStorageKeys(prefix, window.sessionStorage).forEach(function (key) { + result[key.replace(prefix, '')] = JSON.parse(window.localStorage.getItem(key) || 'null'); + }); + return OAUTH3.PromiseA.resolve(result); + } + , clear: function (providerUri) { + var prefix = this.prefix + (providerUri || ''); + OAUTH3._defaultStorage._getStorageKeys(prefix, window.sessionStorage).forEach(function (key) { + window.localStorage.removeItem(key); + }); + return OAUTH3.PromiseA.resolve(); + } + } + }; + // TODO get rid of these OAUTH3.utils = { clientUri: OAUTH3.clientUri diff --git a/oauth3.node.js b/oauth3.node.js index 95b0bd3..97fecd1 100644 --- a/oauth3.node.js +++ b/oauth3.node.js @@ -28,6 +28,7 @@ OAUTH3._base64.atob = function (base64) { OAUTH3._base64.btoa = function (text) { return new Buffer(text, 'utf8').toString('base64'); }; +OAUTH3._defaultStorage = require('./oauth3.node.storage'); OAUTH3._node = {}; OAUTH3._node.discover = function(providerUri/*, opts*/) { diff --git a/oauth3.node.storage.js b/oauth3.node.storage.js index 370c678..c18046f 100644 --- a/oauth3.node.storage.js +++ b/oauth3.node.storage.js @@ -67,10 +67,9 @@ module.exports = { , sessions: { all: function (providerUri) { - var dirname = path.join(oauth3dir, 'sessions'); - return fs.readdirAsync(dirname).then(function (nodes) { + return fs.readdirAsync(sessionsdir).then(function (nodes) { return nodes.map(function (node) { - var result = require(path.join(dirname, node)); + var result = require(path.join(sessionsdir, node)); if (result.link) { return null; } @@ -91,7 +90,7 @@ module.exports = { result = require(path.join(sessionsdir, providerUri + '.json')); // TODO make safer if (result.link && '/' !== result.link[0] && !/\.\./.test(result.link)) { - result = require(path.join(oauth3dir, 'sessions', result.link)); + result = require(path.join(sessionsdir, result.link)); } } } catch(e) { @@ -113,10 +112,9 @@ module.exports = { }); } , clear: function () { - var dirname = path.join(oauth3dir, 'sessions'); - return fs.readdirAsync(dirname).then(function (nodes) { + return fs.readdirAsync(sessionsdir).then(function (nodes) { return PromiseA.all(nodes.map(function (node) { - return fs.unlinkAsync(path.join(dirname, node)); + return fs.unlinkAsync(path.join(sessionsdir, node)); })); }); }