From 578e2b7354bacfacd7fff9f56b4b9f22a73ee3f6 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 24 Jan 2017 16:46:56 -0500 Subject: [PATCH] auto-refresh on request --- oauth3.js | 104 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 17 deletions(-) diff --git a/oauth3.js b/oauth3.js index dfb304a..e8bd127 100644 --- a/oauth3.js +++ b/oauth3.js @@ -73,14 +73,95 @@ }); }; - oauth3.provideRequest = function (request, opts) { + oauth3._recaseRequest = function (recase, req) { + // convert JavaScript camelCase to oauth3/ruby snake_case + if (req.data && 'object' === typeof req.data) { + req.originalData = req.data; + req.data = recase.snakeCopy(req.data); + } + + return req; + }; + oauth3._recaseResponse = function (recase, resp) { + // convert oauth3/ruby snake_case to JavaScript camelCase + if (resp.data && 'object' === typeof resp.data) { + resp.originalData = resp.data; + resp.data = recase.camelCopy(resp.data); + } + return resp; + }; + oauth3._lintRequest = function (preq, opts) { + var providerUri; + var fresh; + + console.log('[os] request meta opts', opts); + + // check that the JWT is not expired + // TODO check that this request applies to the aud and azp + if (!(preq.session && preq.session.accessToken)) { + console.log('[os] no session/accessTokenData'); + return oauth3.PromiseA.resolve(preq); + } + + preq.headers = preq.headers || {}; + preq.headers.Authorization = 'Bearer ' + preq.session.accessToken; + + if (!preq.session._accessTokenData) { + console.log('[os] no _accessTokenData'); + preq.session._accessTokenData = core.jwt.decode(preq.session.accessToken).payload; + } + + if (!preq.url.match(preq.session._accessTokenData.aud)) { + console.log("[os] doesn't match audience", preq.session._accessTokenData.aud); + return oauth3.PromiseA.resolve(preq); + } + + fresh = (Date.now() / 1000) >= (parseInt(preq.session._accessTokenData.exp) || 0); + if (!fresh) { + console.log("[os] isn't fresh", preq.session._accessTokenData.exp); + return oauth3.PromiseA.resolve(preq); + } + + if (!preq.session.refreshToken) { + console.log("[os] cann't refresh", preq.session); + return oauth3.PromiseA.resolve(preq); + } + + opts.refreshToken = preq.session.refreshToken; + console.log('[oauth3.js] refreshToken attempt'); + + // TODO include directive? + providerUri = preq.session.providerUri || preq.session._accessTokenData.iss; + //opts. + return oauth3.refreshToken(providerUri, opts).then(function (res) { + console.log('[oauth3.js] refreshToken result:', res); + + if (!res.data.accessToken) { + return preq; + } + + // TODO fire session update event + res.data.providerUri = preq.session.providerUri; + preq.session = res.data; + preq.headers.Authorization = 'Bearer ' + preq.session.accessToken; + return preq; + }); + }; + + oauth3.provideRequest = function (rawRequest, opts) { opts = opts || {}; var Recase = exports.Recase || require('recase'); // TODO make insensitive to providing exceptions var recase = Recase.create({ exceptions: {} }); + function lintAndRequest(preq) { + return oauth3._lintRequest(preq, opts).then(function (preq) { + return rawRequest(preq); + }); + } + if (opts.rawCase) { - oauth3.request = request; + oauth3.request = lintAndRequest; return; } @@ -90,23 +171,12 @@ opts = opts || {}; if (opts.rawCase) { - return request(req); + return lintAndRequest(req, opts); } - // convert JavaScript camelCase to oauth3 snake_case - if (req.data && 'object' === typeof req.data) { - req.originalData = req.data; - req.data = recase.snakeCopy(req.data); - } - - //console.log('[F] [oauth3 req.url]', req.url); - return request(req).then(function (resp) { - // convert oauth3 snake_case to JavaScript camelCase - if (resp.data && 'object' === typeof resp.data) { - resp.originalData = resp.data; - resp.data = recase.camelCopy(resp.data); - } - return resp; + req = oauth3._recaseRequest(recase, req); + return lintAndRequest(req, opts).then(function (res) { + return oauth3._recaseResponse(recase, res); }); };