@appland/scanner 1.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/LICENSE.txt +25 -0
  2. package/README.md +122 -0
  3. package/built/algorithms/dataStructures/graph/Graph.js +155 -0
  4. package/built/algorithms/dataStructures/graph/Graph.js.map +1 -0
  5. package/built/algorithms/dataStructures/graph/GraphEdge.js +27 -0
  6. package/built/algorithms/dataStructures/graph/GraphEdge.js.map +1 -0
  7. package/built/algorithms/dataStructures/graph/GraphVertex.js +79 -0
  8. package/built/algorithms/dataStructures/graph/GraphVertex.js.map +1 -0
  9. package/built/algorithms/dataStructures/linked-list/LinkedList.js +134 -0
  10. package/built/algorithms/dataStructures/linked-list/LinkedList.js.map +1 -0
  11. package/built/algorithms/dataStructures/linked-list/LinkedListNode.js +16 -0
  12. package/built/algorithms/dataStructures/linked-list/LinkedListNode.js.map +1 -0
  13. package/built/algorithms/graph/depth-first-search/index.js +49 -0
  14. package/built/algorithms/graph/depth-first-search/index.js.map +1 -0
  15. package/built/algorithms/graph/detect-cycle/index.js +77 -0
  16. package/built/algorithms/graph/detect-cycle/index.js.map +1 -0
  17. package/built/algorithms/utils/Comparator.js +35 -0
  18. package/built/algorithms/utils/Comparator.js.map +1 -0
  19. package/built/analyzer/recordSecrets.js +17 -0
  20. package/built/analyzer/recordSecrets.js.map +1 -0
  21. package/built/analyzer/secretsRegexes.js +13 -0
  22. package/built/analyzer/secretsRegexes.js.map +1 -0
  23. package/built/analyzer/secretsRegexesData.json +51 -0
  24. package/built/check.js +47 -0
  25. package/built/check.js.map +1 -0
  26. package/built/checkInstance.js +69 -0
  27. package/built/checkInstance.js.map +1 -0
  28. package/built/cli/ci/command.js +183 -0
  29. package/built/cli/ci/command.js.map +1 -0
  30. package/built/cli/ci/options.js +3 -0
  31. package/built/cli/ci/options.js.map +1 -0
  32. package/built/cli/exitCode.js +11 -0
  33. package/built/cli/exitCode.js.map +1 -0
  34. package/built/cli/progressReporter.js +16 -0
  35. package/built/cli/progressReporter.js.map +1 -0
  36. package/built/cli/resolveAppId.js +83 -0
  37. package/built/cli/resolveAppId.js.map +1 -0
  38. package/built/cli/scan/command.js +174 -0
  39. package/built/cli/scan/command.js.map +1 -0
  40. package/built/cli/scan/options.js +3 -0
  41. package/built/cli/scan/options.js.map +1 -0
  42. package/built/cli/scan/scanner.js +154 -0
  43. package/built/cli/scan/scanner.js.map +1 -0
  44. package/built/cli/scan.js +103 -0
  45. package/built/cli/scan.js.map +1 -0
  46. package/built/cli/scanArgs.js +26 -0
  47. package/built/cli/scanArgs.js.map +1 -0
  48. package/built/cli/scanOptions.js +3 -0
  49. package/built/cli/scanOptions.js.map +1 -0
  50. package/built/cli/upload/command.js +95 -0
  51. package/built/cli/upload/command.js.map +1 -0
  52. package/built/cli/upload/options.js +3 -0
  53. package/built/cli/upload/options.js.map +1 -0
  54. package/built/cli/validateFile.js +66 -0
  55. package/built/cli/validateFile.js.map +1 -0
  56. package/built/cli.js +32 -0
  57. package/built/cli.js.map +1 -0
  58. package/built/configuration/configurationProvider.js +169 -0
  59. package/built/configuration/configurationProvider.js.map +1 -0
  60. package/built/configuration/schema/match-pattern-config.json +32 -0
  61. package/built/configuration/schema/options.json +193 -0
  62. package/built/configuration/types/checkConfig.js +3 -0
  63. package/built/configuration/types/checkConfig.js.map +1 -0
  64. package/built/configuration/types/configuration.js +3 -0
  65. package/built/configuration/types/configuration.js.map +1 -0
  66. package/built/configuration/types/matchEventConfig.js +3 -0
  67. package/built/configuration/types/matchEventConfig.js.map +1 -0
  68. package/built/configuration/types/matchPatternConfig.js +3 -0
  69. package/built/configuration/types/matchPatternConfig.js.map +1 -0
  70. package/built/database/index.js +259 -0
  71. package/built/database/index.js.map +1 -0
  72. package/built/database/visit.js +80 -0
  73. package/built/database/visit.js.map +1 -0
  74. package/built/errors.js +35 -0
  75. package/built/errors.js.map +1 -0
  76. package/built/findings.js +15 -0
  77. package/built/findings.js.map +1 -0
  78. package/built/integration/appland/fetchStatus.js +51 -0
  79. package/built/integration/appland/fetchStatus.js.map +1 -0
  80. package/built/integration/appland/upload.js +193 -0
  81. package/built/integration/appland/upload.js.map +1 -0
  82. package/built/integration/github/commitStatus.js +19 -0
  83. package/built/integration/github/commitStatus.js.map +1 -0
  84. package/built/integration/vars.js +68 -0
  85. package/built/integration/vars.js.map +1 -0
  86. package/built/openapi/index.js +100 -0
  87. package/built/openapi/index.js.map +1 -0
  88. package/built/openapi/method.js +120 -0
  89. package/built/openapi/method.js.map +1 -0
  90. package/built/openapi/model.js +49 -0
  91. package/built/openapi/model.js.map +1 -0
  92. package/built/openapi/path.js +36 -0
  93. package/built/openapi/path.js.map +1 -0
  94. package/built/openapi/provider.js +133 -0
  95. package/built/openapi/provider.js.map +1 -0
  96. package/built/openapi/response.js +59 -0
  97. package/built/openapi/response.js.map +1 -0
  98. package/built/openapi/rpcRequest.js +130 -0
  99. package/built/openapi/rpcRequest.js.map +1 -0
  100. package/built/openapi/schema.js +42 -0
  101. package/built/openapi/schema.js.map +1 -0
  102. package/built/openapi/securitySchemes.js +32 -0
  103. package/built/openapi/securitySchemes.js.map +1 -0
  104. package/built/openapi/statusCodes.js +68 -0
  105. package/built/openapi/statusCodes.js.map +1 -0
  106. package/built/openapi/util.js +91 -0
  107. package/built/openapi/util.js.map +1 -0
  108. package/built/report/appMapMetadata.js +2 -0
  109. package/built/report/appMapMetadata.js.map +1 -0
  110. package/built/report/findingSummary.js +3 -0
  111. package/built/report/findingSummary.js.map +1 -0
  112. package/built/report/findingsReport.js +37 -0
  113. package/built/report/findingsReport.js.map +1 -0
  114. package/built/report/scanResults.js +103 -0
  115. package/built/report/scanResults.js.map +1 -0
  116. package/built/report/scanSummary.js +3 -0
  117. package/built/report/scanSummary.js.map +1 -0
  118. package/built/report/summaryReport.js +70 -0
  119. package/built/report/summaryReport.js.map +1 -0
  120. package/built/ruleChecker.js +260 -0
  121. package/built/ruleChecker.js.map +1 -0
  122. package/built/rules/authzBeforeAuthn.js +82 -0
  123. package/built/rules/authzBeforeAuthn.js.map +1 -0
  124. package/built/rules/circularDependency.js +227 -0
  125. package/built/rules/circularDependency.js.map +1 -0
  126. package/built/rules/http500.js +18 -0
  127. package/built/rules/http500.js.map +1 -0
  128. package/built/rules/illegalPackageDependency.js +38 -0
  129. package/built/rules/illegalPackageDependency.js.map +1 -0
  130. package/built/rules/incompatibleHttpClientRequest.js +96 -0
  131. package/built/rules/incompatibleHttpClientRequest.js.map +1 -0
  132. package/built/rules/insecureCompare.js +59 -0
  133. package/built/rules/insecureCompare.js.map +1 -0
  134. package/built/rules/jobNotCancelled.js +72 -0
  135. package/built/rules/jobNotCancelled.js.map +1 -0
  136. package/built/rules/lib/hasParameterOrReceiver.js +11 -0
  137. package/built/rules/lib/hasParameterOrReceiver.js.map +1 -0
  138. package/built/rules/lib/matchEvent.js +32 -0
  139. package/built/rules/lib/matchEvent.js.map +1 -0
  140. package/built/rules/lib/matchPattern.js +28 -0
  141. package/built/rules/lib/matchPattern.js.map +1 -0
  142. package/built/rules/lib/rpcWithoutProtection.js +40 -0
  143. package/built/rules/lib/rpcWithoutProtection.js.map +1 -0
  144. package/built/rules/missingAuthentication.js +65 -0
  145. package/built/rules/missingAuthentication.js.map +1 -0
  146. package/built/rules/missingContentType.js +27 -0
  147. package/built/rules/missingContentType.js.map +1 -0
  148. package/built/rules/nPlusOneQuery.js +84 -0
  149. package/built/rules/nPlusOneQuery.js.map +1 -0
  150. package/built/rules/queryFromInvalidPackage.js +37 -0
  151. package/built/rules/queryFromInvalidPackage.js.map +1 -0
  152. package/built/rules/queryFromView.js +29 -0
  153. package/built/rules/queryFromView.js.map +1 -0
  154. package/built/rules/rpcWithoutCircuitBreaker.js +97 -0
  155. package/built/rules/rpcWithoutCircuitBreaker.js.map +1 -0
  156. package/built/rules/saveWithoutValidation.js +27 -0
  157. package/built/rules/saveWithoutValidation.js.map +1 -0
  158. package/built/rules/secretInLog.js +76 -0
  159. package/built/rules/secretInLog.js.map +1 -0
  160. package/built/rules/slowFunctionCall.js +37 -0
  161. package/built/rules/slowFunctionCall.js.map +1 -0
  162. package/built/rules/slowHttpServerRequest.js +24 -0
  163. package/built/rules/slowHttpServerRequest.js.map +1 -0
  164. package/built/rules/slowQuery.js +23 -0
  165. package/built/rules/slowQuery.js.map +1 -0
  166. package/built/rules/tooManyJoins.js +77 -0
  167. package/built/rules/tooManyJoins.js.map +1 -0
  168. package/built/rules/tooManyUpdates.js +143 -0
  169. package/built/rules/tooManyUpdates.js.map +1 -0
  170. package/built/rules/unbatchedMaterializedQuery.js +65 -0
  171. package/built/rules/unbatchedMaterializedQuery.js.map +1 -0
  172. package/built/rules/updateInGetRequest.js +66 -0
  173. package/built/rules/updateInGetRequest.js.map +1 -0
  174. package/built/rules/util.js +102 -0
  175. package/built/rules/util.js.map +1 -0
  176. package/built/sampleConfig/bike_index.yml +10 -0
  177. package/built/sampleConfig/default.yml +19 -0
  178. package/built/sampleConfig/railsSampleApp6thEd.yml +29 -0
  179. package/built/sampleConfig/solidus.yml +31 -0
  180. package/built/scope/commandScope.js +156 -0
  181. package/built/scope/commandScope.js.map +1 -0
  182. package/built/scope/httpClientRequestScope.js +105 -0
  183. package/built/scope/httpClientRequestScope.js.map +1 -0
  184. package/built/scope/httpServerRequestScope.js +105 -0
  185. package/built/scope/httpServerRequestScope.js.map +1 -0
  186. package/built/scope/rootScope.js +105 -0
  187. package/built/scope/rootScope.js.map +1 -0
  188. package/built/scope/scopeImpl.js +88 -0
  189. package/built/scope/scopeImpl.js.map +1 -0
  190. package/built/scope/scopeIterator.js +21 -0
  191. package/built/scope/scopeIterator.js.map +1 -0
  192. package/built/scope/sqlTransactionScope.js +175 -0
  193. package/built/scope/sqlTransactionScope.js.map +1 -0
  194. package/built/wellKnownLabels.js +9 -0
  195. package/built/wellKnownLabels.js.map +1 -0
  196. package/package.json +89 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryFromView.js","sourceRoot":"","sources":["../../src/rules/queryFromView.ts"],"names":[],"mappings":";;AAIA;IAAA;QACS,mBAAc,GAAU,cAAc,CAAC;IAChD,CAAC;IAAD,cAAC;AAAD,CAAC,AAFD,IAEC;AAED,SAAS,KAAK,CAAC,OAAgC;IAAhC,wBAAA,EAAA,cAAuB,OAAO,EAAE;IAC7C,SAAS,OAAO,CAAC,CAAQ;QACvB,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,CAAQ,IAAK,OAAA,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAA/C,CAA+C,CAAC,CAAC;IAC3F,CAAC;IACD,SAAS,KAAK,CAAC,CAAQ;QACrB,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACtB,CAAC;IAED,OAAO;QACL,OAAO,SAAA;QACP,KAAK,OAAA;KACN,CAAC;AACJ,CAAC;AAED,kBAAe;IACb,EAAE,EAAE,iBAAiB;IACrB,KAAK,EAAE,mBAAmB;IAC1B,OAAO,SAAA;IACP,cAAc,EAAE,IAAI;IACpB,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __generator = (this && this.__generator) || function (thisArg, body) {
3
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
4
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
5
+ function verb(n) { return function (v) { return step([n, v]); }; }
6
+ function step(op) {
7
+ if (f) throw new TypeError("Generator is already executing.");
8
+ while (_) try {
9
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
10
+ if (y = 0, t) op = [op[0] & 2, t.value];
11
+ switch (op[0]) {
12
+ case 0: case 1: t = op; break;
13
+ case 4: _.label++; return { value: op[1], done: false };
14
+ case 5: _.label++; y = op[1]; op = [0]; continue;
15
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
16
+ default:
17
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
18
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
19
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
20
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
21
+ if (t[2]) _.ops.pop();
22
+ _.trys.pop(); continue;
23
+ }
24
+ op = body.call(thisArg, _);
25
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
26
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
27
+ }
28
+ };
29
+ var __values = (this && this.__values) || function(o) {
30
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
31
+ if (m) return m.call(o);
32
+ if (o && typeof o.length === "number") return {
33
+ next: function () {
34
+ if (o && i >= o.length) o = void 0;
35
+ return { value: o && o[i++], done: !o };
36
+ }
37
+ };
38
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ var models_1 = require("@appland/models");
42
+ var rpcWithoutProtection_1 = require("./lib/rpcWithoutProtection");
43
+ var Options = /** @class */ (function () {
44
+ function Options() {
45
+ this.expectedLabel = RPCCircuitBreaker;
46
+ }
47
+ return Options;
48
+ }());
49
+ // The circuit breaker will be found in a descendant of the httpClientRequest.
50
+ function descendants(httpClientRequest) {
51
+ var _a, _b, candidate, e_1_1;
52
+ var e_1, _c;
53
+ return __generator(this, function (_d) {
54
+ switch (_d.label) {
55
+ case 0:
56
+ _d.trys.push([0, 5, 6, 7]);
57
+ _a = __values(new models_1.EventNavigator(httpClientRequest).descendants()), _b = _a.next();
58
+ _d.label = 1;
59
+ case 1:
60
+ if (!!_b.done) return [3 /*break*/, 4];
61
+ candidate = _b.value;
62
+ return [4 /*yield*/, candidate.event];
63
+ case 2:
64
+ _d.sent();
65
+ _d.label = 3;
66
+ case 3:
67
+ _b = _a.next();
68
+ return [3 /*break*/, 1];
69
+ case 4: return [3 /*break*/, 7];
70
+ case 5:
71
+ e_1_1 = _d.sent();
72
+ e_1 = { error: e_1_1 };
73
+ return [3 /*break*/, 7];
74
+ case 6:
75
+ try {
76
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
77
+ }
78
+ finally { if (e_1) throw e_1.error; }
79
+ return [7 /*endfinally*/];
80
+ case 7: return [2 /*return*/];
81
+ }
82
+ });
83
+ }
84
+ function build(options) {
85
+ if (options === void 0) { options = new Options(); }
86
+ return (0, rpcWithoutProtection_1.rpcWithoutProtection)(descendants, options);
87
+ }
88
+ var RPCCircuitBreaker = 'rpc.circuit_breaker';
89
+ exports.default = {
90
+ id: 'rpc-without-circuit-breaker',
91
+ title: 'RPC without circuit breaker',
92
+ Options: Options,
93
+ labels: [RPCCircuitBreaker],
94
+ enumerateScope: true,
95
+ build: build,
96
+ };
97
+ //# sourceMappingURL=rpcWithoutCircuitBreaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpcWithoutCircuitBreaker.js","sourceRoot":"","sources":["../../src/rules/rpcWithoutCircuitBreaker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0CAAwD;AAExD,mEAA+F;AAG/F;IAAA;QACS,kBAAa,GAAW,iBAAiB,CAAC;IACnD,CAAC;IAAD,cAAC;AAAD,CAAC,AAFD,IAEC;AAED,8EAA8E;AAC9E,SAAU,WAAW,CAAC,iBAAwB;;;;;;;gBACpB,KAAA,SAAA,IAAI,uBAAc,CAAC,iBAAiB,CAAC,CAAC,WAAW,EAAE,CAAA;;;;gBAAhE,SAAS;gBAClB,qBAAM,SAAS,CAAC,KAAK,EAAA;;gBAArB,SAAqB,CAAC;;;;;;;;;;;;;;;;;;;CAEzB;AAED,SAAS,KAAK,CAAC,OAAgC;IAAhC,wBAAA,EAAA,cAAuB,OAAO,EAAE;IAC7C,OAAO,IAAA,2CAAoB,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,IAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEhD,kBAAe;IACb,EAAE,EAAE,6BAA6B;IACjC,KAAK,EAAE,6BAA6B;IACpC,OAAO,SAAA;IACP,MAAM,EAAE,CAAC,iBAAiB,CAAC;IAC3B,cAAc,EAAE,IAAI;IACpB,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var models_1 = require("@appland/models");
4
+ var validatedBy = function (iterator) {
5
+ var i = iterator.next();
6
+ while (!i.done) {
7
+ if (i.value.event.methodId !== undefined &&
8
+ ['valid?', 'validate'].includes(i.value.event.methodId)) {
9
+ return true;
10
+ }
11
+ i = iterator.next();
12
+ }
13
+ return false;
14
+ };
15
+ function build() {
16
+ return {
17
+ matcher: function (event) { return !validatedBy(new models_1.EventNavigator(event).descendants()); },
18
+ where: function (e) { return e.isFunction && ['save', 'save!'].includes(e.methodId); },
19
+ };
20
+ }
21
+ exports.default = {
22
+ id: 'save-without-validation',
23
+ title: 'Save without validation',
24
+ enumerateScope: true,
25
+ build: build,
26
+ };
27
+ //# sourceMappingURL=saveWithoutValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saveWithoutValidation.js","sourceRoot":"","sources":["../../src/rules/saveWithoutValidation.ts"],"names":[],"mappings":";;AAAA,0CAAwD;AAGxD,IAAM,WAAW,GAAG,UAAC,QAAkC;IACrD,IAAI,CAAC,GAAmC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxD,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE;QACd,IACE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS;YACpC,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAS,CAAC,EACxD;YACA,OAAO,IAAI,CAAC;SACb;QACD,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;KACrB;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,SAAS,KAAK;IACZ,OAAO;QACL,OAAO,EAAE,UAAC,KAAY,IAAK,OAAA,CAAC,WAAW,CAAC,IAAI,uBAAc,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,EAArD,CAAqD;QAChF,KAAK,EAAE,UAAC,CAAQ,IAAK,OAAA,CAAC,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAS,CAAC,EAAvD,CAAuD;KAC7E,CAAC;AACJ,CAAC;AAED,kBAAe;IACb,EAAE,EAAE,yBAAyB;IAC7B,KAAK,EAAE,yBAAyB;IAChC,cAAc,EAAE,IAAI;IACpB,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var secretsRegexes_1 = __importDefault(require("../analyzer/secretsRegexes"));
7
+ var util_1 = require("./util");
8
+ var recordSecrets_1 = __importDefault(require("../analyzer/recordSecrets"));
9
+ var Match = /** @class */ (function () {
10
+ function Match(regexp, value) {
11
+ this.regexp = regexp;
12
+ this.value = value;
13
+ }
14
+ return Match;
15
+ }());
16
+ var secrets = new Set();
17
+ var findMatchingValue = function (regexps, parameters) {
18
+ var matches = [];
19
+ parameters
20
+ .filter(function (parameter) { return !(0, util_1.emptyValue)(parameter.value); })
21
+ .forEach(function (parameter) {
22
+ var value = parameter.value;
23
+ regexps
24
+ .filter(function (regexp) { return regexp.test(value); })
25
+ .forEach(function (regexp) {
26
+ matches.push(new Match(regexp, value));
27
+ });
28
+ });
29
+ return matches;
30
+ };
31
+ var findInLog = function (e) {
32
+ var matches = Object.keys(secretsRegexes_1.default).reduce(function (memo, key) {
33
+ var matches = findMatchingValue(secretsRegexes_1.default[key], e.parameters);
34
+ matches.forEach(function (match) { return memo.push(match); });
35
+ return memo;
36
+ }, []);
37
+ e.parameters.filter(function (parameter) { return !(0, util_1.emptyValue)(parameter.value); }).forEach(function (parameter) {
38
+ var value = parameter.value;
39
+ secrets.forEach(function (secret) {
40
+ if (value.includes(secret)) {
41
+ matches.push(new Match(secret, value));
42
+ }
43
+ });
44
+ });
45
+ if (matches.length > 0) {
46
+ return matches.map(function (match) { return ({
47
+ level: 'error',
48
+ message: match.value + " contains secret " + match.regexp,
49
+ }); });
50
+ }
51
+ };
52
+ function build() {
53
+ return {
54
+ matcher: function (e) {
55
+ if (e.codeObject.labels.has(Secret)) {
56
+ (0, recordSecrets_1.default)(secrets, e);
57
+ }
58
+ if (e.parameters && e.codeObject.labels.has(Log)) {
59
+ return findInLog(e);
60
+ }
61
+ },
62
+ where: function (e) {
63
+ return e.codeObject.labels.has(Log) || e.codeObject.labels.has(Secret);
64
+ },
65
+ };
66
+ }
67
+ var Secret = 'secret';
68
+ var Log = 'log';
69
+ exports.default = {
70
+ id: 'secret-in-log',
71
+ title: 'Secret in log',
72
+ labels: [Secret, Log],
73
+ enumerateScope: true,
74
+ build: build,
75
+ };
76
+ //# sourceMappingURL=secretInLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secretInLog.js","sourceRoot":"","sources":["../../src/rules/secretInLog.ts"],"names":[],"mappings":";;;;;AAEA,8EAAwD;AACxD,+BAAoC;AACpC,4EAAsD;AAEtD;IACE,eAAmB,MAAuB,EAAS,KAAa;QAA7C,WAAM,GAAN,MAAM,CAAiB;QAAS,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IACtE,YAAC;AAAD,CAAC,AAFD,IAEC;AAED,IAAM,OAAO,GAAgB,IAAI,GAAG,EAAE,CAAC;AAEvC,IAAM,iBAAiB,GAAG,UAAC,OAAiB,EAAE,UAAsC;IAClF,IAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,UAAU;SACP,MAAM,CAAC,UAAC,SAAS,IAAK,OAAA,CAAC,IAAA,iBAAU,EAAC,SAAS,CAAC,KAAK,CAAC,EAA5B,CAA4B,CAAC;SACnD,OAAO,CAAC,UAAC,SAAS;QACjB,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,OAAO;aACJ,MAAM,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAlB,CAAkB,CAAC;aACtC,OAAO,CAAC,UAAC,MAAM;YACd,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IACL,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,IAAM,SAAS,GAAG,UAAC,CAAQ;IACzB,IAAM,OAAO,GAAY,MAAM,CAAC,IAAI,CAAC,wBAAc,CAAC,CAAC,MAAM,CAAC,UAAC,IAAI,EAAE,GAAG;QACpE,IAAM,OAAO,GAAG,iBAAiB,CAAC,wBAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,UAAW,CAAC,CAAC;QACtE,OAAO,CAAC,OAAO,CAAC,UAAC,KAAK,IAAK,OAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAhB,CAAgB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,EAAa,CAAC,CAAC;IAElB,CAAC,CAAC,UAAW,CAAC,MAAM,CAAC,UAAC,SAAS,IAAK,OAAA,CAAC,IAAA,iBAAU,EAAC,SAAS,CAAC,KAAK,CAAC,EAA5B,CAA4B,CAAC,CAAC,OAAO,CAAC,UAAC,SAAS;QAClF,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,OAAO,CAAC,OAAO,CAAC,UAAC,MAAM;YACrB,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBAC1B,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;aACxC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;QACtB,OAAO,OAAO,CAAC,GAAG,CAAC,UAAC,KAAK,IAAK,OAAA,CAAC;YAC7B,KAAK,EAAE,OAAO;YACd,OAAO,EAAK,KAAK,CAAC,KAAK,yBAAoB,KAAK,CAAC,MAAQ;SAC1D,CAAC,EAH4B,CAG5B,CAAC,CAAC;KACL;AACH,CAAC,CAAC;AAEF,SAAS,KAAK;IACZ,OAAO;QACL,OAAO,EAAE,UAAC,CAAC;YACT,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;gBACnC,IAAA,uBAAa,EAAC,OAAO,EAAE,CAAC,CAAC,CAAC;aAC3B;YACD,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAChD,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;aACrB;QACH,CAAC;QACD,KAAK,EAAE,UAAC,CAAC;YACP,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,IAAM,MAAM,GAAG,QAAQ,CAAC;AACxB,IAAM,GAAG,GAAG,KAAK,CAAC;AAElB,kBAAe;IACb,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,cAAc,EAAE,IAAI;IACpB,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var matchPattern_1 = require("./lib/matchPattern");
4
+ var Options = /** @class */ (function () {
5
+ function Options() {
6
+ this.functions = [];
7
+ this.timeAllowed = 0.1;
8
+ }
9
+ return Options;
10
+ }());
11
+ function build(options) {
12
+ var functionPatterns = (0, matchPattern_1.buildFilters)(options.functions || []);
13
+ return {
14
+ matcher: function (e) {
15
+ if (e.returnEvent.elapsedTime > options.timeAllowed) {
16
+ return "Slow " + e.codeObject.id + " call (" + e.returnEvent.elapsedTime + "ms)";
17
+ }
18
+ },
19
+ where: function (e) {
20
+ return e.isFunction &&
21
+ !!e.returnEvent &&
22
+ !!e.returnEvent.elapsedTime &&
23
+ !!e.codeObject.id &&
24
+ (functionPatterns.length === 0 ||
25
+ functionPatterns.some(function (pattern) { return pattern(e.codeObject.id); }));
26
+ },
27
+ };
28
+ }
29
+ exports.default = {
30
+ id: 'slow-function-call',
31
+ title: 'Slow function call',
32
+ scope: 'root',
33
+ enumerateScope: true,
34
+ Options: Options,
35
+ build: build,
36
+ };
37
+ //# sourceMappingURL=slowFunctionCall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slowFunctionCall.js","sourceRoot":"","sources":["../../src/rules/slowFunctionCall.ts"],"names":[],"mappings":";;AAGA,mDAAkD;AAElD;IAAA;QACS,cAAS,GAAyB,EAAE,CAAC;QACrC,gBAAW,GAAG,GAAG,CAAC;IAC3B,CAAC;IAAD,cAAC;AAAD,CAAC,AAHD,IAGC;AAED,SAAS,KAAK,CAAC,OAAgB;IAC7B,IAAM,gBAAgB,GAAG,IAAA,2BAAY,EAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAE/D,OAAO;QACL,OAAO,EAAE,UAAC,CAAC;YACT,IAAI,CAAC,CAAC,WAAW,CAAC,WAAY,GAAG,OAAO,CAAC,WAAW,EAAE;gBACpD,OAAO,UAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,eAAU,CAAC,CAAC,WAAW,CAAC,WAAW,QAAK,CAAC;aACxE;QACH,CAAC;QACD,KAAK,EAAE,UAAC,CAAC;YACP,OAAA,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,CAAC,CAAC,WAAW;gBACf,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW;gBAC3B,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;gBACjB,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC;oBAC5B,gBAAgB,CAAC,IAAI,CAAC,UAAC,OAAO,IAAK,OAAA,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,EAAxB,CAAwB,CAAC,CAAC;QAL/D,CAK+D;KAClE,CAAC;AACJ,CAAC;AAED,kBAAe;IACb,EAAE,EAAE,oBAAoB;IACxB,KAAK,EAAE,oBAAoB;IAC3B,KAAK,EAAE,MAAM;IACb,cAAc,EAAE,IAAI;IACpB,OAAO,SAAA;IACP,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var Options = /** @class */ (function () {
4
+ function Options() {
5
+ this.timeAllowed = 1;
6
+ }
7
+ return Options;
8
+ }());
9
+ function build(options) {
10
+ return {
11
+ matcher: function (e) { return e.elapsedTime > options.timeAllowed; },
12
+ message: function () { return "Slow HTTP server request (> " + options.timeAllowed * 1000 + "ms)"; },
13
+ where: function (e) { return !!e.httpServerRequest && e.elapsedTime !== undefined; },
14
+ };
15
+ }
16
+ exports.default = {
17
+ id: 'slow-http-server-request',
18
+ title: 'Slow HTTP server request',
19
+ scope: 'http_server_request',
20
+ enumerateScope: false,
21
+ Options: Options,
22
+ build: build,
23
+ };
24
+ //# sourceMappingURL=slowHttpServerRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slowHttpServerRequest.js","sourceRoot":"","sources":["../../src/rules/slowHttpServerRequest.ts"],"names":[],"mappings":";;AAGA;IAAA;QACS,gBAAW,GAAG,CAAC,CAAC;IACzB,CAAC;IAAD,cAAC;AAAD,CAAC,AAFD,IAEC;AAED,SAAS,KAAK,CAAC,OAAgB;IAC7B,OAAO;QACL,OAAO,EAAE,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,WAAY,GAAG,OAAO,CAAC,WAAW,EAApC,CAAoC;QACpD,OAAO,EAAE,cAAM,OAAA,iCAA+B,OAAO,CAAC,WAAW,GAAG,IAAI,QAAK,EAA9D,CAA8D;QAC7E,KAAK,EAAE,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,EAApD,CAAoD;KACnE,CAAC;AACJ,CAAC;AAED,kBAAe;IACb,EAAE,EAAE,0BAA0B;IAC9B,KAAK,EAAE,0BAA0B;IACjC,KAAK,EAAE,qBAAqB;IAC5B,cAAc,EAAE,KAAK;IACrB,OAAO,SAAA;IACP,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var Options = /** @class */ (function () {
4
+ function Options() {
5
+ this.timeAllowed = 1;
6
+ }
7
+ return Options;
8
+ }());
9
+ function build(options) {
10
+ if (options === void 0) { options = new Options(); }
11
+ return {
12
+ matcher: function (e) { return e.elapsedTime > options.timeAllowed; },
13
+ where: function (e) { return !!e.sqlQuery && !!e.elapsedTime; },
14
+ };
15
+ }
16
+ exports.default = {
17
+ id: 'slow-query',
18
+ title: 'Slow SQL query',
19
+ Options: Options,
20
+ enumerateScope: true,
21
+ build: build,
22
+ };
23
+ //# sourceMappingURL=slowQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slowQuery.js","sourceRoot":"","sources":["../../src/rules/slowQuery.ts"],"names":[],"mappings":";;AAGA;IAAA;QACS,gBAAW,GAAG,CAAC,CAAC;IACzB,CAAC;IAAD,cAAC;AAAD,CAAC,AAFD,IAEC;AAED,SAAS,KAAK,CAAC,OAAgC;IAAhC,wBAAA,EAAA,cAAuB,OAAO,EAAE;IAC7C,OAAO;QACL,OAAO,EAAE,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,WAAY,GAAG,OAAO,CAAC,WAAW,EAApC,CAAoC;QACpD,KAAK,EAAE,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAA/B,CAA+B;KAC9C,CAAC;AACJ,CAAC;AAED,kBAAe;IACb,EAAE,EAAE,YAAY;IAChB,KAAK,EAAE,gBAAgB;IACvB,OAAO,SAAA;IACP,cAAc,EAAE,IAAI;IACpB,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __values = (this && this.__values) || function(o) {
3
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
4
+ if (m) return m.call(o);
5
+ if (o && typeof o.length === "number") return {
6
+ next: function () {
7
+ if (o && i >= o.length) o = void 0;
8
+ return { value: o && o[i++], done: !o };
9
+ }
10
+ };
11
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ var database_1 = require("../database");
15
+ var Options = /** @class */ (function () {
16
+ function Options() {
17
+ this.warningLimit = 5;
18
+ }
19
+ return Options;
20
+ }());
21
+ // TODO: clean up (https://github.com/applandinc/scanner/issues/43)
22
+ function build(options) {
23
+ if (options === void 0) { options = new Options(); }
24
+ var joinCount = {};
25
+ function matcher(command, _appMap, eventFilter) {
26
+ var e_1, _a;
27
+ try {
28
+ for (var _b = __values((0, database_1.sqlStrings)(command, eventFilter)), _c = _b.next(); !_c.done; _c = _b.next()) {
29
+ var sqlEvent = _c.value;
30
+ var occurrence = joinCount[sqlEvent.sql];
31
+ if (!occurrence) {
32
+ occurrence = {
33
+ count: 1,
34
+ joins: (0, database_1.countJoins)(sqlEvent.sql),
35
+ events: [sqlEvent.event],
36
+ };
37
+ joinCount[sqlEvent.sql] = occurrence;
38
+ }
39
+ else {
40
+ occurrence.count += 1;
41
+ occurrence.events.push(sqlEvent.event);
42
+ }
43
+ }
44
+ }
45
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
46
+ finally {
47
+ try {
48
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
49
+ }
50
+ finally { if (e_1) throw e_1.error; }
51
+ }
52
+ return Object.keys(joinCount).reduce(function (matchResults, sql) {
53
+ var occurrence = joinCount[sql];
54
+ if (occurrence.joins >= options.warningLimit) {
55
+ matchResults.push({
56
+ level: 'warning',
57
+ event: occurrence.events[0],
58
+ message: occurrence.joins + " join" + (occurrence.joins > 1 ? 's' : '') + " in SQL \"" + sql + "\"",
59
+ relatedEvents: occurrence.events,
60
+ });
61
+ }
62
+ return matchResults;
63
+ }, []);
64
+ }
65
+ return {
66
+ matcher: matcher,
67
+ };
68
+ }
69
+ exports.default = {
70
+ id: 'too-many-joins',
71
+ title: 'Too many joins',
72
+ scope: 'command',
73
+ enumerateScope: false,
74
+ Options: Options,
75
+ build: build,
76
+ };
77
+ //# sourceMappingURL=tooManyJoins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooManyJoins.js","sourceRoot":"","sources":["../../src/rules/tooManyJoins.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAGA,wCAA+D;AAM/D;IAAA;QACS,iBAAY,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAD,cAAC;AAAD,CAAC,AAFD,IAEC;AAED,mEAAmE;AACnE,SAAS,KAAK,CAAC,OAAgC;IAAhC,wBAAA,EAAA,cAAuB,OAAO,EAAE;IAC7C,IAAM,SAAS,GAA8B,EAAE,CAAC;IAChD,SAAS,OAAO,CACd,OAAc,EACd,OAAe,EACf,WAAwB;;;YAExB,KAAuB,IAAA,KAAA,SAAA,IAAA,qBAAU,EAAC,OAAO,EAAE,WAAW,CAAC,CAAA,gBAAA,4BAAE;gBAApD,IAAM,QAAQ,WAAA;gBACjB,IAAI,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAEzC,IAAI,CAAC,UAAU,EAAE;oBACf,UAAU,GAAG;wBACX,KAAK,EAAE,CAAC;wBACR,KAAK,EAAE,IAAA,qBAAU,EAAC,QAAQ,CAAC,GAAG,CAAC;wBAC/B,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;qBACzB,CAAC;oBACF,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;iBACtC;qBAAM;oBACL,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC;oBACtB,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;iBACxC;aACF;;;;;;;;;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,UAAC,YAAY,EAAE,GAAG;YACrD,IAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAElC,IAAI,UAAU,CAAC,KAAK,IAAI,OAAO,CAAC,YAAY,EAAE;gBAC5C,YAAY,CAAC,IAAI,CAAC;oBAChB,KAAK,EAAE,SAAS;oBAChB,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC3B,OAAO,EAAK,UAAU,CAAC,KAAK,cAAQ,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,mBAAY,GAAG,OAAG;oBACrF,aAAa,EAAE,UAAU,CAAC,MAAM;iBACjC,CAAC,CAAC;aACJ;YACD,OAAO,YAAY,CAAC;QACtB,CAAC,EAAE,EAAmB,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO;QACL,OAAO,SAAA;KACR,CAAC;AACJ,CAAC;AAED,kBAAe;IACb,EAAE,EAAE,gBAAgB;IACpB,KAAK,EAAE,gBAAgB;IACvB,KAAK,EAAE,SAAS;IAChB,cAAc,EAAE,KAAK;IACrB,OAAO,SAAA;IACP,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __generator = (this && this.__generator) || function (thisArg, body) {
3
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
4
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
5
+ function verb(n) { return function (v) { return step([n, v]); }; }
6
+ function step(op) {
7
+ if (f) throw new TypeError("Generator is already executing.");
8
+ while (_) try {
9
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
10
+ if (y = 0, t) op = [op[0] & 2, t.value];
11
+ switch (op[0]) {
12
+ case 0: case 1: t = op; break;
13
+ case 4: _.label++; return { value: op[1], done: false };
14
+ case 5: _.label++; y = op[1]; op = [0]; continue;
15
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
16
+ default:
17
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
18
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
19
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
20
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
21
+ if (t[2]) _.ops.pop();
22
+ _.trys.pop(); continue;
23
+ }
24
+ op = body.call(thisArg, _);
25
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
26
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
27
+ }
28
+ };
29
+ var __values = (this && this.__values) || function(o) {
30
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
31
+ if (m) return m.call(o);
32
+ if (o && typeof o.length === "number") return {
33
+ next: function () {
34
+ if (o && i >= o.length) o = void 0;
35
+ return { value: o && o[i++], done: !o };
36
+ }
37
+ };
38
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ var models_1 = require("@appland/models");
42
+ // TODO: Use the Query AST for this.
43
+ var QueryIncludes = [/\bINSERT\b/i, /\bUPDATE\b/i];
44
+ var UpdateMethods = ['put', 'post', 'patch'];
45
+ var Options = /** @class */ (function () {
46
+ function Options() {
47
+ this.warningLimit = 20;
48
+ }
49
+ return Options;
50
+ }());
51
+ function build(options) {
52
+ var isUpdate = function (event) {
53
+ var isSQLUpdate = function () {
54
+ if (!event.sqlQuery) {
55
+ return false;
56
+ }
57
+ return QueryIncludes.some(function (pattern) { return pattern.test(event.sqlQuery); });
58
+ };
59
+ var isRPCUpdate = function () {
60
+ if (!event.httpClientRequest) {
61
+ return false;
62
+ }
63
+ return UpdateMethods.includes(event.httpClientRequest.request_method.toLowerCase());
64
+ };
65
+ return isSQLUpdate() || isRPCUpdate();
66
+ };
67
+ var updateEvents = function (event) {
68
+ var _a, _b, e, e_1_1;
69
+ var e_1, _c;
70
+ return __generator(this, function (_d) {
71
+ switch (_d.label) {
72
+ case 0:
73
+ _d.trys.push([0, 5, 6, 7]);
74
+ _a = __values(new models_1.EventNavigator(event).descendants()), _b = _a.next();
75
+ _d.label = 1;
76
+ case 1:
77
+ if (!!_b.done) return [3 /*break*/, 4];
78
+ e = _b.value;
79
+ if (!isUpdate(e.event)) {
80
+ return [3 /*break*/, 3];
81
+ }
82
+ return [4 /*yield*/, e.event];
83
+ case 2:
84
+ _d.sent();
85
+ _d.label = 3;
86
+ case 3:
87
+ _b = _a.next();
88
+ return [3 /*break*/, 1];
89
+ case 4: return [3 /*break*/, 7];
90
+ case 5:
91
+ e_1_1 = _d.sent();
92
+ e_1 = { error: e_1_1 };
93
+ return [3 /*break*/, 7];
94
+ case 6:
95
+ try {
96
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
97
+ }
98
+ finally { if (e_1) throw e_1.error; }
99
+ return [7 /*endfinally*/];
100
+ case 7: return [2 /*return*/];
101
+ }
102
+ });
103
+ };
104
+ function matcher(command) {
105
+ var e_2, _a;
106
+ var events = [];
107
+ try {
108
+ for (var _b = __values(updateEvents(command)), _c = _b.next(); !_c.done; _c = _b.next()) {
109
+ var updateEvent = _c.value;
110
+ events.push(updateEvent);
111
+ }
112
+ }
113
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
114
+ finally {
115
+ try {
116
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
117
+ }
118
+ finally { if (e_2) throw e_2.error; }
119
+ }
120
+ if (events.length > options.warningLimit) {
121
+ return [
122
+ {
123
+ level: 'error',
124
+ message: "Command performs " + events.length + " SQL and RPC updates",
125
+ event: events[0],
126
+ relatedEvents: events,
127
+ },
128
+ ];
129
+ }
130
+ }
131
+ return {
132
+ matcher: matcher,
133
+ };
134
+ }
135
+ exports.default = {
136
+ id: 'too-many-updates',
137
+ title: 'Too many SQL and RPC updates performed in one command',
138
+ scope: 'command',
139
+ enumerateScope: false,
140
+ Options: Options,
141
+ build: build,
142
+ };
143
+ //# sourceMappingURL=tooManyUpdates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooManyUpdates.js","sourceRoot":"","sources":["../../src/rules/tooManyUpdates.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0CAAwD;AAIxD,oCAAoC;AACpC,IAAM,aAAa,GAAa,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAC/D,IAAM,aAAa,GAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzD;IAAA;QACS,iBAAY,GAAG,EAAE,CAAC;IAC3B,CAAC;IAAD,cAAC;AAAD,CAAC,AAFD,IAEC;AAED,SAAS,KAAK,CAAC,OAAgB;IAC7B,IAAM,QAAQ,GAAG,UAAC,KAAY;QAC5B,IAAM,WAAW,GAAG;YAClB,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;gBACnB,OAAO,KAAK,CAAC;aACd;YACD,OAAO,aAAa,CAAC,IAAI,CAAC,UAAC,OAAO,IAAK,OAAA,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,QAAS,CAAC,EAA7B,CAA6B,CAAC,CAAC;QACxE,CAAC,CAAC;QAEF,IAAM,WAAW,GAAG;YAClB,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE;gBAC5B,OAAO,KAAK,CAAC;aACd;YACD,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,iBAAkB,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;QACvF,CAAC,CAAC;QAEF,OAAO,WAAW,EAAE,IAAI,WAAW,EAAE,CAAC;IACxC,CAAC,CAAC;IAEF,IAAM,YAAY,GAAG,UAAW,KAAY;;;;;;;oBAC1B,KAAA,SAAA,IAAI,uBAAc,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;;;;oBAA5C,CAAC;oBACV,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;wBACtB,wBAAS;qBACV;oBACD,qBAAM,CAAC,CAAC,KAAK,EAAA;;oBAAb,SAAa,CAAC;;;;;;;;;;;;;;;;;;;KAEjB,CAAC;IAEF,SAAS,OAAO,CAAC,OAAc;;QAC7B,IAAM,MAAM,GAAY,EAAE,CAAC;;YAC3B,KAA0B,IAAA,KAAA,SAAA,YAAY,CAAC,OAAO,CAAC,CAAA,gBAAA,4BAAE;gBAA5C,IAAM,WAAW,WAAA;gBACpB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC1B;;;;;;;;;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE;YACxC,OAAO;gBACL;oBACE,KAAK,EAAE,OAAO;oBACd,OAAO,EAAE,sBAAoB,MAAM,CAAC,MAAM,yBAAsB;oBAChE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;oBAChB,aAAa,EAAE,MAAM;iBACtB;aACF,CAAC;SACH;IACH,CAAC;IAED,OAAO;QACL,OAAO,SAAA;KACR,CAAC;AACJ,CAAC;AAED,kBAAe;IACb,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,uDAAuD;IAC9D,KAAK,EAAE,SAAS;IAChB,cAAc,EAAE,KAAK;IACrB,OAAO,SAAA;IACP,KAAK,OAAA;CACE,CAAC"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var models_1 = require("@appland/models");
4
+ var visit_1 = require("../database/visit");
5
+ function isMaterialized(e) {
6
+ return e.ancestors().some(function (_a) {
7
+ var labels = _a.labels;
8
+ return labels.has(DAOMaterialize);
9
+ });
10
+ }
11
+ function isApplicable(e) {
12
+ try {
13
+ var ast = (0, models_1.buildQueryAST)(e.sqlQuery);
14
+ var isSelect_1 = false;
15
+ var isCount_1 = false;
16
+ var hasLimitClause_1 = false;
17
+ var isMetadataQuery_1 = false;
18
+ if (ast) {
19
+ var metadataTableNames_1 = ['sqlite_master'];
20
+ (0, visit_1.visit)(ast, {
21
+ 'statement.select': function (statement) {
22
+ isSelect_1 = true;
23
+ if (statement.result &&
24
+ Array.isArray(statement.result) &&
25
+ statement.result.length === 1 &&
26
+ statement.result[0].type === 'function' &&
27
+ statement.result[0].name.name === 'count') {
28
+ isCount_1 = true;
29
+ }
30
+ },
31
+ 'expression.limit': function () {
32
+ hasLimitClause_1 = true;
33
+ },
34
+ 'identifier.table': function (identifier) {
35
+ if (metadataTableNames_1.includes(identifier.name)) {
36
+ isMetadataQuery_1 = true;
37
+ }
38
+ },
39
+ });
40
+ }
41
+ var isBatched = hasLimitClause_1 || isCount_1 || isMetadataQuery_1;
42
+ return isSelect_1 && !isBatched && isMaterialized(e);
43
+ }
44
+ catch (_) {
45
+ console.warn("Unable to analyze query \"" + e.sqlQuery + "\"");
46
+ return false;
47
+ }
48
+ }
49
+ function build() {
50
+ return {
51
+ matcher: function (e) { return isApplicable(e); },
52
+ where: function (e) { return !!e.sqlQuery; },
53
+ };
54
+ }
55
+ // Example: ActiveRecord::Relation#records
56
+ var DAOMaterialize = 'dao.materialize';
57
+ exports.default = {
58
+ id: 'unbatched-materialized-query',
59
+ title: 'Unbatched materialized SQL query',
60
+ labels: [DAOMaterialize],
61
+ scope: 'command',
62
+ enumerateScope: true,
63
+ build: build,
64
+ };
65
+ //# sourceMappingURL=unbatchedMaterializedQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unbatchedMaterializedQuery.js","sourceRoot":"","sources":["../../src/rules/unbatchedMaterializedQuery.ts"],"names":[],"mappings":";;AAAA,0CAAuD;AAEvD,2CAA0C;AAE1C,SAAS,cAAc,CAAC,CAAQ;IAC9B,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,EAAU;YAAR,MAAM,YAAA;QAAO,OAAA,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;IAA1B,CAA0B,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,YAAY,CAAC,CAAQ;IAC5B,IAAI;QACF,IAAM,GAAG,GAAG,IAAA,sBAAa,EAAC,CAAC,CAAC,QAAS,CAAC,CAAC;QACvC,IAAI,UAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,SAAO,GAAG,KAAK,CAAC;QACpB,IAAI,gBAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,iBAAe,GAAG,KAAK,CAAC;QAE5B,IAAI,GAAG,EAAE;YACP,IAAM,oBAAkB,GAAG,CAAC,eAAe,CAAC,CAAC;YAE7C,IAAA,aAAK,EAAC,GAAG,EAAE;gBACT,kBAAkB,EAAE,UAAC,SAAc;oBACjC,UAAQ,GAAG,IAAI,CAAC;oBAEhB,IACE,SAAS,CAAC,MAAM;wBAChB,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC;wBAC/B,SAAS,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;wBAC7B,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU;wBACvC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,EACzC;wBACA,SAAO,GAAG,IAAI,CAAC;qBAChB;gBACH,CAAC;gBACD,kBAAkB,EAAE;oBAClB,gBAAc,GAAG,IAAI,CAAC;gBACxB,CAAC;gBACD,kBAAkB,EAAE,UAAC,UAAe;oBAClC,IAAI,oBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;wBAChD,iBAAe,GAAG,IAAI,CAAC;qBACxB;gBACH,CAAC;aACF,CAAC,CAAC;SACJ;QAED,IAAM,SAAS,GAAG,gBAAc,IAAI,SAAO,IAAI,iBAAe,CAAC;QAE/D,OAAO,UAAQ,IAAI,CAAC,SAAS,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;KACpD;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,IAAI,CAAC,+BAA4B,CAAC,CAAC,QAAS,OAAG,CAAC,CAAC;QACzD,OAAO,KAAK,CAAC;KACd;AACH,CAAC;AAED,SAAS,KAAK;IACZ,OAAO;QACL,OAAO,EAAE,UAAC,CAAC,IAAK,OAAA,YAAY,CAAC,CAAC,CAAC,EAAf,CAAe;QAC/B,KAAK,EAAE,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAZ,CAAY;KAC3B,CAAC;AACJ,CAAC;AAED,0CAA0C;AAC1C,IAAM,cAAc,GAAG,iBAAiB,CAAC;AAEzC,kBAAe;IACb,EAAE,EAAE,8BAA8B;IAClC,KAAK,EAAE,kCAAkC;IACzC,MAAM,EAAE,CAAC,cAAc,CAAC;IACxB,KAAK,EAAE,SAAS;IAChB,cAAc,EAAE,IAAI;IACpB,KAAK,OAAA;CACE,CAAC"}