source: imaps-frontend/node_modules/eslint-plugin-react/lib/rules/iframe-missing-sandbox.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/**
2 * @fileoverview TBD
3 */
4
5'use strict';
6
7const docsUrl = require('../util/docsUrl');
8const isCreateElement = require('../util/isCreateElement');
9const report = require('../util/report');
10
11const messages = {
12 attributeMissing: 'An iframe element is missing a sandbox attribute',
13 invalidValue: 'An iframe element defines a sandbox attribute with invalid value "{{ value }}"',
14 invalidCombination: 'An iframe element defines a sandbox attribute with both allow-scripts and allow-same-origin which is invalid',
15};
16
17const ALLOWED_VALUES = [
18 // From https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox
19 '',
20 'allow-downloads-without-user-activation',
21 'allow-downloads',
22 'allow-forms',
23 'allow-modals',
24 'allow-orientation-lock',
25 'allow-pointer-lock',
26 'allow-popups',
27 'allow-popups-to-escape-sandbox',
28 'allow-presentation',
29 'allow-same-origin',
30 'allow-scripts',
31 'allow-storage-access-by-user-activation',
32 'allow-top-navigation',
33 'allow-top-navigation-by-user-activation',
34];
35
36function validateSandboxAttribute(context, node, attribute) {
37 if (typeof attribute !== 'string') {
38 // Only string literals are supported for now
39 return;
40 }
41 const values = attribute.split(' ');
42 let allowScripts = false;
43 let allowSameOrigin = false;
44 values.forEach((attributeValue) => {
45 const trimmedAttributeValue = attributeValue.trim();
46 if (ALLOWED_VALUES.indexOf(trimmedAttributeValue) === -1) {
47 report(context, messages.invalidValue, 'invalidValue', {
48 node,
49 data: {
50 value: trimmedAttributeValue,
51 },
52 });
53 }
54 if (trimmedAttributeValue === 'allow-scripts') {
55 allowScripts = true;
56 }
57 if (trimmedAttributeValue === 'allow-same-origin') {
58 allowSameOrigin = true;
59 }
60 });
61 if (allowScripts && allowSameOrigin) {
62 report(context, messages.invalidCombination, 'invalidCombination', {
63 node,
64 });
65 }
66}
67
68function checkAttributes(context, node) {
69 let sandboxAttributeFound = false;
70 node.attributes.forEach((attribute) => {
71 if (attribute.type === 'JSXAttribute'
72 && attribute.name
73 && attribute.name.type === 'JSXIdentifier'
74 && attribute.name.name === 'sandbox'
75 ) {
76 sandboxAttributeFound = true;
77 if (
78 attribute.value
79 && attribute.value.type === 'Literal'
80 && attribute.value.value
81 ) {
82 validateSandboxAttribute(context, node, attribute.value.value);
83 }
84 }
85 });
86 if (!sandboxAttributeFound) {
87 report(context, messages.attributeMissing, 'attributeMissing', {
88 node,
89 });
90 }
91}
92
93function checkProps(context, node) {
94 let sandboxAttributeFound = false;
95 if (node.arguments.length > 1) {
96 const props = node.arguments[1];
97 const sandboxProp = props.properties && props.properties.find((x) => x.type === 'Property' && x.key.name === 'sandbox');
98 if (sandboxProp) {
99 sandboxAttributeFound = true;
100 if (sandboxProp.value && sandboxProp.value.type === 'Literal' && sandboxProp.value.value) {
101 validateSandboxAttribute(context, node, sandboxProp.value.value);
102 }
103 }
104 }
105 if (!sandboxAttributeFound) {
106 report(context, messages.attributeMissing, 'attributeMissing', {
107 node,
108 });
109 }
110}
111
112/** @type {import('eslint').Rule.RuleModule} */
113module.exports = {
114 meta: {
115 docs: {
116 description: 'Enforce sandbox attribute on iframe elements',
117 category: 'Best Practices',
118 recommended: false,
119 url: docsUrl('iframe-missing-sandbox'),
120 },
121
122 schema: [],
123
124 messages,
125 },
126
127 create(context) {
128 return {
129 'JSXOpeningElement[name.name="iframe"]'(node) {
130 checkAttributes(context, node);
131 },
132
133 CallExpression(node) {
134 if (isCreateElement(context, node) && node.arguments && node.arguments.length > 0) {
135 const tag = node.arguments[0];
136 if (tag.type === 'Literal' && tag.value === 'iframe') {
137 checkProps(context, node);
138 }
139 }
140 },
141 };
142 },
143};
Note: See TracBrowser for help on using the repository browser.