@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.
- package/LICENSE.txt +25 -0
- package/README.md +122 -0
- package/built/algorithms/dataStructures/graph/Graph.js +155 -0
- package/built/algorithms/dataStructures/graph/Graph.js.map +1 -0
- package/built/algorithms/dataStructures/graph/GraphEdge.js +27 -0
- package/built/algorithms/dataStructures/graph/GraphEdge.js.map +1 -0
- package/built/algorithms/dataStructures/graph/GraphVertex.js +79 -0
- package/built/algorithms/dataStructures/graph/GraphVertex.js.map +1 -0
- package/built/algorithms/dataStructures/linked-list/LinkedList.js +134 -0
- package/built/algorithms/dataStructures/linked-list/LinkedList.js.map +1 -0
- package/built/algorithms/dataStructures/linked-list/LinkedListNode.js +16 -0
- package/built/algorithms/dataStructures/linked-list/LinkedListNode.js.map +1 -0
- package/built/algorithms/graph/depth-first-search/index.js +49 -0
- package/built/algorithms/graph/depth-first-search/index.js.map +1 -0
- package/built/algorithms/graph/detect-cycle/index.js +77 -0
- package/built/algorithms/graph/detect-cycle/index.js.map +1 -0
- package/built/algorithms/utils/Comparator.js +35 -0
- package/built/algorithms/utils/Comparator.js.map +1 -0
- package/built/analyzer/recordSecrets.js +17 -0
- package/built/analyzer/recordSecrets.js.map +1 -0
- package/built/analyzer/secretsRegexes.js +13 -0
- package/built/analyzer/secretsRegexes.js.map +1 -0
- package/built/analyzer/secretsRegexesData.json +51 -0
- package/built/check.js +47 -0
- package/built/check.js.map +1 -0
- package/built/checkInstance.js +69 -0
- package/built/checkInstance.js.map +1 -0
- package/built/cli/ci/command.js +183 -0
- package/built/cli/ci/command.js.map +1 -0
- package/built/cli/ci/options.js +3 -0
- package/built/cli/ci/options.js.map +1 -0
- package/built/cli/exitCode.js +11 -0
- package/built/cli/exitCode.js.map +1 -0
- package/built/cli/progressReporter.js +16 -0
- package/built/cli/progressReporter.js.map +1 -0
- package/built/cli/resolveAppId.js +83 -0
- package/built/cli/resolveAppId.js.map +1 -0
- package/built/cli/scan/command.js +174 -0
- package/built/cli/scan/command.js.map +1 -0
- package/built/cli/scan/options.js +3 -0
- package/built/cli/scan/options.js.map +1 -0
- package/built/cli/scan/scanner.js +154 -0
- package/built/cli/scan/scanner.js.map +1 -0
- package/built/cli/scan.js +103 -0
- package/built/cli/scan.js.map +1 -0
- package/built/cli/scanArgs.js +26 -0
- package/built/cli/scanArgs.js.map +1 -0
- package/built/cli/scanOptions.js +3 -0
- package/built/cli/scanOptions.js.map +1 -0
- package/built/cli/upload/command.js +95 -0
- package/built/cli/upload/command.js.map +1 -0
- package/built/cli/upload/options.js +3 -0
- package/built/cli/upload/options.js.map +1 -0
- package/built/cli/validateFile.js +66 -0
- package/built/cli/validateFile.js.map +1 -0
- package/built/cli.js +32 -0
- package/built/cli.js.map +1 -0
- package/built/configuration/configurationProvider.js +169 -0
- package/built/configuration/configurationProvider.js.map +1 -0
- package/built/configuration/schema/match-pattern-config.json +32 -0
- package/built/configuration/schema/options.json +193 -0
- package/built/configuration/types/checkConfig.js +3 -0
- package/built/configuration/types/checkConfig.js.map +1 -0
- package/built/configuration/types/configuration.js +3 -0
- package/built/configuration/types/configuration.js.map +1 -0
- package/built/configuration/types/matchEventConfig.js +3 -0
- package/built/configuration/types/matchEventConfig.js.map +1 -0
- package/built/configuration/types/matchPatternConfig.js +3 -0
- package/built/configuration/types/matchPatternConfig.js.map +1 -0
- package/built/database/index.js +259 -0
- package/built/database/index.js.map +1 -0
- package/built/database/visit.js +80 -0
- package/built/database/visit.js.map +1 -0
- package/built/errors.js +35 -0
- package/built/errors.js.map +1 -0
- package/built/findings.js +15 -0
- package/built/findings.js.map +1 -0
- package/built/integration/appland/fetchStatus.js +51 -0
- package/built/integration/appland/fetchStatus.js.map +1 -0
- package/built/integration/appland/upload.js +193 -0
- package/built/integration/appland/upload.js.map +1 -0
- package/built/integration/github/commitStatus.js +19 -0
- package/built/integration/github/commitStatus.js.map +1 -0
- package/built/integration/vars.js +68 -0
- package/built/integration/vars.js.map +1 -0
- package/built/openapi/index.js +100 -0
- package/built/openapi/index.js.map +1 -0
- package/built/openapi/method.js +120 -0
- package/built/openapi/method.js.map +1 -0
- package/built/openapi/model.js +49 -0
- package/built/openapi/model.js.map +1 -0
- package/built/openapi/path.js +36 -0
- package/built/openapi/path.js.map +1 -0
- package/built/openapi/provider.js +133 -0
- package/built/openapi/provider.js.map +1 -0
- package/built/openapi/response.js +59 -0
- package/built/openapi/response.js.map +1 -0
- package/built/openapi/rpcRequest.js +130 -0
- package/built/openapi/rpcRequest.js.map +1 -0
- package/built/openapi/schema.js +42 -0
- package/built/openapi/schema.js.map +1 -0
- package/built/openapi/securitySchemes.js +32 -0
- package/built/openapi/securitySchemes.js.map +1 -0
- package/built/openapi/statusCodes.js +68 -0
- package/built/openapi/statusCodes.js.map +1 -0
- package/built/openapi/util.js +91 -0
- package/built/openapi/util.js.map +1 -0
- package/built/report/appMapMetadata.js +2 -0
- package/built/report/appMapMetadata.js.map +1 -0
- package/built/report/findingSummary.js +3 -0
- package/built/report/findingSummary.js.map +1 -0
- package/built/report/findingsReport.js +37 -0
- package/built/report/findingsReport.js.map +1 -0
- package/built/report/scanResults.js +103 -0
- package/built/report/scanResults.js.map +1 -0
- package/built/report/scanSummary.js +3 -0
- package/built/report/scanSummary.js.map +1 -0
- package/built/report/summaryReport.js +70 -0
- package/built/report/summaryReport.js.map +1 -0
- package/built/ruleChecker.js +260 -0
- package/built/ruleChecker.js.map +1 -0
- package/built/rules/authzBeforeAuthn.js +82 -0
- package/built/rules/authzBeforeAuthn.js.map +1 -0
- package/built/rules/circularDependency.js +227 -0
- package/built/rules/circularDependency.js.map +1 -0
- package/built/rules/http500.js +18 -0
- package/built/rules/http500.js.map +1 -0
- package/built/rules/illegalPackageDependency.js +38 -0
- package/built/rules/illegalPackageDependency.js.map +1 -0
- package/built/rules/incompatibleHttpClientRequest.js +96 -0
- package/built/rules/incompatibleHttpClientRequest.js.map +1 -0
- package/built/rules/insecureCompare.js +59 -0
- package/built/rules/insecureCompare.js.map +1 -0
- package/built/rules/jobNotCancelled.js +72 -0
- package/built/rules/jobNotCancelled.js.map +1 -0
- package/built/rules/lib/hasParameterOrReceiver.js +11 -0
- package/built/rules/lib/hasParameterOrReceiver.js.map +1 -0
- package/built/rules/lib/matchEvent.js +32 -0
- package/built/rules/lib/matchEvent.js.map +1 -0
- package/built/rules/lib/matchPattern.js +28 -0
- package/built/rules/lib/matchPattern.js.map +1 -0
- package/built/rules/lib/rpcWithoutProtection.js +40 -0
- package/built/rules/lib/rpcWithoutProtection.js.map +1 -0
- package/built/rules/missingAuthentication.js +65 -0
- package/built/rules/missingAuthentication.js.map +1 -0
- package/built/rules/missingContentType.js +27 -0
- package/built/rules/missingContentType.js.map +1 -0
- package/built/rules/nPlusOneQuery.js +84 -0
- package/built/rules/nPlusOneQuery.js.map +1 -0
- package/built/rules/queryFromInvalidPackage.js +37 -0
- package/built/rules/queryFromInvalidPackage.js.map +1 -0
- package/built/rules/queryFromView.js +29 -0
- package/built/rules/queryFromView.js.map +1 -0
- package/built/rules/rpcWithoutCircuitBreaker.js +97 -0
- package/built/rules/rpcWithoutCircuitBreaker.js.map +1 -0
- package/built/rules/saveWithoutValidation.js +27 -0
- package/built/rules/saveWithoutValidation.js.map +1 -0
- package/built/rules/secretInLog.js +76 -0
- package/built/rules/secretInLog.js.map +1 -0
- package/built/rules/slowFunctionCall.js +37 -0
- package/built/rules/slowFunctionCall.js.map +1 -0
- package/built/rules/slowHttpServerRequest.js +24 -0
- package/built/rules/slowHttpServerRequest.js.map +1 -0
- package/built/rules/slowQuery.js +23 -0
- package/built/rules/slowQuery.js.map +1 -0
- package/built/rules/tooManyJoins.js +77 -0
- package/built/rules/tooManyJoins.js.map +1 -0
- package/built/rules/tooManyUpdates.js +143 -0
- package/built/rules/tooManyUpdates.js.map +1 -0
- package/built/rules/unbatchedMaterializedQuery.js +65 -0
- package/built/rules/unbatchedMaterializedQuery.js.map +1 -0
- package/built/rules/updateInGetRequest.js +66 -0
- package/built/rules/updateInGetRequest.js.map +1 -0
- package/built/rules/util.js +102 -0
- package/built/rules/util.js.map +1 -0
- package/built/sampleConfig/bike_index.yml +10 -0
- package/built/sampleConfig/default.yml +19 -0
- package/built/sampleConfig/railsSampleApp6thEd.yml +29 -0
- package/built/sampleConfig/solidus.yml +31 -0
- package/built/scope/commandScope.js +156 -0
- package/built/scope/commandScope.js.map +1 -0
- package/built/scope/httpClientRequestScope.js +105 -0
- package/built/scope/httpClientRequestScope.js.map +1 -0
- package/built/scope/httpServerRequestScope.js +105 -0
- package/built/scope/httpServerRequestScope.js.map +1 -0
- package/built/scope/rootScope.js +105 -0
- package/built/scope/rootScope.js.map +1 -0
- package/built/scope/scopeImpl.js +88 -0
- package/built/scope/scopeImpl.js.map +1 -0
- package/built/scope/scopeIterator.js +21 -0
- package/built/scope/scopeIterator.js.map +1 -0
- package/built/scope/sqlTransactionScope.js +175 -0
- package/built/scope/sqlTransactionScope.js.map +1 -0
- package/built/wellKnownLabels.js +9 -0
- package/built/wellKnownLabels.js.map +1 -0
- 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"}
|