Skip to content
This repository has been archived by the owner on Sep 30, 2020. It is now read-only.

Commit

Permalink
Merge pull request #62 from jbalsas/feat/no-global-fetch
Browse files Browse the repository at this point in the history
feat: adds no-global-fetch rule to avoid direct usage of fetch in favour of our thin wrapper
  • Loading branch information
wincent authored Aug 12, 2019
2 parents 5a7c1c7 + 7a9d29a commit a21c78f
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ The bundled `eslint-plugin-liferay` plugin includes the following [rules](./plug

The bundled `eslint-plugin-liferay-portal` plugin includes the following [rules](./plugins/eslint-plugin-liferay-portal/docs/rules):

- [liferay-portal/no-global-fetch](./plugins/eslint-plugin-liferay-portal/docs/rules/no-global-fetch.md): Prevents usage of unwrapped fetch to avoid possible issues related to security misconfiguration.
- [liferay-portal/no-explicit-extend](./plugins/eslint-plugin-liferay-portal/docs/rules/no-explicit-extend.md): Prevents unnecessary `extends: ["liferay/portal"]` configuration.
- [liferay-portal/no-metal-plugins](./plugins/eslint-plugin-liferay-portal/docs/rules/no-metal-plugins.md): Prevents usage of deprecated `metal-*` plugins and utilities.
- [liferay-portal/no-side-navigation](./plugins/eslint-plugin-liferay-portal/docs/rules/no-side-navigation.md): Guards against the use of the legacy jQuery `sideNavigation` plugin.
Expand Down
49 changes: 49 additions & 0 deletions plugins/eslint-plugin-liferay-portal/docs/rules/no-global-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Disallow use of global fetch (no-global-fetch)

This rule guards against the direct use of the `fetch` API. As a secured-environment, Liferay Portal requests often rely on specific security headers and tokens being set in the requests. The `frontend-js-web` module offers a thin wrapper around `fetch` that takes care of the most common configuration to avoid issues.

## Rule Details

Examples of **incorrect** code for this rule:

```js
function doSomething(url) {
return fetch(foo);
}
```

Examples of **correct** code for this rule:

```js
import {fetch} from 'frontend-js-web';

function doSomething(url) {
return fetch(foo);
}

function doSomethingElse(url) {
return Liferay.Util.fetch(url);
}
```

## Further Reading

- [LPS-94712 Make a utility that encapsulates common 'fetch' configuration and use](https://issues.liferay.com/browse/LPS-94712)
- [LPS-96778 Standardize Ajax requests in frontend-js-web](https://issues.liferay.com/browse/LPS-96778)
- [LPS-96933 Standardize Ajax requests in frontend-js-aui-web](https://issues.liferay.com/browse/LPS-96933)
- [LPS-98655 Extend 'fetch' utility to set 'x-csrf-token' header by default](https://issues.liferay.com/browse/LPS-98655)
- [LPS-98888 Standardize Ajax requests in layout modules](https://issues.liferay.com/browse/LPS-98888)
- [LPS-98940 Standardize Ajax requests in collaboration modules #1](https://issues.liferay.com/browse/LPS-98940)
- [LPS-98941 Standardize Ajax requests in collaboration modules #2](https://issues.liferay.com/browse/LPS-98941)
- [LPS-98942 Standardize Ajax requests in collaboration modules #3](https://issues.liferay.com/browse/LPS-98942)
- [LPS-98946 Standardize Ajax requests in wem1 (asset, mobile-device-rules, journal)](https://issues.liferay.com/browse/LPS-98946)
- [LPS-98947 Standardize Ajax requests in users modules](https://issues.liferay.com/browse/LPS-98947)
- [LPS-98948 Standardize Ajax requests in site modules](https://issues.liferay.com/browse/LPS-98948)
- [LPS-98949 Standardize Ajax requests in segments](https://issues.liferay.com/browse/LPS-98949)
- [LPS-98953 Standardize Ajax requests in change-tracking modules](https://issues.liferay.com/browse/LPS-98953)
- [LPS-98962 Standardize Ajax requests in dynamic-data-mapping](https://issues.liferay.com/browse/LPS-98962)
- [LPS-99339 Standardize Ajax requests in frontend-js-aui-web, part 2](https://issues.liferay.com/browse/LPS-99339)
- [LPS-99414 Standardize Ajax requests in common #1](https://issues.liferay.com/browse/LPS-99414)
- [LPS-99610 Standardize Ajax requests in common #2](https://issues.liferay.com/browse/LPS-99610)
- [LPS-99611 Standardize Ajax requests in product-navigation](https://issues.liferay.com/browse/LPS-99611)
- [LPS-99612 Standardize Ajax requests in staging and export-import](https://issues.liferay.com/browse/LPS-99612)
1 change: 1 addition & 0 deletions plugins/eslint-plugin-liferay-portal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
module.exports = {
rules: {
'no-explicit-extend': require('./lib/rules/no-explicit-extend'),
'no-global-fetch': require('./lib/rules/no-global-fetch'),
'no-metal-plugins': require('./lib/rules/no-metal-plugins'),
'no-side-navigation': require('./lib/rules/no-side-navigation'),
},
Expand Down
57 changes: 57 additions & 0 deletions plugins/eslint-plugin-liferay-portal/lib/rules/no-global-fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* © 2017 Liferay, Inc. <https://liferay.com>
*
* SPDX-License-Identifier: MIT
*/

const DESCRIPTION =
'Direct usage of the `fetch` API is discouraged in favour of our wrapped version that takes care of the necessary security configuration; import fetch from frontend-js-web instead';

module.exports = {
meta: {
docs: {
description: DESCRIPTION,
category: 'Best Practices',
recommended: false,
url: 'https://issues.liferay.com/browse/LPS-98283',
},
fixable: null,
messages: {
noGlobalFetch: DESCRIPTION,
},
schema: [],
type: 'problem',
},

create(context) {
let foundFetchImport = false;

return {
CallExpression(node) {
if (
node.callee.type === 'Identifier' &&
node.callee.name === 'fetch' &&
!foundFetchImport
) {
context.report({
messageId: 'noGlobalFetch',
node,
});
}
},

ImportDeclaration(node) {
if (
node.source &&
node.source.type === 'Literal' &&
node.source.value === 'frontend-js-web' &&
node.specifiers.find(
specifier => specifier.imported.name === 'fetch'
)
) {
foundFetchImport = true;
}
},
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* © 2017 Liferay, Inc. <https://liferay.com>
*
* SPDX-License-Identifier: MIT
*/

const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/no-global-fetch');

const parserOptions = {
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
},
};

const ruleTester = new RuleTester(parserOptions);

ruleTester.run('no-global-fetch', rule, {
valid: [
{
// Imported from frontend-js-web
code: `
import {fetch} from 'frontend-js-web';
function doSomething(url) {
return fetch(url);
}
`,
},
{
// Namespaced from Liferay.Util
code: `
function doSomething(url) {
return Liferay.Util.fetch(url);
}
`,
},
],
invalid: [
{
// As a global fetch without an import.
code: `
function doSomething(url) {
return fetch(url);
};
`,
errors: [
{
messageId: 'noGlobalFetch',
type: 'CallExpression',
},
],
},
],
});
1 change: 1 addition & 0 deletions portal.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const config = {
plugins: [local('liferay-portal')],
rules: {
'liferay-portal/no-explicit-extend': 'error',
'liferay-portal/no-global-fetch': 'error',
'liferay-portal/no-metal-plugins': 'error',
'liferay-portal/no-side-navigation': 'error',
},
Expand Down

0 comments on commit a21c78f

Please sign in to comment.