diff --git a/lib/rules/no-template-target-blank.js b/lib/rules/no-template-target-blank.js index 1cbe7f401..d535b14b9 100644 --- a/lib/rules/no-template-target-blank.js +++ b/lib/rules/no-template-target-blank.js @@ -67,6 +67,32 @@ function hasDynamicLink(node) { ) } +/** + * @param {VAttribute} node + * @returns {Rule.SuggestionReportDescriptor} + */ +function getSuggestion(node) { + const relAttributeNode = node.parent.attributes.find( + (attribute) => attribute.key.name === 'rel' + ) + + if (relAttributeNode) { + return { + desc: 'Change `rel` attribute value to `noopener noreferrer`.', + fix(fixer) { + return fixer.replaceText(relAttributeNode, 'rel="noopener noreferrer"') + } + } + } + + return { + desc: 'Add `rel="noopener noreferrer"`.', + fix(fixer) { + return fixer.insertTextAfter(node, ' rel="noopener noreferrer"') + } + } +} + module.exports = { meta: { type: 'problem', @@ -76,6 +102,7 @@ module.exports = { categories: undefined, url: 'https://eslint.vuejs.org/rules/no-template-target-blank.html' }, + hasSuggestions: true, schema: [ { type: 'object', @@ -118,7 +145,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: [getSuggestion(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: + '' + } + ] + } ] } ]