Skip to content

Commit

Permalink
v3.0.3: access /account with a timestamp when logged in, to prevent h…
Browse files Browse the repository at this point in the history
…itting a browser cache
  • Loading branch information
joanniclaborde committed Jun 20, 2024
1 parent 87f8a09 commit ca47a6c
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 13 deletions.
18 changes: 13 additions & 5 deletions build/universe.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ Universe.prototype.init = function(callback) {
var data = {};

getFanclub.call(self, function(err, fanclub) {
data.fanclub = fanclub;
self.fanclub = data.fanclub = fanclub;
if (err) {
if (callback) callback(err, data);
return setTimeout(function() {self.emit('error', err)}, 0);
}

getCustomer.call(self, function(err, customer) {
data.customer = customer;
self.customer = data.customer = customer;
if (callback) callback(err, data);
if (!err) setTimeout(function() {self.emit('ready', data)}, 0);
});
Expand Down Expand Up @@ -96,8 +96,8 @@ Universe.prototype.linkify = function(scope, processor) {
// PRIVATE

var getFanclub = function(callback) {
if (this.context && this.context.resources && this.context.resources.fanclub) {
callback(null, this.context.resources.fanclub.fanclub);
if (this.fanclub || (this.context && this.context.resources && this.context.resources.fanclub)) {
callback(null, this.fanclub || this.context.resources.fanclub.fanclub);
} else {
this.get('/fanclub', function(err, data) {
callback(err, data ? data.fanclub : null);
Expand All @@ -107,7 +107,10 @@ var getFanclub = function(callback) {

var getCustomer = function(callback) {
if (!this.useJWT || localStorage.getItem('universeAccessToken')) {
this.get('/account', function(err, data) {
// When logged in, add the login time to the /account query, to prevent the
// browser from serving a cached "logged out" response (and vice-versa)
this.get(localStorage.getItem('universeLoginTime') ? '/account?t=' + localStorage.getItem('universeLoginTime').toString() : '/account', function(err, data) {
if (!err && data && !data.customer) localStorage.removeItem('universeLoginTime');
callback(err, data ? data.customer : null);
});
} else {
Expand Down Expand Up @@ -160,6 +163,7 @@ var validateTokens = function(callback) {
// Valid access token
return callback();
} else {
// Missing or expired access token
localStorage.removeItem('universeAccessToken');
localStorage.removeItem('universeAccessTokenExpiration');
}
Expand All @@ -168,6 +172,7 @@ var validateTokens = function(callback) {
// Missing or expired refresh token
localStorage.removeItem('universeRefreshToken');
localStorage.removeItem('universeRefreshTokenExpiration');
localStorage.removeItem('universeLoginTime');
return callback(true);
}

Expand All @@ -179,6 +184,7 @@ var validateTokens = function(callback) {
// Invalid refresh token
localStorage.removeItem('universeRefreshToken');
localStorage.removeItem('universeRefreshTokenExpiration');
localStorage.removeItem('universeLoginTime');
}
callback(err);
} else {
Expand Down Expand Up @@ -263,12 +269,14 @@ function linkify (fanclub, scope, processor, popup) {

if (url.match('login')) {
event.preventDefault();
localStorage.setItem('universeLoginTime', Date.now());
module.exports.prompt(fanclub, url, processor, popup);
} else if (url.match('logout')) {
localStorage.removeItem('universeAccessToken');
localStorage.removeItem('universeAccessTokenExpiration');
localStorage.removeItem('universeRefreshToken');
localStorage.removeItem('universeRefreshTokenExpiration');
localStorage.removeItem('universeLoginTime');
}
});
};
Expand Down
16 changes: 11 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ Universe.prototype.init = function(callback) {
var data = {};

getFanclub.call(self, function(err, fanclub) {
data.fanclub = fanclub;
self.fanclub = data.fanclub = fanclub;
if (err) {
if (callback) callback(err, data);
return setTimeout(function() {self.emit('error', err)}, 0);
}

getCustomer.call(self, function(err, customer) {
data.customer = customer;
self.customer = data.customer = customer;
if (callback) callback(err, data);
if (!err) setTimeout(function() {self.emit('ready', data)}, 0);
});
Expand Down Expand Up @@ -95,8 +95,8 @@ Universe.prototype.linkify = function(scope, processor) {
// PRIVATE

var getFanclub = function(callback) {
if (this.context && this.context.resources && this.context.resources.fanclub) {
callback(null, this.context.resources.fanclub.fanclub);
if (this.fanclub || (this.context && this.context.resources && this.context.resources.fanclub)) {
callback(null, this.fanclub || this.context.resources.fanclub.fanclub);
} else {
this.get('/fanclub', function(err, data) {
callback(err, data ? data.fanclub : null);
Expand All @@ -106,7 +106,10 @@ var getFanclub = function(callback) {

var getCustomer = function(callback) {
if (!this.useJWT || localStorage.getItem('universeAccessToken')) {
this.get('/account', function(err, data) {
// When logged in, add the login time to the /account query, to prevent the
// browser from serving a cached "logged out" response (and vice-versa)
this.get(localStorage.getItem('universeLoginTime') ? '/account?t=' + localStorage.getItem('universeLoginTime').toString() : '/account', function(err, data) {
if (!err && data && !data.customer) localStorage.removeItem('universeLoginTime');
callback(err, data ? data.customer : null);
});
} else {
Expand Down Expand Up @@ -159,6 +162,7 @@ var validateTokens = function(callback) {
// Valid access token
return callback();
} else {
// Missing or expired access token
localStorage.removeItem('universeAccessToken');
localStorage.removeItem('universeAccessTokenExpiration');
}
Expand All @@ -167,6 +171,7 @@ var validateTokens = function(callback) {
// Missing or expired refresh token
localStorage.removeItem('universeRefreshToken');
localStorage.removeItem('universeRefreshTokenExpiration');
localStorage.removeItem('universeLoginTime');
return callback(true);
}

Expand All @@ -178,6 +183,7 @@ var validateTokens = function(callback) {
// Invalid refresh token
localStorage.removeItem('universeRefreshToken');
localStorage.removeItem('universeRefreshTokenExpiration');
localStorage.removeItem('universeLoginTime');
}
callback(err);
} else {
Expand Down
2 changes: 2 additions & 0 deletions login/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ function linkify (fanclub, scope, processor, popup) {

if (url.match('login')) {
event.preventDefault();
localStorage.setItem('universeLoginTime', Date.now());
module.exports.prompt(fanclub, url, processor, popup);
} else if (url.match('logout')) {
localStorage.removeItem('universeAccessToken');
localStorage.removeItem('universeAccessTokenExpiration');
localStorage.removeItem('universeRefreshToken');
localStorage.removeItem('universeRefreshTokenExpiration');
localStorage.removeItem('universeLoginTime');
}
});
};
Expand Down
1 change: 1 addition & 0 deletions login/logout.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
localStorage.removeItem('universeAccessTokenExpiration');
localStorage.removeItem('universeRefreshToken');
localStorage.removeItem('universeRefreshTokenExpiration');
localStorage.removeItem('universeLoginTime');
var redirect = document.getElementById('redirect');
redirect.href = '{{{ fanclub.links.logout }}}' || '/';
Expand Down
1 change: 1 addition & 0 deletions login/logout.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
localStorage.removeItem('universeAccessTokenExpiration');
localStorage.removeItem('universeRefreshToken');
localStorage.removeItem('universeRefreshTokenExpiration');
localStorage.removeItem('universeLoginTime');

document.getElementById('redirect').click();

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "universe-js",
"version": "3.0.2",
"version": "3.0.3",
"main": "index.js",
"author": {
"name": "Joannic Laborde",
Expand Down
6 changes: 6 additions & 0 deletions test/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ module.exports.routes = function (req, res) {

if (req.method === 'OPTIONS') return success();

req.url = req.url.replace(/^\/api\/v1\/account\?t=\d+&key=12345$/, '/api/v1/account?t=54321&key=12345');

switch ((req.method + ' ' + req.url)
.replace(/solidus_client_jsonp_callback_\d+/, 'solidus_client_jsonp_callback')
.replace(/redirect=[^&#$]+/, 'redirect=')) {
Expand All @@ -84,6 +86,10 @@ module.exports.routes = function (req, res) {
success(logged_in ? {customer: 'me!'} : {});
break;

case 'GET /api/v1/account?t=54321&key=12345':
success(logged_in ? {customer: 'me! not cached'} : {});
break;

case 'POST /api/v1/account?key=12345':
var body = '';
req.on('data', function(data) {body += data;});
Expand Down
48 changes: 48 additions & 0 deletions test/tests/universe-js.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ describe('Universe', function() {
Math.random = random;
});

beforeEach(function() {
localStorage.removeItem('universeLoginTime');
})

afterEach(function() {
localStorage.removeItem('universeLoginTime');
});

describe('JWTs', function() {
beforeEach(login);
afterEach(logout);
Expand Down Expand Up @@ -79,6 +87,26 @@ describe('Universe', function() {
});
});

it('after a login state change', function(done) {
localStorage.setItem('universeLoginTime', Date.now());

var callbackCalled;
var universe = new Universe({environment: 'test', key: '12345'});
universe.init(function(err, data) {
assert.ifError(err);
assert.deepEqual(data, {fanclub: 'demo!', customer: 'me! not cached'});
callbackCalled = true;
});
universe.on('error', function(err) {
assert(false);
});
universe.on('ready', function(data) {
assert(callbackCalled);
assert.deepEqual(data, {fanclub: 'demo!', customer: 'me! not cached'});
done();
});
});

it('with no logged in customer', function(done) {
logout();
var universe = new Universe({environment: 'test', key: '12345'});
Expand Down Expand Up @@ -394,6 +422,26 @@ describe('Universe', function() {
});
});

it('after a login state change', function(done) {
localStorage.setItem('universeLoginTime', Date.now());

var callback_called;
var universe = new Universe({apiUrl: config.sameSiteUrlLoggedIn, key: '12345'});
universe.init(function(err, data) {
assert.ifError(err);
assert.deepEqual(data, {fanclub: 'demo!', customer: 'me! not cached'});
callback_called = true;
});
universe.on('error', function(err) {
assert(false);
});
universe.on('ready', function(data) {
assert(callback_called);
assert.deepEqual(data, {fanclub: 'demo!', customer: 'me! not cached'});
done();
});
});

it('with no logged in customer', function(done) {
var universe = new Universe({apiUrl: config.sameSiteUrlLoggedOut, key: '12345'});
universe.init(function(err, data) {
Expand Down
2 changes: 1 addition & 1 deletion universe-js.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Universe JS
* Plugin URI: https://github.com/sparkartgroup/universe-js
* Description: Javascript modules and PHP functions for interacting with Sparkart's Universe API.
* Version: 3.0.2
* Version: 3.0.3
* Author: Sparkart Group, Inc.
* Author URI: http://www.sparkart.com/
*/
Expand Down

0 comments on commit ca47a6c

Please sign in to comment.