From e9864f114c223b12183feb3c8beaab3d7f9eea09 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Tue, 21 Mar 2023 13:35:11 +0100 Subject: [PATCH 1/2] Add suggestions for `no-template-target-blank` rule --- lib/rules/no-template-target-blank.js | 32 ++++++++++- tests/lib/rules/no-template-target-blank.js | 60 +++++++++++++++++++-- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/lib/rules/no-template-target-blank.js b/lib/rules/no-template-target-blank.js index 1cbe7f401..24ca78ae4 100644 --- a/lib/rules/no-template-target-blank.js +++ b/lib/rules/no-template-target-blank.js @@ -67,6 +67,34 @@ function hasDynamicLink(node) { ) } +/** @param {VAttribute} node */ +function getSuggestions(node) { + /** @type {Rule.SuggestionReportDescriptor[]} */ + const suggestions = [] + + const relAttributeNode = node.parent.attributes.find( + (attribute) => attribute.key.name === 'rel' + ) + + if (relAttributeNode) { + suggestions.push({ + desc: 'Change `rel` attribute value to `noopener noreferrer`.', + fix(fixer) { + return fixer.replaceText(relAttributeNode, 'rel="noopener noreferrer"') + } + }) + } else { + suggestions.push({ + desc: 'Add `rel="noopener noreferrer"`.', + fix(fixer) { + return fixer.insertTextAfter(node, ' rel="noopener noreferrer"') + } + }) + } + + return suggestions +} + module.exports = { meta: { type: 'problem', @@ -76,6 +104,7 @@ module.exports = { categories: undefined, url: 'https://eslint.vuejs.org/rules/no-template-target-blank.html' }, + hasSuggestions: true, schema: [ { type: 'object', @@ -118,7 +147,8 @@ module.exports = { context.report({ node, message: - 'Using target="_blank" without rel="noopener noreferrer" is a security risk.' + 'Using target="_blank" without rel="noopener noreferrer" is a security risk.', + suggest: getSuggestions(node) }) } } diff --git a/tests/lib/rules/no-template-target-blank.js b/tests/lib/rules/no-template-target-blank.js index 9745fd1c4..5445ae6d7 100644 --- a/tests/lib/rules/no-template-target-blank.js +++ b/tests/lib/rules/no-template-target-blank.js @@ -49,31 +49,81 @@ ruleTester.run('no-template-target-blank', rule, { { code: '', errors: [ - 'Using target="_blank" without rel="noopener noreferrer" is a security risk.' + { + message: + 'Using target="_blank" without rel="noopener noreferrer" is a security risk.', + suggestions: [ + { + desc: 'Add `rel="noopener noreferrer"`.', + output: + '' + } + ] + } ] }, { code: '', errors: [ - 'Using target="_blank" without rel="noopener noreferrer" is a security risk.' + { + message: + 'Using target="_blank" without rel="noopener noreferrer" is a security risk.', + suggestions: [ + { + desc: 'Change `rel` attribute value to `noopener noreferrer`.', + output: + '' + } + ] + } ] }, { code: '', errors: [ - 'Using target="_blank" without rel="noopener noreferrer" is a security risk.' + { + message: + 'Using target="_blank" without rel="noopener noreferrer" is a security risk.', + suggestions: [ + { + desc: 'Change `rel` attribute value to `noopener noreferrer`.', + output: + '' + } + ] + } ] }, { code: '', errors: [ - 'Using target="_blank" without rel="noopener noreferrer" is a security risk.' + { + message: + 'Using target="_blank" without rel="noopener noreferrer" is a security risk.', + suggestions: [ + { + desc: 'Add `rel="noopener noreferrer"`.', + output: + '' + } + ] + } ] }, { code: '', errors: [ - 'Using target="_blank" without rel="noopener noreferrer" is a security risk.' + { + message: + 'Using target="_blank" without rel="noopener noreferrer" is a security risk.', + suggestions: [ + { + desc: 'Change `rel` attribute value to `noopener noreferrer`.', + output: + '' + } + ] + } ] } ] From 80dd9d7e303d0b4884b67451f5ecea4b950782d2 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Tue, 21 Mar 2023 13:38:26 +0100 Subject: [PATCH 2/2] Simplify logic --- lib/rules/no-template-target-blank.js | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/lib/rules/no-template-target-blank.js b/lib/rules/no-template-target-blank.js index 24ca78ae4..d535b14b9 100644 --- a/lib/rules/no-template-target-blank.js +++ b/lib/rules/no-template-target-blank.js @@ -67,32 +67,30 @@ function hasDynamicLink(node) { ) } -/** @param {VAttribute} node */ -function getSuggestions(node) { - /** @type {Rule.SuggestionReportDescriptor[]} */ - const suggestions = [] - +/** + * @param {VAttribute} node + * @returns {Rule.SuggestionReportDescriptor} + */ +function getSuggestion(node) { const relAttributeNode = node.parent.attributes.find( (attribute) => attribute.key.name === 'rel' ) if (relAttributeNode) { - suggestions.push({ + return { desc: 'Change `rel` attribute value to `noopener noreferrer`.', fix(fixer) { return fixer.replaceText(relAttributeNode, 'rel="noopener noreferrer"') } - }) - } else { - suggestions.push({ - desc: 'Add `rel="noopener noreferrer"`.', - fix(fixer) { - return fixer.insertTextAfter(node, ' rel="noopener noreferrer"') - } - }) + } } - return suggestions + return { + desc: 'Add `rel="noopener noreferrer"`.', + fix(fixer) { + return fixer.insertTextAfter(node, ' rel="noopener noreferrer"') + } + } } module.exports = { @@ -148,7 +146,7 @@ module.exports = { node, message: 'Using target="_blank" without rel="noopener noreferrer" is a security risk.', - suggest: getSuggestions(node) + suggest: [getSuggestion(node)] }) } }