Skip to content

Commit 703434f

Browse files
committed
Added SessionPluginExample sources
1 parent d9bad84 commit 703434f

File tree

5 files changed

+181
-0
lines changed

5 files changed

+181
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Collection of plugins for use in your [L³](https://github.com/lambda-lambda-lam
1515
| [ContentTypeJsonHeader](https://github.com/lambda-lambda-lambda/middleware/tree/master/plugins/ContentTypeJsonHeader) | Middleware to send JSON `Content-Type` header. |
1616
| [GoogleRecaptchaHandler](https://github.com/lambda-lambda-lambda/middleware/tree/master/plugins/GoogleRecaptchaHandler) | Middleware to validate [Google ReCAPTCHA invisible](https://developers.google.com/recaptcha/docs/invisible) responses. |
1717
| [PreflightOptionsHandler](https://github.com/lambda-lambda-lambda/middleware/tree/master/plugins/PreflightOptionsHandler) | Middleware to handle [preflight requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS). |
18+
| [SessionPluginExample](https://github.com/lambda-lambda-lambda/middleware/tree/master/plugins/SessionPluginExample) | Middleware example of validating a session that uses cookies. |
1819
| [SwaggerUIViewer](https://github.com/lambda-lambda-lambda/middleware/tree/master/plugins/SwaggerUIViewer) | Middleware to generate [Swagger UI](https://swagger.io/tools/swagger-ui) viewer. |
1920

2021
## Installation
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# SessionPluginExample
2+
3+
Middleware example of validating a session that uses cookies.
4+
5+
## Installation
6+
7+
See package [README](https://github.com/lambda-lambda-lambda/middleware#manual-installation) for instructions.
8+
9+
### app.js
10+
11+
```javascript
12+
const sessionPlugin = require(`${APP_ROOT}/middleware/SessionPluginExample`);
13+
14+
router.use(sessionPlugin({
15+
cookieName: 'SESSIONID',
16+
validator: (token) => {
17+
18+
// Check token using conventional method; Return session values.
19+
const customValidator = (token) => ({role: 'user', status: 'active', foo: 'bar'});
20+
const sessionData = customValidator(token);
21+
22+
if (!sessionData) {
23+
throw Error(`Invalid session: ${token}`);
24+
}
25+
26+
return sessionData;
27+
}
28+
}));
29+
```
30+
31+
## Usage
32+
33+
```javascript
34+
module.exports = (req, res) => {
35+
const cookie = req.plugin('cookies');
36+
// SESSIONID=<token>
37+
38+
const session = req.plugin('session');
39+
// {role: 'user', status: 'active', foo: 'bar'}
40+
};
41+
```
42+
43+
## References
44+
45+
- [lambda-lambda-lambda](https://github.com/lambda-lambda-lambda)

plugins/SessionPluginExample/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./src/plugin');
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
const {RouterError} = require('@lambda-lambda-lambda/router/src/router/Error');
4+
5+
/**
6+
* Middleware example of validating a session that uses cookies.
7+
*
8+
* @requires CookieParserPlugin
9+
*/
10+
module.exports = ({cookieName, validator}) => {
11+
return async (req, res, next) => {
12+
if (cookieName && typeof validator === 'function') {
13+
try {
14+
const cookies = req.plugin('cookies');
15+
const token = cookies[cookieName];
16+
token && req.plugin('session', await validator(token));
17+
18+
} catch {
19+
// Continue as "anonymous" user.
20+
}
21+
22+
} else {
23+
throw new RouterError('Invalid session options');
24+
}
25+
};
26+
};
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
'use strict';
2+
3+
const event = require(`${PACKAGE_ROOT}/event.json`);
4+
const chai = require('chai');
5+
const chaiAsPromised = require('chai-as-promised');
6+
7+
chai.use(chaiAsPromised);
8+
9+
const expect = chai.expect;
10+
11+
// Load modules.
12+
const {
13+
RouterError,
14+
Request,
15+
Response,
16+
Stack,
17+
Utils
18+
} = require('@lambda-lambda-lambda/router/exports');
19+
20+
const middleware = require(PLUGIN_ROOT);
21+
22+
describe('SessionPlugin', function() {
23+
const stack = new Stack();
24+
25+
describe('success', function() {
26+
const settings = {
27+
cookieName: 'SESSIONID',
28+
validator: (token) => ({role: 'user', status: 'active', foo: 'bar'})
29+
};
30+
31+
const dependency = function(req, res, next) {
32+
req.plugin('cookies', {[settings.cookieName]: 'abcdefghijklmnopqrstuvwxyz123456'});
33+
next();
34+
};
35+
36+
Utils.setFuncName(dependency, 'middleware');
37+
Utils.setFuncName(middleware, 'middleware');
38+
39+
const route = async function(req, res, next) {
40+
res.status(200).send();
41+
};
42+
43+
Utils.setFuncName(route, 'route:index');
44+
45+
stack.middleware = [dependency, middleware(settings)];
46+
stack.routes = route;
47+
48+
// Define form POST parameters.
49+
event.Records[0].cf.request.method = 'GET';
50+
event.Records[0].cf.request.uri = '/path/to/resource';
51+
event.Records[0].cf.request.body = {
52+
data: Buffer.from('')
53+
.toString('base64')
54+
};
55+
56+
const req = new Request(event.Records[0].cf.request, {});
57+
const res = new Response({});
58+
59+
stack.exec(req, res);
60+
61+
const result = res.data();
62+
63+
it('should not return headers', function() {
64+
expect(result.headers).to.be.empty;
65+
});
66+
67+
it('should return status', function() {
68+
expect(result.status).to.equal(200);
69+
});
70+
71+
it('should not return body', function() {
72+
expect(result.body).to.be.undefined;
73+
});
74+
});
75+
76+
describe('error', function() {
77+
const settings = {
78+
cookieName: '',
79+
validator: (token) => (true)
80+
};
81+
82+
const dependency = function(req, res, next) {
83+
req.plugin('cookies', {SESSIONID: 'abcdefghijklmnopqrstuvwxyz123456'});
84+
next();
85+
};
86+
87+
Utils.setFuncName(dependency, 'middleware');
88+
Utils.setFuncName(middleware, 'middleware');
89+
90+
const route = async function(req, res, next) {
91+
res.status(200).send();
92+
};
93+
94+
Utils.setFuncName(route, 'route:index');
95+
96+
stack.middleware = [dependency, middleware(settings)];
97+
stack.routes = route;
98+
99+
const req = new Request(event.Records[0].cf.request, {});
100+
const res = new Response({});
101+
102+
it('should throw RouterError', function() {
103+
const result = stack.exec(req, res);
104+
105+
expect(result).to.be.rejectedWith(RouterError, /Invalid session options/);
106+
});
107+
});
108+
});

0 commit comments

Comments
 (0)