require-post-message-target-origin.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. 'use strict';
  2. const {methodCallSelector} = require('./selectors/index.js');
  3. const {appendArgument} = require('./fix/index.js');
  4. const ERROR = 'error';
  5. const SUGGESTION_TARGET_LOCATION_ORIGIN = 'target-location-origin';
  6. const SUGGESTION_SELF_LOCATION_ORIGIN = 'self-location-origin';
  7. const SUGGESTION_STAR = 'star';
  8. const messages = {
  9. [ERROR]: 'Missing the `targetOrigin` argument.',
  10. [SUGGESTION_TARGET_LOCATION_ORIGIN]: 'Use `{{target}}.location.origin`.',
  11. [SUGGESTION_SELF_LOCATION_ORIGIN]: 'Use `self.location.origin`.',
  12. [SUGGESTION_STAR]: 'Use `"*"`.',
  13. };
  14. /** @param {import('eslint').Rule.RuleContext} context */
  15. function create(context) {
  16. const sourceCode = context.getSourceCode();
  17. return {
  18. [methodCallSelector({method: 'postMessage', argumentsLength: 1})](node) {
  19. const [penultimateToken, lastToken] = sourceCode.getLastTokens(node, 2);
  20. const suggestions = [];
  21. const target = node.callee.object;
  22. if (target.type === 'Identifier') {
  23. const {name} = target;
  24. suggestions.push({
  25. messageId: SUGGESTION_TARGET_LOCATION_ORIGIN,
  26. data: {target: name},
  27. code: `${target.name}.location.origin`,
  28. });
  29. if (name !== 'self' && name !== 'window' && name !== 'globalThis') {
  30. suggestions.push({messageId: SUGGESTION_SELF_LOCATION_ORIGIN, code: 'self.location.origin'});
  31. }
  32. } else {
  33. suggestions.push({messageId: SUGGESTION_SELF_LOCATION_ORIGIN, code: 'self.location.origin'});
  34. }
  35. suggestions.push({messageId: SUGGESTION_STAR, code: '\'*\''});
  36. return {
  37. loc: {
  38. start: penultimateToken.loc.end,
  39. end: lastToken.loc.end,
  40. },
  41. messageId: ERROR,
  42. suggest: suggestions.map(({messageId, data, code}) => ({
  43. messageId,
  44. data,
  45. /** @param {import('eslint').Rule.RuleFixer} fixer */
  46. fix: fixer => appendArgument(fixer, node, code, sourceCode),
  47. })),
  48. };
  49. },
  50. };
  51. }
  52. /** @type {import('eslint').Rule.RuleModule} */
  53. module.exports = {
  54. create,
  55. meta: {
  56. type: 'problem',
  57. docs: {
  58. description: 'Enforce using the `targetOrigin` argument with `window.postMessage()`.',
  59. },
  60. hasSuggestions: true,
  61. messages,
  62. },
  63. };