@sun-asterisk/sunlint 1.3.44 → 1.3.45
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/core/cli-action-handler.js +4 -4
- package/core/output-service.js +2 -2
- package/core/output-service.js.debug.js +1 -0
- package/package.json +1 -1
- package/rules/common/C006_function_naming/typescript/analyzer.js +1 -2
- package/rules/common/C017_constructor_logic/typescript/symbol-based-analyzer.js +1 -1
- package/rules/common/C019_log_level_usage/typescript/system-log-analyzer.js +2 -2
- package/rules/common/C021_import_organization/typescript/ts-morph-analyzer.js +3 -3
- package/rules/common/C024_no_scatter_hardcoded_constants/typescript/symbol-based-analyzer.js +1 -1
- package/rules/common/C029_catch_block_logging/typescript/analyzer.js +1 -1
- package/rules/common/C040_centralized_validation/typescript/regex-based-analyzer.js +1 -1
- package/rules/common/C073_validate_required_config_on_startup/typescript/analyzer.js +1 -1
- package/rules/security/S042_require_re_authentication_for_long_lived/typescript/symbol-based-analyzer.js +9 -9
- package/rules/security/S043_password_changes_invalidate_all_sessions/typescript/symbol-based-analyzer.js +1 -1
- package/rules/security/S046_jwt_algorithm_allowlist/dart/analyzer.js +1 -1
- package/rules/security/S047_oauth_pkce_protection/dart/analyzer.js +1 -1
- package/rules/security/S050_reference_tokens_entropy/dart/analyzer.js +1 -1
- package/rules/security/S053_generic_error_messages/dart/analyzer.js +1 -1
- package/rules/security/S055_content_type_validation/typescript/symbol-based-analyzer.js +1 -1
- package/rules/security/S059_disable_debug_mode/dart/analyzer.js +1 -1
- package/rules/security/S060_password_minimum_length/dart/analyzer.js +1 -1
- package/rules/utils/severity-constants.js +0 -1
|
@@ -505,12 +505,12 @@ class CliActionHandler {
|
|
|
505
505
|
handleExit(results) {
|
|
506
506
|
if (this.options.noExit) return;
|
|
507
507
|
|
|
508
|
-
//
|
|
509
|
-
const
|
|
510
|
-
result.violations
|
|
508
|
+
// Only fail on errors, not warnings (ESLint-compatible behavior)
|
|
509
|
+
const hasErrors = results.results?.some(result =>
|
|
510
|
+
result.violations?.some(v => v.severity === 'error')
|
|
511
511
|
);
|
|
512
512
|
|
|
513
|
-
if (
|
|
513
|
+
if (hasErrors && this.options.failOnViolations !== false) {
|
|
514
514
|
process.exit(1);
|
|
515
515
|
} else {
|
|
516
516
|
process.exit(0);
|
package/core/output-service.js
CHANGED
|
@@ -273,10 +273,10 @@ class OutputService {
|
|
|
273
273
|
if (result.ruleId) {
|
|
274
274
|
result.violations.forEach(violation => {
|
|
275
275
|
if (isValidViolation(violation)) {
|
|
276
|
-
allViolations.push(violation);
|
|
276
|
+
allViolations.push(violation);
|
|
277
277
|
}
|
|
278
278
|
});
|
|
279
|
-
}
|
|
279
|
+
}
|
|
280
280
|
// Handle file-based format (legacy)
|
|
281
281
|
else {
|
|
282
282
|
result.violations.forEach(violation => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// temp debug
|
package/package.json
CHANGED
|
@@ -669,8 +669,7 @@ class SmartC006Analyzer {
|
|
|
669
669
|
|
|
670
670
|
getSeverityFromConfidence(confidence) {
|
|
671
671
|
if (confidence >= this.confidenceThresholds.HIGH) return 'warning';
|
|
672
|
-
|
|
673
|
-
return 'hint';
|
|
672
|
+
return 'warning';
|
|
674
673
|
}
|
|
675
674
|
}
|
|
676
675
|
|
|
@@ -299,7 +299,7 @@ class C017SymbolBasedAnalyzer {
|
|
|
299
299
|
|
|
300
300
|
violations.push({
|
|
301
301
|
ruleId: this.ruleId,
|
|
302
|
-
severity: '
|
|
302
|
+
severity: 'warning',
|
|
303
303
|
message: 'Constructor contains logging - side effects should be avoided',
|
|
304
304
|
source: this.ruleId,
|
|
305
305
|
file: filePath,
|
|
@@ -581,7 +581,7 @@ class C019SystemLogAnalyzer {
|
|
|
581
581
|
filePath: filePath,
|
|
582
582
|
line: logs[0].position.line,
|
|
583
583
|
column: logs[0].position.column,
|
|
584
|
-
severity: '
|
|
584
|
+
severity: 'warning',
|
|
585
585
|
category: 'performance',
|
|
586
586
|
confidence: this.config.overusedLogPatterns.hot_path_over_logging.confidence,
|
|
587
587
|
suggestion: this.config.overusedLogPatterns.hot_path_over_logging.suggestion,
|
|
@@ -697,7 +697,7 @@ class C019SystemLogAnalyzer {
|
|
|
697
697
|
filePath: filePath,
|
|
698
698
|
line: log2.position.line,
|
|
699
699
|
column: log2.position.column,
|
|
700
|
-
severity: '
|
|
700
|
+
severity: 'warning',
|
|
701
701
|
category: 'maintainability',
|
|
702
702
|
confidence: this.config.redundancyPatterns.duplicate_log_events.confidence,
|
|
703
703
|
suggestion: this.config.redundancyPatterns.duplicate_log_events.suggestion,
|
|
@@ -234,7 +234,7 @@ class C021TsMorphAnalyzer {
|
|
|
234
234
|
violations.push({
|
|
235
235
|
ruleId: this.ruleId,
|
|
236
236
|
message: `Import group "${misplacedGroup}" should come ${this.getOrderMessage(misplacedGroup, expectedFiltered, i)}`,
|
|
237
|
-
severity: '
|
|
237
|
+
severity: 'warning',
|
|
238
238
|
location: {
|
|
239
239
|
start: {
|
|
240
240
|
line: imports[0].line,
|
|
@@ -289,7 +289,7 @@ class C021TsMorphAnalyzer {
|
|
|
289
289
|
violations.push({
|
|
290
290
|
ruleId: this.ruleId,
|
|
291
291
|
message: `Import "${current}" should come after "${next}" (alphabetical order within ${groupName} group)`,
|
|
292
|
-
severity: '
|
|
292
|
+
severity: 'warning',
|
|
293
293
|
location: {
|
|
294
294
|
start: {
|
|
295
295
|
line: imports[i].line,
|
|
@@ -345,7 +345,7 @@ class C021TsMorphAnalyzer {
|
|
|
345
345
|
violations.push({
|
|
346
346
|
ruleId: this.ruleId,
|
|
347
347
|
message: `Missing blank line between "${nonEmptyGroups[i]}" and "${nonEmptyGroups[i + 1]}" import groups`,
|
|
348
|
-
severity: '
|
|
348
|
+
severity: 'warning',
|
|
349
349
|
location: {
|
|
350
350
|
start: {
|
|
351
351
|
line: lastLine,
|
package/rules/common/C024_no_scatter_hardcoded_constants/typescript/symbol-based-analyzer.js
CHANGED
|
@@ -388,7 +388,7 @@ class C024SymbolBasedAnalyzer {
|
|
|
388
388
|
createViolation(node, sourceFile, message, type, value) {
|
|
389
389
|
return {
|
|
390
390
|
ruleId: this.ruleId,
|
|
391
|
-
severity: '
|
|
391
|
+
severity: 'warning',
|
|
392
392
|
message: message,
|
|
393
393
|
source: this.ruleId,
|
|
394
394
|
file: sourceFile.getFilePath(),
|
|
@@ -114,7 +114,7 @@ class C040RegexBasedAnalyzer {
|
|
|
114
114
|
if (duplicatePatterns.length > 0) {
|
|
115
115
|
violations.push({
|
|
116
116
|
ruleId: this.ruleId,
|
|
117
|
-
severity: '
|
|
117
|
+
severity: 'warning',
|
|
118
118
|
message: `Found potentially duplicate validation patterns: ${duplicatePatterns.join(', ')}`,
|
|
119
119
|
file: filePath,
|
|
120
120
|
line: validationMatches[0].line,
|
|
@@ -714,7 +714,7 @@ class C073ConfigValidationAnalyzer {
|
|
|
714
714
|
if (isServiceFile && analysis.envAccess && analysis.envAccess.length > 0) {
|
|
715
715
|
violations.push({
|
|
716
716
|
ruleId: 'C073',
|
|
717
|
-
severity: '
|
|
717
|
+
severity: 'warning',
|
|
718
718
|
message: 'Service layer accessing environment variables directly. Consider using dependency injection for configuration.',
|
|
719
719
|
line: analysis.envAccess[0].line || 1,
|
|
720
720
|
column: 1,
|
|
@@ -173,7 +173,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
173
173
|
violations.push({
|
|
174
174
|
ruleId: this.ruleId,
|
|
175
175
|
ruleName: this.ruleName,
|
|
176
|
-
severity: '
|
|
176
|
+
severity: 'warning',
|
|
177
177
|
message: `Session maxAge is too long (${this.formatDuration(sessionConfig.maxAge)}). Consider limiting to 24 hours or less for security.`,
|
|
178
178
|
line: startLine,
|
|
179
179
|
column: node.getStart() - node.getStartLinePos() + 1,
|
|
@@ -191,7 +191,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
191
191
|
violations.push({
|
|
192
192
|
ruleId: this.ruleId,
|
|
193
193
|
ruleName: this.ruleName,
|
|
194
|
-
severity: '
|
|
194
|
+
severity: 'warning',
|
|
195
195
|
message: `Persistent session (Remember Me) enabled without re-authentication requirements for sensitive actions.`,
|
|
196
196
|
line: startLine,
|
|
197
197
|
column: node.getStart() - node.getStartLinePos() + 1,
|
|
@@ -209,7 +209,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
209
209
|
violations.push({
|
|
210
210
|
ruleId: this.ruleId,
|
|
211
211
|
ruleName: this.ruleName,
|
|
212
|
-
severity: '
|
|
212
|
+
severity: 'warning',
|
|
213
213
|
message: `Session configuration missing idle timeout. Consider adding inactivity-based expiration.`,
|
|
214
214
|
line: startLine,
|
|
215
215
|
column: node.getStart() - node.getStartLinePos() + 1,
|
|
@@ -420,7 +420,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
420
420
|
violations.push({
|
|
421
421
|
ruleId: this.ruleId,
|
|
422
422
|
ruleName: this.ruleName,
|
|
423
|
-
severity: '
|
|
423
|
+
severity: 'error',
|
|
424
424
|
message: `JWT token created without expiration configuration. Add expiresIn option.`,
|
|
425
425
|
line: startLine,
|
|
426
426
|
column: callExpr.getStart() - callExpr.getStartLinePos() + 1,
|
|
@@ -442,7 +442,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
442
442
|
violations.push({
|
|
443
443
|
ruleId: this.ruleId,
|
|
444
444
|
ruleName: this.ruleName,
|
|
445
|
-
severity: '
|
|
445
|
+
severity: 'error',
|
|
446
446
|
message: `JWT token created without expiration time. Tokens should have short expiry (e.g., 1 hour).`,
|
|
447
447
|
line: startLine,
|
|
448
448
|
column: callExpr.getStart() - callExpr.getStartLinePos() + 1,
|
|
@@ -463,7 +463,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
463
463
|
violations.push({
|
|
464
464
|
ruleId: this.ruleId,
|
|
465
465
|
ruleName: this.ruleName,
|
|
466
|
-
severity: '
|
|
466
|
+
severity: 'warning',
|
|
467
467
|
message: `JWT expiration is too long (${this.formatDuration(jwtConfig.expirationValue)}). Access tokens should expire within 1 hour.`,
|
|
468
468
|
line: startLine,
|
|
469
469
|
column: jwtConfig.expirationNode.getStart() - jwtConfig.expirationNode.getStartLinePos() + 1,
|
|
@@ -613,7 +613,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
613
613
|
violations.push({
|
|
614
614
|
ruleId: this.ruleId,
|
|
615
615
|
ruleName: this.ruleName,
|
|
616
|
-
severity: '
|
|
616
|
+
severity: 'error',
|
|
617
617
|
message: `Sensitive action '${funcName}' does not appear to require re-authentication.`,
|
|
618
618
|
line: startLine,
|
|
619
619
|
column: func.getStart() - func.getStartLinePos() + 1,
|
|
@@ -657,7 +657,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
657
657
|
violations.push({
|
|
658
658
|
ruleId: this.ruleId,
|
|
659
659
|
ruleName: this.ruleName,
|
|
660
|
-
severity: '
|
|
660
|
+
severity: 'warning',
|
|
661
661
|
message: `Remember Me feature implemented without apparent re-authentication requirements.`,
|
|
662
662
|
line: startLine,
|
|
663
663
|
column: node.getStart() - node.getStartLinePos() + 1,
|
|
@@ -687,7 +687,7 @@ class S042SymbolBasedAnalyzer {
|
|
|
687
687
|
violations.push({
|
|
688
688
|
ruleId: this.ruleId,
|
|
689
689
|
ruleName: this.ruleName,
|
|
690
|
-
severity: '
|
|
690
|
+
severity: 'warning',
|
|
691
691
|
message: `Session management detected but no idle timeout implementation found.`,
|
|
692
692
|
line: sessionConfigLocation.line,
|
|
693
693
|
column: sessionConfigLocation.column,
|
|
@@ -523,7 +523,7 @@ class S043SymbolBasedAnalyzer {
|
|
|
523
523
|
violations.push({
|
|
524
524
|
ruleId: this.ruleId,
|
|
525
525
|
ruleName: this.ruleName,
|
|
526
|
-
severity: '
|
|
526
|
+
severity: 'warning',
|
|
527
527
|
message: `Password change function "${functionName}" must invalidate all active sessions`,
|
|
528
528
|
line: startLine,
|
|
529
529
|
column: column,
|
|
@@ -389,7 +389,7 @@ class S055SymbolBasedAnalyzer {
|
|
|
389
389
|
violations.push({
|
|
390
390
|
ruleId: this.ruleId,
|
|
391
391
|
ruleName: this.ruleName,
|
|
392
|
-
severity: '
|
|
392
|
+
severity: 'warning',
|
|
393
393
|
message: `REST endpoint '${name}' does not validate Content-Type header. Add validation for 'application/json' or other expected types.`,
|
|
394
394
|
line: startLine,
|
|
395
395
|
column: node.getStart() - node.getStartLinePos() + 1,
|