Skip to content

Commit 364866b

Browse files
committed
added optional disableCookieDomain parameter (awslabs#10)
* add disable cookie domain attribute as optional - in case app needs to exclude domain attribute which is more restrictive (ie. not allow subdomains) - defaults to false to maintain backwards compatibility (ie. include domain if false or not specified). * add (Optional) to the disableCookieDomain param documentation
1 parent 4601d2b commit 364866b

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ For an explanation of the interactions between CloudFront, Cognito and Lambda@Ed
5555
* `userPoolAppSecret` *string* (Optional) Cognito UserPool Application Secret (eg: `oh470px2i0uvy4i2ha6sju0vxe4ata9ol3m63ufhs2t8yytwjn7p`)
5656
* `userPoolDomain` *string* Cognito UserPool domain (eg: `your-domain.auth.us-east-1.amazoncognito.com`)
5757
* `cookieExpirationDays` *number* (Optional) Number of day to set cookies expiration date, default to 365 days (eg: `365`)
58+
* `disableCookieDomain` *boolean* (Optional) Sets domain attribute in cookies, defaults to false (eg: `false`)
5859
* `logLevel` *string* (Optional) Logging level. Default: `'silent'`. One of `'fatal'`, `'error'`, `'warn'`, `'info'`, `'debug'`, `'trace'` or `'silent'`.
5960

6061
*This is the class constructor.*

__tests__/index.test.js

+49
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe('private functions', () => {
2525
userPoolAppId: '123456789qwertyuiop987abcd',
2626
userPoolDomain: 'my-cognito-domain.auth.us-east-1.amazoncognito.com',
2727
cookieExpirationDays: 365,
28+
disableCookieDomain: false,
2829
logLevel: 'error',
2930
});
3031
});
@@ -97,6 +98,43 @@ describe('private functions', () => {
9798
expect(authenticator._getVerifiedToken).toHaveBeenCalled();
9899
});
99100

101+
test('should not return cookie domain', () => {
102+
const authenticatorWithNoCookieDomain = new Authenticator({
103+
region: 'us-east-1',
104+
userPoolId: 'us-east-1_abcdef123',
105+
userPoolAppId: '123456789qwertyuiop987abcd',
106+
userPoolDomain: 'my-cognito-domain.auth.us-east-1.amazoncognito.com',
107+
cookieExpirationDays: 365,
108+
disableCookieDomain: true,
109+
logLevel: 'error',
110+
});
111+
112+
const username = 'toto';
113+
const domain = 'example.com';
114+
const path = '/test';
115+
jest.spyOn(authenticatorWithNoCookieDomain, '_getVerifiedToken');
116+
authenticatorWithNoCookieDomain._getVerifiedToken.mockReturnValueOnce({ token_use: 'id', 'cognito:username': username });
117+
118+
const response = authenticatorWithNoCookieDomain._getRedirectResponse(tokenData, domain, path);
119+
expect(response).toMatchObject({
120+
status: '302',
121+
headers: {
122+
location: [{
123+
key: 'Location',
124+
value: path,
125+
}],
126+
},
127+
});
128+
expect(response.headers['set-cookie']).toEqual(expect.arrayContaining([
129+
{key: 'Set-Cookie', value: `CognitoIdentityServiceProvider.123456789qwertyuiop987abcd.${username}.accessToken=${tokenData.access_token}; Expires=${DATE}; Secure`},
130+
{key: 'Set-Cookie', value: `CognitoIdentityServiceProvider.123456789qwertyuiop987abcd.${username}.refreshToken=${tokenData.refresh_token}; Expires=${DATE}; Secure`},
131+
{key: 'Set-Cookie', value: `CognitoIdentityServiceProvider.123456789qwertyuiop987abcd.${username}.tokenScopesString=phone email profile openid aws.cognito.signin.user.admin; Expires=${DATE}; Secure`},
132+
{key: 'Set-Cookie', value: `CognitoIdentityServiceProvider.123456789qwertyuiop987abcd.${username}.idToken=${tokenData.id_token}; Expires=${DATE}; Secure`},
133+
{key: 'Set-Cookie', value: `CognitoIdentityServiceProvider.123456789qwertyuiop987abcd.LastAuthUser=${username}; Expires=${DATE}; Secure`},
134+
]));
135+
expect(authenticatorWithNoCookieDomain._getVerifiedToken).toHaveBeenCalled();
136+
});
137+
100138
test('should getIdTokenFromCookie', () => {
101139
const appClientName = 'toto,./;;..-_lol123';
102140
expect(
@@ -124,6 +162,7 @@ describe('createAuthenticator', () => {
124162
userPoolAppId: '123456789qwertyuiop987abcd',
125163
userPoolDomain: 'my-cognito-domain.auth.us-east-1.amazoncognito.com',
126164
cookieExpirationDays: 365,
165+
disableCookieDomain: true
127166
};
128167
});
129168

@@ -136,6 +175,11 @@ describe('createAuthenticator', () => {
136175
expect(typeof new Authenticator(params)).toBe('object');
137176
});
138177

178+
test('should create authenticator without disableCookieDomain', () => {
179+
delete params.disableCookieDomain;
180+
expect(typeof new Authenticator(params)).toBe('object');
181+
});
182+
139183
test('should fail when creating authenticator without params', () => {
140184
expect(() => new Authenticator()).toThrow('Expected params');
141185
expect(() => new Authenticator()).toThrow('Expected params');
@@ -185,6 +229,11 @@ describe('createAuthenticator', () => {
185229
params.cookieExpirationDays = '123';
186230
expect(() => new Authenticator(params)).toThrow('cookieExpirationDays');
187231
});
232+
233+
test('should fail when creating authenticator with invalid disableCookieDomain', () => {
234+
params.disableCookieDomain = '123';
235+
expect(() => new Authenticator(params)).toThrow('disableCookieDomain');
236+
});
188237
});
189238

190239
describe('handle', () => {

index.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Authenticator {
1414
this._userPoolAppSecret = params.userPoolAppSecret;
1515
this._userPoolDomain = params.userPoolDomain;
1616
this._cookieExpirationDays = params.cookieExpirationDays || 365;
17-
17+
this._disableCookieDomain = ('disableCookieDomain' in params && params.disableCookieDomain === true) ? true : false;
1818
this._issuer = `https://cognito-idp.${params.region}.amazonaws.com/${params.userPoolId}`;
1919
this._cookieBase = `CognitoIdentityServiceProvider.${params.userPoolAppId}`;
2020
this._logger = pino({
@@ -40,6 +40,9 @@ class Authenticator {
4040
if (params.cookieExpirationDays && typeof params.cookieExpirationDays !== 'number') {
4141
throw new Error('Expected params.cookieExpirationDays to be a number');
4242
}
43+
if ('disableCookieDomain' in params && typeof params.disableCookieDomain !== 'boolean') {
44+
throw new Error('Expected params.disableCookieDomain to be a boolean');
45+
}
4346
}
4447

4548
/**
@@ -120,8 +123,9 @@ class Authenticator {
120123
const decoded = this._getVerifiedToken(tokens.id_token);
121124
const username = decoded['cognito:username'];
122125
const usernameBase = `${this._cookieBase}.${username}`;
123-
const directives = `Domain=${domain}; Expires=${new Date(new Date() * 1 + this._cookieExpirationDays * 864e+5)}; Secure`;
124-
126+
const directives = (!this._disableCookieDomain) ?
127+
`Domain=${domain}; Expires=${new Date(new Date() * 1 + this._cookieExpirationDays * 864e+5)}; Secure` :
128+
`Expires=${new Date(new Date() * 1 + this._cookieExpirationDays * 864e+5)}; Secure`;
125129
const response = {
126130
status: '302' ,
127131
headers: {

0 commit comments

Comments
 (0)