Skip to content

Commit ac6b038

Browse files
author
Patrick Brandt
committed
refactoring code and improving order of operations for refreshSession
1 parent a08896c commit ac6b038

File tree

7 files changed

+114
-26
lines changed

7 files changed

+114
-26
lines changed

lambda_functions/deleteSession/deleteSession.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ module.exports = function(event, context, cb) {
2121
.catch(err => {
2222
log.error(log);
2323
cb(null, response.genericError());
24-
})
24+
});
2525
};

lambda_functions/deleteSession/deleteSession.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('deleteSession', function() {
1616
this.deleteSession = proxyquire('./deleteSession', {
1717
'../../lib/log': testHelper.mockLog,
1818
'../../lib/db': this.dbMock
19-
})
19+
});
2020
});
2121

2222
afterEach(function() {
@@ -30,7 +30,7 @@ describe('deleteSession', function() {
3030
let body = JSON.parse(data.body);
3131
testHelper.check(done, () => {
3232
assert(this.dbMock.deleteTokens.calledOnce, 'db.deleteTokens must be called');
33-
assert(this.dbMock.deleteTokens.calledWith(rt))
33+
assert(this.dbMock.deleteTokens.calledWith(rt));
3434
expect(err).is.null;
3535
expect(data.statusCode).to.equal(200);
3636
expect(body.message).to.equal('session ended');

lambda_functions/refreshSession/refreshSession.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ var token = require('../../lib/token');
99
var authorization = require('../../lib/authorization');
1010
var constants = require('../../lib/constants');
1111
var config = require(`../../config/${process.env.NODE_ENV}.json`);
12+
var bb = require('bluebird');
1213

1314
module.exports = function(event, context, cb) {
1415
let body = JSON.parse(event.body);
@@ -28,6 +29,82 @@ module.exports = function(event, context, cb) {
2829
}));
2930
}
3031

32+
token.parseAuthorizationHeader(event.headers.Authorization)
33+
.then(parsedToken => {
34+
bb.join(token.getTimeRemaining(parsedToken, secret),
35+
token.getTimeRemaining(body.refresh_token, secret),
36+
(at_timeRemaining, rt_timeRemaining) => {
37+
return {
38+
at_timeRemaining: at_timeRemaining,
39+
rt_timeRemaining: rt_timeRemaining
40+
}
41+
})
42+
.then(times => {
43+
db.getTokens(body.refresh_token)
44+
.then(item => {
45+
if (!item) {
46+
return cb(null, response.create(401, {
47+
message: 'session no longer exists'
48+
}));
49+
}
50+
51+
if(!times.rt_timeRemaining) {
52+
log.info(`expired refresh_token: ${body.refresh_token}`);
53+
return cb(null, response.create(401, {
54+
message: 'refresh_token is expired'
55+
}));
56+
}
57+
58+
if(parsedToken !== item.AccessToken) {
59+
return cb(null, response.create(401, {
60+
message: 'can only refresh most recently expired access token'
61+
}));
62+
}
63+
64+
if(times.at_timeRemaining) {
65+
return cb(null, response.create(200,
66+
{
67+
access_token: parsedToken,
68+
refresh_token: body.refresh_token,
69+
access_token_expires_in: times.at_timeRemaining
70+
}));
71+
}
72+
73+
let userId = jwt.decode(body.refresh_token).sub;
74+
let access_token = token.createAccessToken(userId, clientId, event.requestContext.apiId, config.AccessTokenExpiration);
75+
db.saveTokens(body.refresh_token, access_token, userId, clientId)
76+
.then(() => {
77+
return cb(null, response.create(200,
78+
{
79+
access_token: access_token,
80+
refresh_token: body.refresh_token,
81+
access_token_expires_in: jwt.decode(access_token).exp - Math.floor(Date.now() / 1000)
82+
}));
83+
})
84+
.catch(err => {
85+
log.error(err);
86+
return cb(null, response.genericError());
87+
});
88+
})
89+
.catch(err => {
90+
log.error(err);
91+
return cb(null, response.genericError());
92+
});
93+
})
94+
.catch(err => {
95+
log.error(err);
96+
return cb(null, response.genericError());
97+
});
98+
})
99+
.catch(err => {
100+
log.error(err);
101+
cb(null, response.create(500,
102+
{
103+
name: err.name,
104+
message: err.message
105+
}));
106+
});
107+
/*
31108
//TODO: nested promises need some cleanup - maybe bluebird:
32109
//Promise.join(token.getTimeRemaining(parsedToken, secret), token.getTimeRemaining(body.refresh_token, secret),
33110
// (at_timeRemaining, rt_timeRemaining) => { })
@@ -109,4 +186,5 @@ module.exports = function(event, context, cb) {
109186
message: err.message
110187
}));
111188
});
189+
*/
112190
};

lambda_functions/refreshSession/refreshSession.test.js

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@ describe('refreshSession', function() {
3131
return event;
3232
};
3333

34+
this.createDbMock = (event) => {
35+
let access_token = event.headers[constants.AUTHORIZATION_HEADER].split(' ')[1];
36+
let eventBody = JSON.parse(event.body);
37+
let refresh_token = eventBody.refresh_token;
38+
let dbMock = {
39+
getTokens: () => Promise.resolve({
40+
AccessToken: access_token,
41+
IssuedAt: jwt.decode(refresh_token).iat,
42+
SessionCreatedAt: jwt.decode(refresh_token).iat,
43+
ExpiresAt: jwt.decode(refresh_token).exp,
44+
ClientId: this.clientId,
45+
RefreshToken: refresh_token,
46+
PrincipalId: this.userId
47+
}),
48+
saveTokens: () => Promise.resolve()
49+
};
50+
51+
return dbMock;
52+
}
53+
3454
this.refreshToken = (dbMock) => {
3555
return proxyquire('./refreshSession', {
3656
'../../lib/log': testHelper.mockLog,
@@ -47,7 +67,7 @@ describe('refreshSession', function() {
4767
let event = this.createEvent(true, true);
4868
let eventBody = JSON.parse(event.body);
4969
let access_token = event.headers[constants.AUTHORIZATION_HEADER].split(' ')[1];
50-
this.refreshToken()(event, {}, (err, data) => {
70+
this.refreshToken(this.createDbMock(event))(event, {}, (err, data) => {
5171
let body = JSON.parse(data.body);
5272
testHelper.check(done, () => {
5373
expect(err).to.be.null;
@@ -61,23 +81,10 @@ describe('refreshSession', function() {
6181

6282
it('should create new access_token if current access_token is expired', function(done) {
6383
let event = this.createEvent(false, true);
64-
let eventBody = JSON.parse(event.body);
84+
let eventBody = JSON.parse(event.body);
6585
let access_token = event.headers[constants.AUTHORIZATION_HEADER].split(' ')[1];
66-
let refresh_token = eventBody.refresh_token;
67-
let dbMock = {
68-
getTokens: () => Promise.resolve({
69-
AccessToken: access_token,
70-
IssuedAt: jwt.decode(refresh_token).iat,
71-
SessionCreatedAt: jwt.decode(refresh_token).iat,
72-
ExpiresAt: jwt.decode(refresh_token).exp,
73-
ClientId: this.clientId,
74-
RefreshToken: refresh_token,
75-
PrincipalId: this.userId
76-
}),
77-
saveTokens: () => Promise.resolve()
78-
};
7986

80-
this.refreshToken(dbMock)(event, {}, (err, data) => {
87+
this.refreshToken(this.createDbMock(event))(event, {}, (err, data) => {
8188
let body = JSON.parse(data.body);
8289
testHelper.check(done, () => {
8390
expect(err).to.be.null;
@@ -146,7 +153,7 @@ describe('refreshSession', function() {
146153

147154
it('should return 401 for expired refresh_token', function(done) {
148155
let event = this.createEvent(false, false);
149-
this.refreshToken()(event, {}, (err, data) => {
156+
this.refreshToken(this.createDbMock(event))(event, {}, (err, data) => {
150157
let body = JSON.parse(data.body);
151158
testHelper.check(done, () => {
152159
expect(err).to.be.null;
@@ -168,5 +175,4 @@ describe('refreshSession', function() {
168175
});
169176
});
170177
});
171-
172178
});

lib/db.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,10 @@ module.exports = {
127127

128128
docClient.get(params, (err, data) => {
129129
if (err) return reject(err);
130-
let isEmpty = Object.keys(data.Item).length === 0 && data.Item.constructor === Object;
131-
resolve(isEmpty ? undefined : data.Item);
130+
console.log(`data: ${JSON.stringify(data)}`);
131+
//let isEmpty = !data.Item; //Object.keys(data.Item).length === 0 && data.Item.constructor === Object;
132+
//resolve(isEmpty ? undefined : data.Item);
133+
resolve(data.Item);
132134
});
133135
});
134136
},
@@ -140,6 +142,7 @@ module.exports = {
140142
};
141143

142144
docClient.delete(params, (err, data) => {
145+
console.log(`data: ${JSON.stringify(data)}`);
143146
if (err) return reject(err);
144147
resolve(data);
145148
});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"yamljs": "^0.2.8"
3939
},
4040
"dependencies": {
41+
"bluebird": "^3.4.6",
4142
"bunyan": "^1.8.1",
4243
"jsonwebtoken": "^7.1.9",
4344
"node-forge": "^0.6.43",

serverless.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ functions:
7979
path: session
8080
method: DELETE
8181
authorizer:
82-
name: authorizer
83-
resultTtlInSeconds: 3
84-
identitySource: method.request.header.Authorization
82+
name: clientIdAuthorizer
83+
resultTtlInSeconds: 300
84+
identitySource: method.request.header.x-koms-clientid
8585
createUser:
8686
handler: handler.createUser
8787
events:

0 commit comments

Comments
 (0)