base.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import type { Span } from '../../trace';
  2. import { compareAndWriteFile } from '../create-file';
  3. /**
  4. * The class is not about holding rule data, instead it determines how the
  5. * date is written to a file.
  6. */
  7. export abstract class BaseWriteStrategy {
  8. /**
  9. * Sometimes a ruleset will create extra files (e.g. reject-url-regex w/ mitm.sgmodule),
  10. * and doesn't share the same filename and id. This property is used to overwrite the filename.
  11. */
  12. public overwriteFilename: string | null = null;
  13. public withFilename(filename: string) {
  14. this.overwriteFilename = filename;
  15. return this;
  16. }
  17. public abstract readonly type: 'domainset' | 'non_ip' | 'ip' | (string & {});
  18. abstract readonly fileExtension: 'conf' | 'txt' | 'json' | 'sgmodule' /* | (string & {}) */;
  19. constructor(public readonly outputDir: string) {}
  20. protected abstract result: string[] | null;
  21. abstract writeDomain(domain: string): void;
  22. abstract writeDomainSuffix(domain: string): void;
  23. abstract writeDomainKeywords(keyword: Set<string>): void;
  24. abstract writeDomainWildcards(wildcard: Set<string>): void;
  25. abstract writeUserAgents(userAgent: Set<string>): void;
  26. abstract writeProcessNames(processName: Set<string>): void;
  27. abstract writeProcessPaths(processPath: Set<string>): void;
  28. abstract writeUrlRegexes(urlRegex: Set<string>): void;
  29. abstract writeIpCidrs(ipCidr: string[], noResolve: boolean): void;
  30. abstract writeIpCidr6s(ipCidr6: string[], noResolve: boolean): void;
  31. abstract writeGeoip(geoip: Set<string>, noResolve: boolean): void;
  32. abstract writeIpAsns(asns: Set<string>, noResolve: boolean): void;
  33. abstract writeSourceIpCidrs(sourceIpCidr: string[]): void;
  34. abstract writeSourcePorts(port: Set<string>): void;
  35. abstract writeDestinationPorts(port: Set<string>): void;
  36. abstract writeOtherRules(rule: string[]): void;
  37. protected abstract withPadding(title: string, description: string[] | readonly string[], date: Date, content: string[]): string[];
  38. static readonly domainWildCardToRegex = (domain: string) => {
  39. let result = '^';
  40. for (let i = 0, len = domain.length; i < len; i++) {
  41. switch (domain[i]) {
  42. case '.':
  43. result += String.raw`\.`;
  44. break;
  45. case '*':
  46. result += String.raw`[\w.-]*?`;
  47. break;
  48. case '?':
  49. result += String.raw`[\w.-]`;
  50. break;
  51. default:
  52. result += domain[i];
  53. }
  54. }
  55. result += '$';
  56. return result;
  57. };
  58. public output(
  59. span: Span,
  60. title: string,
  61. description: string[] | readonly string[],
  62. date: Date,
  63. filePath: string
  64. ): void | Promise<void> {
  65. if (!this.result) {
  66. return;
  67. }
  68. return compareAndWriteFile(
  69. span,
  70. this.withPadding(
  71. title,
  72. description,
  73. date,
  74. this.result
  75. ),
  76. filePath
  77. );
  78. };
  79. public get content() {
  80. return this.result;
  81. }
  82. }