forked from liferay/liferay-frontend-projects
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request liferay#1008 from tinycarol/IFI-3334
feat(eslint-plugin): add ESLint rule to prevent usage of document.cookie
- Loading branch information
Showing
6 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
projects/eslint-plugin/rules/portal/docs/rules/no-document-cookie.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Disallow use of document.cookie (no-document-cookie) | ||
|
||
This rule guards against the direct use of the global cookie API in `document.cookie`. To comply with data protection regulations, Liferay users can disable the storage of data that is not fundamental for the main purpose of the site to work, and that applies to cookies. Both the global Liferay object and the `frontend-js-web` module offer a thin wrapper around this API with added user consent enforcement. | ||
|
||
## Rule Details | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```js | ||
function doSomething(name) { | ||
return document.cookie | ||
.split('; ') | ||
.find((v) => v.startsWith(name)) | ||
?.split('=')[0]; | ||
} | ||
|
||
function doSomethingElse(name, value) { | ||
document.cookie += `${name}=${value}`; | ||
} | ||
``` | ||
Examples of **correct** code for this rule: | ||
```js | ||
import {getCookie, setCookie, COOKIE_TYPES} from 'frontend-js-web'; | ||
|
||
function doSomething(name) { | ||
return getCookie(name, COOKIE_TYPES.NECESSARY); | ||
} | ||
|
||
function doSomethingElse(name, value, expires) { | ||
return setCookie(name, value, COOKIE_TYPES.FUNCTIONAL, {expires}); | ||
} | ||
|
||
function doSomethingOther(name, value) { | ||
return Liferay.Util.Cookie.set( | ||
name, | ||
value, | ||
Liferay.Util.Cookie.TYPES.PERSONALIZATION | ||
); | ||
} | ||
``` | ||
## Further Reading | ||
- [LPS-151966 Create a JS API for cookie management, which enforces user's consent](https://issues.liferay.com/browse/LPS-151966) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
projects/eslint-plugin/rules/portal/lib/rules/no-document-cookie.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* SPDX-FileCopyrightText: © 2017 Liferay, Inc. <https://liferay.com> | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
const DESCRIPTION = | ||
'Direct usage of `document.cookie` is discouraged in favour of our wrapped version that checks user consent status; import `[get|set|remove]Cookie` from frontend-js-web instead or use the global `Liferay.Util.Cookie`.'; | ||
|
||
module.exports = { | ||
create(context) { | ||
const isDocumentCookie = (node) => | ||
node.object.name === 'document' && node.property.name === 'cookie'; | ||
|
||
return { | ||
MemberExpression(node) { | ||
if (isDocumentCookie(node)) { | ||
context.report({ | ||
messageId: 'noDocumentCookie', | ||
node, | ||
}); | ||
} | ||
}, | ||
}; | ||
}, | ||
|
||
meta: { | ||
docs: { | ||
category: 'Best Practices', | ||
description: DESCRIPTION, | ||
recommended: false, | ||
url: 'https://issues.liferay.com/browse/IFI-3334', | ||
}, | ||
fixable: null, | ||
messages: { | ||
noDocumentCookie: DESCRIPTION, | ||
}, | ||
schema: [], | ||
type: 'problem', | ||
}, | ||
}; |
78 changes: 78 additions & 0 deletions
78
projects/eslint-plugin/rules/portal/tests/lib/rules/no-document-cookie.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* SPDX-FileCopyrightText: © 2017 Liferay, Inc. <https://liferay.com> | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
const MultiTester = require('../../../../../scripts/MultiTester'); | ||
const rule = require('../../../lib/rules/no-document-cookie'); | ||
|
||
const parserOptions = { | ||
parserOptions: { | ||
ecmaVersion: 6, | ||
sourceType: 'module', | ||
}, | ||
}; | ||
|
||
const ruleTester = new MultiTester(parserOptions); | ||
|
||
ruleTester.run('no-document-cookie', rule, { | ||
invalid: [ | ||
{ | ||
|
||
// Assignment expression. | ||
|
||
code: ` | ||
function doSomething(name, value) { | ||
return document.cookie = \`\${name}=\${value}\`; | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'noDocumentCookie', | ||
type: 'MemberExpression', | ||
}, | ||
], | ||
}, | ||
{ | ||
|
||
// Property access expression. | ||
|
||
code: ` | ||
function doSomething() { | ||
return document.cookie.split(";").length; | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'noDocumentCookie', | ||
type: 'MemberExpression', | ||
}, | ||
], | ||
}, | ||
], | ||
|
||
valid: [ | ||
{ | ||
|
||
// Named import from frontend-js-web | ||
|
||
code: ` | ||
import {setCookie, COOKIE_TYPES} from 'frontend-js-web'; | ||
function doSomething() { | ||
return setCookie("name", "value", COOKIE_TYPES.NECESSARY); | ||
} | ||
`, | ||
}, | ||
{ | ||
|
||
// Namespaced from Liferay.Util | ||
|
||
code: ` | ||
function doSomething() { | ||
return Liferay.Util.Cookie.set("name", "value", Liferay.Util.Cookie.TYPES.PERFORMANCE); | ||
} | ||
`, | ||
}, | ||
], | ||
}); |