x-fidelity 3.10.0 → 3.12.0
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/.github/CODEOWNERS +15 -0
- package/.xfi-config.json +19 -1
- package/CHANGELOG.md +49 -0
- package/dist/core/cli.js +2 -1
- package/dist/core/engine/analyzer.js +3 -1
- package/dist/demoConfig/node-fullstack.json +15 -1
- package/dist/demoConfig/rules/newSdkFeatureNotAdoped-global-rule.json +2 -2
- package/dist/demoConfig/rules/noDatabases-iterative-rule.json +5 -1
- package/dist/demoConfig/rules/sensitiveLogging-iterative-rule.json +1 -3
- package/dist/facts/repoFilesystemFacts.js +7 -7
- package/dist/index.js +26 -0
- package/dist/index.test.js +1 -0
- package/dist/notifications/index.d.ts +3 -0
- package/dist/notifications/index.js +120 -0
- package/dist/notifications/notificationManager.d.ts +19 -0
- package/dist/notifications/notificationManager.js +344 -0
- package/dist/notifications/notifications.test.d.ts +1 -0
- package/dist/notifications/notifications.test.js +100 -0
- package/dist/notifications/providers/emailProvider.d.ts +17 -0
- package/dist/notifications/providers/emailProvider.js +94 -0
- package/dist/notifications/providers/slackProvider.d.ts +11 -0
- package/dist/notifications/providers/slackProvider.js +67 -0
- package/dist/notifications/providers/teamsProvider.d.ts +10 -0
- package/dist/notifications/providers/teamsProvider.js +95 -0
- package/dist/types/notificationTypes.d.ts +22 -0
- package/dist/types/notificationTypes.js +2 -0
- package/dist/types/typeDefs.d.ts +11 -0
- package/dist/utils/jsonSchemas.js +53 -0
- package/dist/xfidelity +26 -0
- package/package.json +4 -1
- package/src/core/cli.ts +2 -1
- package/src/core/engine/analyzer.ts +3 -1
- package/src/demoConfig/node-fullstack.json +15 -1
- package/src/demoConfig/rules/newSdkFeatureNotAdoped-global-rule.json +2 -2
- package/src/demoConfig/rules/noDatabases-iterative-rule.json +5 -1
- package/src/demoConfig/rules/sensitiveLogging-iterative-rule.json +1 -3
- package/src/facts/repoFilesystemFacts.ts +7 -7
- package/src/index.test.ts +1 -0
- package/src/index.ts +35 -1
- package/src/notifications/index.ts +119 -0
- package/src/notifications/notificationManager.ts +381 -0
- package/src/notifications/notifications.test.ts +116 -0
- package/src/notifications/providers/emailProvider.ts +98 -0
- package/src/notifications/providers/slackProvider.ts +63 -0
- package/src/notifications/providers/teamsProvider.ts +89 -0
- package/src/types/notificationTypes.ts +25 -0
- package/src/types/typeDefs.ts +11 -0
- package/src/utils/jsonSchemas.ts +53 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Default owners for everything in the repo
|
|
2
|
+
* @zotoio/core-team
|
|
3
|
+
|
|
4
|
+
# Specific ownership rules
|
|
5
|
+
/src/core/ @zotoio/core-team
|
|
6
|
+
/src/facts/ @zotoio/rules-team
|
|
7
|
+
/src/operators/ @zotoio/rules-team
|
|
8
|
+
/src/plugins/ @zotoio/plugin-team
|
|
9
|
+
/src/server/ @zotoio/api-team
|
|
10
|
+
/src/types/ @zotoio/core-team
|
|
11
|
+
/src/utils/ @zotoio/core-team
|
|
12
|
+
/website/ @zotoio/docs-team
|
|
13
|
+
|
|
14
|
+
# Notification test team
|
|
15
|
+
/src/notifications/ @zotoio/notification-team
|
package/.xfi-config.json
CHANGED
|
@@ -34,5 +34,23 @@
|
|
|
34
34
|
],
|
|
35
35
|
"additionalFacts": ["customFact"],
|
|
36
36
|
"additionalOperators": ["customOperator"],
|
|
37
|
-
"additionalPlugins": ["xfiPluginSimpleExample"]
|
|
37
|
+
"additionalPlugins": ["xfiPluginSimpleExample"],
|
|
38
|
+
"notifications": {
|
|
39
|
+
"recipients": {
|
|
40
|
+
"email": [
|
|
41
|
+
"io@zoto.io"
|
|
42
|
+
],
|
|
43
|
+
"slack": [
|
|
44
|
+
"U123456",
|
|
45
|
+
"U789012"
|
|
46
|
+
],
|
|
47
|
+
"teams": [
|
|
48
|
+
"user1@example.com",
|
|
49
|
+
"user2@example.com"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"codeOwners": true,
|
|
53
|
+
"notifyOnSuccess": false,
|
|
54
|
+
"notifyOnFailure": true
|
|
55
|
+
}
|
|
38
56
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,52 @@
|
|
|
1
|
+
# [3.12.0](https://github.com/zotoio/x-fidelity/compare/v3.11.0...v3.12.0) (2025-03-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add HTML email support with plain text fallback ([ec0f252](https://github.com/zotoio/x-fidelity/commit/ec0f2529d4f05ca570cd4b11db07ede2d4d21113))
|
|
7
|
+
* correct string interpolation syntax in notification template ([092b64d](https://github.com/zotoio/x-fidelity/commit/092b64d3f614d505c7a792bd7a559e10aed3192c))
|
|
8
|
+
* correct template literal syntax in notification manager ([f5720c2](https://github.com/zotoio/x-fidelity/commit/f5720c230051d8e38bbc95024a02d7298d2299f5))
|
|
9
|
+
* escape nested template literals in notification template ([4feb497](https://github.com/zotoio/x-fidelity/commit/4feb497255615b93655ba7bba8729e55b56b4016))
|
|
10
|
+
* **notify:** email formatting fixes ([06e80a8](https://github.com/zotoio/x-fidelity/commit/06e80a81bab30c1ab03d202d0649306fe331debd))
|
|
11
|
+
* remove duplicate fileIssues declaration in notification manager ([d5678a1](https://github.com/zotoio/x-fidelity/commit/d5678a1620fae5b78ee475b95ee2248051d17c8f))
|
|
12
|
+
* remove local directory paths from notification file links ([d55da96](https://github.com/zotoio/x-fidelity/commit/d55da9637477b0b14acb45d99a8a1a4b9e661c30))
|
|
13
|
+
* remove trailing comma in .xfi-config.json ([41c7368](https://github.com/zotoio/x-fidelity/commit/41c7368a7e7ba8b989f3d8bf2fc0ce9e3e4d1183))
|
|
14
|
+
* replace nested template literals with string concatenation ([89712cf](https://github.com/zotoio/x-fidelity/commit/89712cf77e231863e5bcb6c214fedf5b9f0d1f3f))
|
|
15
|
+
* resolve TypeScript errors with yaml imports and variable declarations ([af2ea8e](https://github.com/zotoio/x-fidelity/commit/af2ea8ee80d48b9dddb1f586d61285518aee0b1c))
|
|
16
|
+
* use repoPath from results metadata instead of undefined variable ([36b42fa](https://github.com/zotoio/x-fidelity/commit/36b42fae14895ba147955806efcf3cc94ec1d306))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* add failed rule names to notification template for each file ([d09d019](https://github.com/zotoio/x-fidelity/commit/d09d019bc1f9eff2f5c375185aec7f8f54fb7f96))
|
|
22
|
+
* add severity levels to failed rules in notification output ([a90ffe7](https://github.com/zotoio/x-fidelity/commit/a90ffe724c440f60f1f1c59be0ec3074316c28c1))
|
|
23
|
+
* add YAML results attachment to email notifications ([e2671b4](https://github.com/zotoio/x-fidelity/commit/e2671b46081168b1ac911f595a05f3301f8df780))
|
|
24
|
+
* enhance notification formatting with HTML and color-coded severity ([f034a85](https://github.com/zotoio/x-fidelity/commit/f034a858c0da629d7fc134818babcbf28fa7b03e))
|
|
25
|
+
* enhance notification templates with clickable links and emojis ([3afbd5d](https://github.com/zotoio/x-fidelity/commit/3afbd5db68cfbb604407e791f58c184961e7dc78))
|
|
26
|
+
* support GitHub Enterprise links in notifications ([092867f](https://github.com/zotoio/x-fidelity/commit/092867fd3948e1bfcc10e8ecfc312686f37c9afa))
|
|
27
|
+
* use git commands to extract GitHub repo details ([8f35471](https://github.com/zotoio/x-fidelity/commit/8f3547145a612444b9320c0b5d1b75529edfaa4a))
|
|
28
|
+
|
|
29
|
+
# [3.11.0](https://github.com/zotoio/x-fidelity/compare/v3.10.0...v3.11.0) (2025-03-09)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
* Remove duplicate import statement in notifications test ([f5c6468](https://github.com/zotoio/x-fidelity/commit/f5c6468063c1575610cd4b54aad84b97d4884437))
|
|
35
|
+
* **results:** fix missing filesystem match details ([bc62faf](https://github.com/zotoio/x-fidelity/commit/bc62faff20e69fa6977e1ceee1bc22ad578cf2ba))
|
|
36
|
+
* update NotificationManager mock to properly handle registerProvider ([6102837](https://github.com/zotoio/x-fidelity/commit/6102837f206938500885faf33560a91235a41885))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Features
|
|
40
|
+
|
|
41
|
+
* add CODEOWNERS and notification test config ([5dc2904](https://github.com/zotoio/x-fidelity/commit/5dc29047d86f33b27fc9603077884b4df3f37330))
|
|
42
|
+
* add debug logging for notification flow ([0e6af6b](https://github.com/zotoio/x-fidelity/commit/0e6af6b1583636935561f85a33c0bbea830905a5))
|
|
43
|
+
* add detailed debug logging for email notifications ([18d929b](https://github.com/zotoio/x-fidelity/commit/18d929b3cc49b538c6ea3330d51d2670b090f7ba))
|
|
44
|
+
* add email notification configuration to node-fullstack archetype ([424c5a0](https://github.com/zotoio/x-fidelity/commit/424c5a007c1b9eabeaffbca375cac131142ff7c9))
|
|
45
|
+
* add notification system with email, slack and teams providers ([95d4ade](https://github.com/zotoio/x-fidelity/commit/95d4ade7de8db30c1592087ffa8dd78845c4ee47))
|
|
46
|
+
* add notification team to CODEOWNERS file ([edb648e](https://github.com/zotoio/x-fidelity/commit/edb648e7378239ae7b6f672b9ce73c97e820a82a))
|
|
47
|
+
* add package version to XFI_RESULT metadata ([1ee061a](https://github.com/zotoio/x-fidelity/commit/1ee061a971bbf63d18014f529a3353d4efb63482))
|
|
48
|
+
* add xfiVersion field to ResultMetadata interface ([e59b187](https://github.com/zotoio/x-fidelity/commit/e59b18725b98781f547e58c5d9581d2ad7d5949f))
|
|
49
|
+
|
|
1
50
|
# [3.10.0](https://github.com/zotoio/x-fidelity/compare/v3.9.1...v3.10.0) (2025-03-08)
|
|
2
51
|
|
|
3
52
|
|
package/dist/core/cli.js
CHANGED
|
@@ -35,7 +35,8 @@ function initCLI() {
|
|
|
35
35
|
info: (obj) => console.log(JSON.stringify(obj)),
|
|
36
36
|
error: (obj) => console.error(JSON.stringify(obj)),
|
|
37
37
|
warn: (obj) => console.warn(JSON.stringify(obj)),
|
|
38
|
-
debug: (obj) => console.debug(JSON.stringify(obj))
|
|
38
|
+
debug: (obj) => console.debug(JSON.stringify(obj)),
|
|
39
|
+
trace: (obj) => console.trace(JSON.stringify(obj))
|
|
39
40
|
};
|
|
40
41
|
global.logger = fallbackLogger;
|
|
41
42
|
}
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.analyzeCodebase = analyzeCodebase;
|
|
13
13
|
const logger_1 = require("../../utils/logger");
|
|
14
14
|
const configManager_1 = require("../configManager");
|
|
15
|
+
const package_json_1 = require("../../../package.json");
|
|
15
16
|
const openaiUtils_1 = require("../../utils/openaiUtils");
|
|
16
17
|
const telemetry_1 = require("../../utils/telemetry");
|
|
17
18
|
const repoFilesystemFacts_1 = require("../../facts/repoFilesystemFacts");
|
|
@@ -172,7 +173,8 @@ function analyzeCodebase(params) {
|
|
|
172
173
|
exemptCount: exemptCount,
|
|
173
174
|
options: cli_1.options,
|
|
174
175
|
repoPath,
|
|
175
|
-
repoUrl
|
|
176
|
+
repoUrl,
|
|
177
|
+
xfiVersion: package_json_1.version
|
|
176
178
|
}
|
|
177
179
|
};
|
|
178
180
|
// Send telemetry for analysis end
|
|
@@ -59,6 +59,20 @@
|
|
|
59
59
|
".*\\.(ts|tsx|js|jsx)$",
|
|
60
60
|
".*\\/xfiTestMatch\\.json$",
|
|
61
61
|
".*\\/README\\.md$"
|
|
62
|
-
]
|
|
62
|
+
],
|
|
63
|
+
"notifications": {
|
|
64
|
+
"enabled": true,
|
|
65
|
+
"providers": ["email"],
|
|
66
|
+
"recipients": {
|
|
67
|
+
"email": ["io@zoto.io"]
|
|
68
|
+
},
|
|
69
|
+
"codeOwners": true,
|
|
70
|
+
"notifyOnSuccess": true,
|
|
71
|
+
"notifyOnFailure": true,
|
|
72
|
+
"customTemplates": {
|
|
73
|
+
"success": "All checks passed successfully! 🎉\n\nArchetype: ${archetype}\nFiles analyzed: ${fileCount}\nExecution time: ${executionTime}s",
|
|
74
|
+
"failure": "Issues found in codebase:\n\nArchetype: ${archetype}\nTotal issues: ${totalIssues}\n- Warnings: ${warningCount}\n- Errors: ${errorCount}\n- Fatalities: ${fatalityCount}\n\nAffected files:\n${affectedFiles}"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
63
77
|
}
|
|
64
78
|
}
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"fact": "globalFileAnalysis",
|
|
13
13
|
"params": {
|
|
14
14
|
"newPatterns": [
|
|
15
|
-
"
|
|
15
|
+
"const plugin: XFiPlugin = {"
|
|
16
16
|
],
|
|
17
17
|
"legacyPatterns": [
|
|
18
|
-
"
|
|
18
|
+
"import {.*FactDefn.*} from '\\.\\./types/typeDefs';"
|
|
19
19
|
],
|
|
20
20
|
"fileFilter": ".*\\.(ts|js)$",
|
|
21
21
|
"resultFact": "sdkUsageAnalysis"
|
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
{
|
|
12
12
|
"fact": "repoFileAnalysis",
|
|
13
13
|
"params": {
|
|
14
|
-
"checkPattern": [
|
|
14
|
+
"checkPattern": [
|
|
15
|
+
"[\\s\\'\\\"\\.](oracle)[\\s\\'\\\"\\.]",
|
|
16
|
+
"[\\s\\'\\\"\\.](postgres)[\\s\\'\\\"\\.]",
|
|
17
|
+
"[\\s\\'\\\"\\.](mongodb)[\\s\\'\\\"\\.]"
|
|
18
|
+
],
|
|
15
19
|
"resultFact": "fileResultsDB"
|
|
16
20
|
},
|
|
17
21
|
"operator": "fileContains",
|
|
@@ -23,11 +23,9 @@
|
|
|
23
23
|
"checkPattern": [
|
|
24
24
|
"(api[_-]?key|auth[_-]?token|access[_-]?token|secret[_-]?key)",
|
|
25
25
|
"(aws[_-]?access[_-]?key[_-]?id|aws[_-]?secret[_-]?access[_-]?key)",
|
|
26
|
-
"(password|passphrase)",
|
|
27
26
|
"(private[_-]?key|ssh[_-]?key)",
|
|
28
27
|
"(oauth[_-]?token|jwt[_-]?token)",
|
|
29
|
-
"db[_-]?password"
|
|
30
|
-
"(declare)"
|
|
28
|
+
"db[_-]?password"
|
|
31
29
|
],
|
|
32
30
|
"resultFact": "fileResults"
|
|
33
31
|
},
|
|
@@ -130,11 +130,11 @@ function repoFileAnalysis(params, almanac) {
|
|
|
130
130
|
return result;
|
|
131
131
|
}
|
|
132
132
|
//if there is already a resultFact for this file, we need to append
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
const existingResult = almanac.factValue(params.resultFact);
|
|
134
|
+
if (Object.keys(existingResult).includes('result')) {
|
|
135
|
+
logger_1.logger.error(JSON.stringify(existingResult));
|
|
136
|
+
result.result = existingResult.result;
|
|
137
|
+
}
|
|
138
138
|
const analysis = [];
|
|
139
139
|
const lines = fileContent.split('\n');
|
|
140
140
|
logger_1.logger.debug({ lineCount: lines.length }, 'Processing file lines');
|
|
@@ -196,8 +196,8 @@ function repoFileAnalysis(params, almanac) {
|
|
|
196
196
|
result.result[resultLength + i] = fileAnalysis[i];
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
-
|
|
200
|
-
almanac.addRuntimeFact(params.resultFact, result);
|
|
199
|
+
result.result = analysis;
|
|
200
|
+
almanac.addRuntimeFact(params.resultFact, result.result);
|
|
201
201
|
return result;
|
|
202
202
|
// testing match on 'oracle'
|
|
203
203
|
// testing match on 'declare'
|
package/dist/index.js
CHANGED
|
@@ -62,6 +62,7 @@ const prettyjson_1 = __importDefault(require("prettyjson"));
|
|
|
62
62
|
const analyzer_1 = require("./core/engine/analyzer");
|
|
63
63
|
const configServer_1 = require("./server/configServer");
|
|
64
64
|
const telemetry_1 = require("./utils/telemetry");
|
|
65
|
+
const notifications_1 = require("./notifications");
|
|
65
66
|
// Function to handle errors and send telemetry
|
|
66
67
|
const handleError = (error) => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
68
|
yield (0, telemetry_1.sendTelemetry)({
|
|
@@ -85,6 +86,16 @@ logger_1.logger.debug({ options: cli_1.options }, 'Startup options');
|
|
|
85
86
|
function main() {
|
|
86
87
|
return __awaiter(this, void 0, void 0, function* () {
|
|
87
88
|
try {
|
|
89
|
+
// Initialize notification system
|
|
90
|
+
const notificationConfig = {
|
|
91
|
+
enabled: process.env.NOTIFICATIONS_ENABLED === 'true',
|
|
92
|
+
providers: (process.env.NOTIFICATION_PROVIDERS || '').split(',').filter(Boolean),
|
|
93
|
+
codeOwnersPath: process.env.CODEOWNERS_PATH || '.github/CODEOWNERS',
|
|
94
|
+
codeOwnersEnabled: process.env.CODEOWNERS_ENABLED !== 'false', // Default to true
|
|
95
|
+
notifyOnSuccess: process.env.NOTIFY_ON_SUCCESS === 'true',
|
|
96
|
+
notifyOnFailure: process.env.NOTIFY_ON_FAILURE !== 'false', // Default to true
|
|
97
|
+
};
|
|
98
|
+
const notificationManager = yield (0, notifications_1.initializeNotifications)(notificationConfig);
|
|
88
99
|
if (cli_1.options.examine && process.env.NODE_ENV !== 'test') {
|
|
89
100
|
const { validateArchetypeConfig } = yield Promise.resolve().then(() => __importStar(require('./core/validateConfig')));
|
|
90
101
|
validateArchetypeConfig();
|
|
@@ -103,6 +114,21 @@ function main() {
|
|
|
103
114
|
});
|
|
104
115
|
const resultString = JSON.stringify(resultMetadata);
|
|
105
116
|
const prettyResult = prettyjson_1.default.render(resultMetadata.XFI_RESULT);
|
|
117
|
+
// Add debug logging before notification check
|
|
118
|
+
logger_1.logger.debug({
|
|
119
|
+
notificationsEnabled: process.env.NOTIFICATIONS_ENABLED,
|
|
120
|
+
notificationConfig: notificationConfig,
|
|
121
|
+
hasNotificationManager: !!notificationManager
|
|
122
|
+
}, 'Checking notification status');
|
|
123
|
+
// Send notifications if enabled
|
|
124
|
+
if (notificationConfig.enabled) {
|
|
125
|
+
logger_1.logger.debug('Notifications are enabled, preparing to send report');
|
|
126
|
+
logger_1.logger.debug({
|
|
127
|
+
affectedFilesCount: resultMetadata.XFI_RESULT.issueDetails.length
|
|
128
|
+
}, 'Preparing notification data');
|
|
129
|
+
// Pass the repo config to the notification manager
|
|
130
|
+
yield notificationManager.sendReport(resultMetadata);
|
|
131
|
+
}
|
|
106
132
|
// if results are found, there were issues found in the codebase
|
|
107
133
|
if (resultMetadata.XFI_RESULT.totalIssues > 0) {
|
|
108
134
|
logger_1.logger.warn(`WARNING: lo-fi attributes detected in codebase. ${resultMetadata.XFI_RESULT.warningCount} are warnings, ${resultMetadata.XFI_RESULT.fatalityCount} are fatal.`);
|
package/dist/index.test.js
CHANGED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.initializeNotifications = initializeNotifications;
|
|
13
|
+
const notificationManager_1 = require("./notificationManager");
|
|
14
|
+
const emailProvider_1 = require("./providers/emailProvider");
|
|
15
|
+
const slackProvider_1 = require("./providers/slackProvider");
|
|
16
|
+
const teamsProvider_1 = require("./providers/teamsProvider");
|
|
17
|
+
const logger_1 = require("../utils/logger");
|
|
18
|
+
function initializeNotifications(config) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
if (!config.enabled) {
|
|
21
|
+
logger_1.logger.info('Notifications are disabled');
|
|
22
|
+
return notificationManager_1.NotificationManager.getInstance(config);
|
|
23
|
+
}
|
|
24
|
+
const notificationManager = notificationManager_1.NotificationManager.getInstance(config);
|
|
25
|
+
// Register configured providers
|
|
26
|
+
for (const providerName of config.providers) {
|
|
27
|
+
switch (providerName) {
|
|
28
|
+
case 'email':
|
|
29
|
+
const emailConfig = loadEmailConfig();
|
|
30
|
+
if (emailConfig) {
|
|
31
|
+
notificationManager.registerProvider(new emailProvider_1.EmailProvider(emailConfig));
|
|
32
|
+
}
|
|
33
|
+
break;
|
|
34
|
+
case 'slack':
|
|
35
|
+
const slackConfig = loadSlackConfig();
|
|
36
|
+
if (slackConfig) {
|
|
37
|
+
notificationManager.registerProvider(new slackProvider_1.SlackProvider(slackConfig));
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
case 'teams':
|
|
41
|
+
const teamsConfig = loadTeamsConfig();
|
|
42
|
+
if (teamsConfig) {
|
|
43
|
+
notificationManager.registerProvider(new teamsProvider_1.TeamsProvider(teamsConfig));
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
logger_1.logger.warn(`Unknown notification provider: ${providerName}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return notificationManager;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function loadEmailConfig() {
|
|
54
|
+
try {
|
|
55
|
+
const config = {
|
|
56
|
+
host: process.env.NOTIFICATION_EMAIL_HOST || '',
|
|
57
|
+
port: parseInt(process.env.NOTIFICATION_EMAIL_PORT || '587'),
|
|
58
|
+
secure: process.env.NOTIFICATION_EMAIL_SECURE === 'true',
|
|
59
|
+
auth: {
|
|
60
|
+
user: process.env.NOTIFICATION_EMAIL_USER || '',
|
|
61
|
+
pass: process.env.NOTIFICATION_EMAIL_PASS || '',
|
|
62
|
+
},
|
|
63
|
+
from: process.env.NOTIFICATION_EMAIL_FROM || 'x-fidelity@noreply.com',
|
|
64
|
+
};
|
|
65
|
+
// Add debug logging
|
|
66
|
+
logger_1.logger.debug({
|
|
67
|
+
emailConfig: Object.assign(Object.assign({}, config), { auth: {
|
|
68
|
+
user: config.auth.user,
|
|
69
|
+
pass: '****' // Mask password
|
|
70
|
+
} })
|
|
71
|
+
}, 'Email configuration loaded');
|
|
72
|
+
// Validate required fields
|
|
73
|
+
if (!config.host || !config.auth.user || !config.auth.pass) {
|
|
74
|
+
logger_1.logger.warn('Missing required email configuration fields', {
|
|
75
|
+
hasHost: !!config.host,
|
|
76
|
+
hasUser: !!config.auth.user,
|
|
77
|
+
hasPass: !!config.auth.pass
|
|
78
|
+
});
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return config;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
logger_1.logger.error(error, 'Failed to load email configuration');
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function loadSlackConfig() {
|
|
89
|
+
try {
|
|
90
|
+
const webhookUrl = process.env.NOTIFICATION_SLACK_WEBHOOK;
|
|
91
|
+
if (!webhookUrl) {
|
|
92
|
+
logger_1.logger.warn('Slack webhook URL not configured');
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
webhookUrl,
|
|
97
|
+
channel: process.env.NOTIFICATION_SLACK_CHANNEL,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
logger_1.logger.error(error, 'Failed to load Slack configuration');
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function loadTeamsConfig() {
|
|
106
|
+
try {
|
|
107
|
+
const webhookUrl = process.env.NOTIFICATION_TEAMS_WEBHOOK;
|
|
108
|
+
if (!webhookUrl) {
|
|
109
|
+
logger_1.logger.warn('Teams webhook URL not configured');
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
webhookUrl
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
logger_1.logger.error(error, 'Failed to load Teams configuration');
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ResultMetadata } from '../types/typeDefs';
|
|
2
|
+
import { NotificationProvider, NotificationConfig } from '../types/notificationTypes';
|
|
3
|
+
export declare class NotificationManager {
|
|
4
|
+
private static instance;
|
|
5
|
+
private providers;
|
|
6
|
+
private config;
|
|
7
|
+
private codeOwners;
|
|
8
|
+
private constructor();
|
|
9
|
+
static getInstance(config: NotificationConfig): NotificationManager;
|
|
10
|
+
registerProvider(provider: NotificationProvider): void;
|
|
11
|
+
sendReport(results: ResultMetadata): Promise<void>;
|
|
12
|
+
private mergeNotificationConfig;
|
|
13
|
+
private getRecipients;
|
|
14
|
+
private loadCodeOwners;
|
|
15
|
+
private getCodeOwnersForFiles;
|
|
16
|
+
private matchesGlob;
|
|
17
|
+
private getAffectedFiles;
|
|
18
|
+
private generateReportContent;
|
|
19
|
+
}
|