Skip to content

Commit

Permalink
Merge pull request #28 from Financial-Times/use-next-session-proxy
Browse files Browse the repository at this point in the history
Use next session proxy
  • Loading branch information
ironsidevsquincy authored Mar 16, 2017
2 parents 594cff2 + dfe0db1 commit 3039a6d
Show file tree
Hide file tree
Showing 17 changed files with 188 additions and 283 deletions.
11 changes: 6 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.idea/
node_modules/
bower_components/
test/app/public/
.eslintrc.js
.editorconfig
.eslintrc.js

/.idea/
/bower_components/
/node_modules/
/test/app/public/
10 changes: 3 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
include n.Makefile

test: verify
karma start
unit-test:
karma start test/karma.conf.js

test-app:
rm -rf test/app/public/
mkdir test/app/public/
browserify test/app/main.js --debug --transform debowerify > test/app/public/bundle.js
node test/app/server.js
test: verify unit-test
6 changes: 1 addition & 5 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,5 @@
"bower_components",
"test",
"tests"
],
"devDpendencies": {
"fetch": "github/fetch#^0.9.0",
"es6-promise": "^2.1.0"
}
]
}
6 changes: 0 additions & 6 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
machine:
node:
version: 4.4.7
deployment:
release:
tag: /^v[0-9]+(.[0-9]+)*/
owner: Financial-Times
commands:
- make npm-publish
107 changes: 65 additions & 42 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,78 @@
'use strict';
const request = require('./src/request');
const cache = require('./src/cache');
const promises = {};

function uuid (){
const uuid = cache('uuid')

if (uuid){
return Promise.resolve({
uuid:uuid
});
import request from './src/request';
import cache from './src/cache';

const requests = {};

// DEPRECATED: use the secure session ID, via getSessionId
const getCookie = () => {
return (/FTSession=([^;]+)/.exec(document.cookie) || [null, ''])[1];
};

const getSessionId = () => {
const [, sessionId] = /FTSession_s=([^;]+)/.exec(document.cookie) || [];
return sessionId;
};

const getUuid = () => {
const cachedUUID = cache('uuid');
if (cachedUUID) {
return Promise.resolve({ uuid: cachedUUID });
}
if (!promises.uuid) {
promises.uuid = request('/uuid').then(function (response){
cache('uuid', response.uuid);
return response;
});

const sessionId = getSessionId();
if (!sessionId) {
return Promise.resolve({ uuid: undefined });
}

return promises.uuid;
}
if (!requests.uuid) {
requests.uuid = request(`/sessions/s/${sessionId}`)
.then(({ uuid } = {}) => {
delete requests.uuid;
if (uuid) {
cache('uuid', uuid);
}
return { uuid };
});
}

return requests.uuid;
};

function products () {
const getProducts = () => {
const cachedProducts = cache('products');
const cachedUUID = cache('uuid');

if(cachedProducts && cachedUUID){
return Promise.resolve({products:cachedProducts, uuid:cachedUUID});
if (cachedProducts && cachedUUID){
return Promise.resolve({ products: cachedProducts, uuid: cachedUUID });
}

if (!promises.products) {
promises.products = request('/products').then(function (response) {
cache('products', response.products);
cache('uuid', response.uuid);
return response;
});
if (!requests.products) {
requests.products = request('/products', { credentials: 'include' })
.then(({ products, uuid } = {}) => {
delete requests.products;
if (products) {
cache('uuid', uuid);
}
if (uuid) {
cache('uuid', uuid);
}
return { products, uuid };
});
}

return promises.products;
}
return requests.products;
};

function validate () {
return request('/validate');
}
// DEPRECATED: use getUuid, will only return a uuid if session is valid
const validate = () => {
return getUuid()
.then(({ uuid }) => uuid ? true : false);
};

module.exports = {
uuid : uuid,
validate : validate,
cache : cache,
products: products,
cookie : function () {
return (/FTSession=([^;]+)/.exec(document.cookie) || [null, ''])[1];
}
export default {
uuid: getUuid,
products: getProducts,
validate,
cache,
cookie: getCookie,
sessionId: getSessionId
};
4 changes: 3 additions & 1 deletion n.Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ endif
# Enforce repo ownership
ifeq ("$(wildcard ft.yml)","")
$(error 'Projects making use of n-makefile *must* define an ft.yml file containing the repo owner's details (see any next- repo for required structure)')
$(error 'If you are creating a project not to be maintained by the next team please feel free to copy what you need from our build tools but don't add an ft.yml.')
$(error 'Integrating with our tooling may result in unwanted effects e.g. nightly builds, slack alerts, emails etc')
endif

# ./node_modules/.bin on the PATH
Expand All @@ -28,7 +30,7 @@ NPM_INSTALL = npm prune --production=false && npm install
BOWER_INSTALL = bower prune && bower install --config.registry.search=http://registry.origami.ft.com --config.registry.search=https://bower.herokuapp.com
JSON_GET_VALUE = grep $1 | head -n 1 | sed 's/[," ]//g' | cut -d : -f 2
IS_GIT_IGNORED = grep -q $(if $1, $1, $@) .gitignore
VERSION = v14
VERSION = v15
APP_NAME = $(shell cat package.json 2>/dev/null | $(call JSON_GET_VALUE,name))
DONE = echo ✓ $@ done
CONFIG_VARS = curl -fsL https://ft-next-config-vars.herokuapp.com/$1/$(call APP_NAME)$(if $2,.$2,) -H "Authorization: `heroku config:get APIKEY --app ft-next-config-vars`"
Expand Down
34 changes: 18 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,25 @@
},
"homepage": "https://github.com/Financial-Times/next-session-component",
"devDependencies": {
"babel-loader": "^6.4.0",
"babel-preset-es2015": "^6.24.0",
"bower": "^1.7.9",
"browserify": "^10.1.3",
"chai": "^2.3.0",
"debowerify": "^1.2.1",
"eslint": "^3.0.1",
"chai": "^3.0.0",
"eslint": "^3.16.1",
"express": "^4.12.3",
"fetch-mock": "^1.4.1",
"isomorphic-fetch": "^2.0.2",
"karma": "^0.12.31",
"karma-browserify": "^4.1.2",
"karma-chrome-launcher": "^0.1.10",
"karma-mocha": "^0.1.10",
"karma-phantomjs-launcher": "^0.1.4",
"lintspaces-cli": "^0.4.0",
"mocha": "^2.2.4",
"npm-prepublish": "^1.2.1",
"origami-build-tools": "^2.13.0",
"sinon": "^1.14.1"
"karma": "^1.5.0",
"karma-chai": "^0.1.0",
"karma-cli": "^1.0.1",
"karma-firefox-launcher": "^1.0.0",
"karma-mocha": "^1.3.0",
"karma-sinon": "^1.0.5",
"karma-webpack": "^2.0.3",
"lintspaces-cli": "^0.6.0",
"mocha": "^3.2.0",
"sinon": "^1.14.1",
"webpack": "^2.2.1"
},
"engines": {
"node": "4.4.7"
}
}
17 changes: 7 additions & 10 deletions src/cache.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
'use strict';

let detailsCache = {};


function cache (name, value) {
if(typeof name === 'object'){
const cache = (name, value) => {
if (typeof name === 'object'){
detailsCache = name;
return;
}

if(typeof name === 'string' && typeof value === 'string') {
if (typeof name === 'string' && typeof value === 'string') {
detailsCache[name] = value;
return;
}

if(typeof name === 'string' && typeof value === 'undefined') {
if (typeof name === 'string' && typeof value === 'undefined') {
return detailsCache[name] || null;
}

if(typeof name === 'undefined' && typeof value === 'undefined') {
if (typeof name === 'undefined' && typeof value === 'undefined') {
return detailsCache;
}

throw new Error('Invalid arguments');
}

cache.clear = function () {
cache.clear = () => {
detailsCache = {};
};

module.exports = cache;
export default cache;
45 changes: 17 additions & 28 deletions src/request.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,27 @@
'use strict';

function request (url) {
// if we don't have a session token cookie, don't bother..
if (document.cookie.indexOf('FTSession=') === -1) {
return Promise.reject(new Error('No session cookie found'));
}

export default (url, { credentials = 'omit' } = {}) => {
return fetch(`https://session-next.ft.com${url}`, {
credentials:'include',
credentials,
useCorsProxy: true
}).then(function (response) {
if (response.ok){
return (url === '/validate') ? Promise.resolve(true) : response.json();
} else {
return (url === '/validate') ? Promise.resolve(false) : Promise.reject(response.status);
}

}).catch(function (e) {
const message = e.message || '';
if (message.indexOf('timed out') > -1 || message.indexOf('Network request failed') > -1 || message.indexOf('Not Found') > -1) {
// HTTP timeouts and invalid sessions are a fact of life on the internet.
// We don't want to report this to Sentry.
} else {
})
.then(response => {
if (response.ok){
return response.json();
} else {
return response.text()
.then(text => {
throw new Error(`Next session responded with "${text}" (${response.status})`);
});
}
})
.catch(err => {
document.body.dispatchEvent(new CustomEvent('oErrors.log', {
bubbles: true,
detail: {
error: e,
error: err,
info: {
component: 'next-session-client'
}
}
}))
}
});
}));
});
}

module.exports = request;
22 changes: 0 additions & 22 deletions test/app/index.html

This file was deleted.

33 changes: 0 additions & 33 deletions test/app/main.js

This file was deleted.

16 changes: 0 additions & 16 deletions test/app/server.js

This file was deleted.

Loading

0 comments on commit 3039a6d

Please sign in to comment.