@vee-stack/delta-cli 2.0.8 → 2.0.10
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/dist/adapters/analysis.adapter.d.ts +29 -0
- package/dist/analyzer/commands/analyze.d.ts +14 -0
- package/dist/analyzer/commands/config.d.ts +12 -0
- package/dist/analyzer/commands/report.d.ts +11 -0
- package/dist/analyzer/generators/report.generator.d.ts +43 -0
- package/dist/analyzer/index.d.ts +8 -0
- package/dist/analyzer/scanners/project.scanner.d.ts +29 -0
- package/dist/analyzer/validators/contracts.validator.d.ts +27 -0
- package/dist/analyzer/validators/maintainability.validator.d.ts +27 -0
- package/dist/analyzer/validators/observability.validator.d.ts +27 -0
- package/dist/analyzer/validators/performance.validator.d.ts +27 -0
- package/dist/analyzer/validators/security.validator.d.ts +27 -0
- package/dist/analyzer/validators/soc.validator.d.ts +27 -0
- package/dist/auth/device-auth.d.ts +18 -0
- package/dist/auth/secure-auth.d.ts +35 -0
- package/dist/bundle.mjs +422 -0
- package/dist/commands/analyze.d.ts +12 -0
- package/dist/commands/auth-new.d.ts +6 -0
- package/dist/commands/auth.d.ts +17 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/deploy.d.ts +5 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/plugins.d.ts +7 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/sync.d.ts +5 -0
- package/dist/commands/whoami.d.ts +4 -0
- package/dist/components/Dashboard.d.ts +8 -0
- package/dist/components/DeltaApp.d.ts +13 -0
- package/dist/components/UnifiedManager.d.ts +10 -0
- package/dist/core/audit.d.ts +60 -0
- package/dist/core/completion.d.ts +79 -0
- package/dist/core/contracts.d.ts +127 -0
- package/dist/core/engine.d.ts +26 -0
- package/dist/core/exit-codes.d.ts +19 -0
- package/dist/core/hooks.d.ts +50 -0
- package/dist/{apps/cli/src/core/index.js → core/index.d.ts} +1 -1
- package/dist/core/policy.d.ts +24 -0
- package/dist/core/profiles.d.ts +45 -0
- package/dist/core/wizard.d.ts +28 -0
- package/dist/interactive/index.d.ts +5 -0
- package/dist/plugins/GitStatusPlugin.d.ts +25 -0
- package/dist/providers/ai-provider.d.ts +21 -0
- package/dist/providers/local-provider.d.ts +21 -0
- package/dist/providers/remote-provider.d.ts +15 -0
- package/dist/telemetry/wrapper.d.ts +18 -0
- package/dist/types/api.d.ts +46 -0
- package/dist/ui.d.ts +52 -0
- package/dist/welcome.d.ts +8 -0
- package/package.json +8 -8
- package/dist/analyzer/commands/analyze.js +0 -260
- package/dist/analyzer/commands/config.js +0 -83
- package/dist/analyzer/commands/report.js +0 -38
- package/dist/analyzer/generators/report.generator.js +0 -123
- package/dist/analyzer/index.js +0 -44
- package/dist/analyzer/scanners/project.scanner.js +0 -92
- package/dist/analyzer/validators/contracts.validator.js +0 -42
- package/dist/analyzer/validators/maintainability.validator.js +0 -40
- package/dist/analyzer/validators/observability.validator.js +0 -39
- package/dist/analyzer/validators/performance.validator.js +0 -42
- package/dist/analyzer/validators/security.validator.js +0 -66
- package/dist/analyzer/validators/soc.validator.js +0 -75
- package/dist/apps/cli/src/analyzer/commands/analyze.js +0 -256
- package/dist/apps/cli/src/analyzer/commands/config.js +0 -83
- package/dist/apps/cli/src/analyzer/commands/report.js +0 -38
- package/dist/apps/cli/src/analyzer/generators/report.generator.js +0 -123
- package/dist/apps/cli/src/analyzer/index.js +0 -44
- package/dist/apps/cli/src/analyzer/scanners/project.scanner.js +0 -92
- package/dist/apps/cli/src/analyzer/validators/contracts.validator.js +0 -42
- package/dist/apps/cli/src/analyzer/validators/maintainability.validator.js +0 -40
- package/dist/apps/cli/src/analyzer/validators/observability.validator.js +0 -39
- package/dist/apps/cli/src/analyzer/validators/performance.validator.js +0 -42
- package/dist/apps/cli/src/analyzer/validators/security.validator.js +0 -66
- package/dist/apps/cli/src/analyzer/validators/soc.validator.js +0 -75
- package/dist/apps/cli/src/auth/secure-auth.js +0 -312
- package/dist/apps/cli/src/commands/analyze.js +0 -286
- package/dist/apps/cli/src/commands/auth-new.js +0 -37
- package/dist/apps/cli/src/commands/auth.js +0 -122
- package/dist/apps/cli/src/commands/config.js +0 -49
- package/dist/apps/cli/src/commands/deploy.js +0 -6
- package/dist/apps/cli/src/commands/init.js +0 -47
- package/dist/apps/cli/src/commands/logout.js +0 -23
- package/dist/apps/cli/src/commands/plugins.js +0 -21
- package/dist/apps/cli/src/commands/status.js +0 -80
- package/dist/apps/cli/src/commands/sync.js +0 -6
- package/dist/apps/cli/src/commands/whoami.js +0 -115
- package/dist/apps/cli/src/components/Dashboard.js +0 -168
- package/dist/apps/cli/src/components/DeltaApp.js +0 -56
- package/dist/apps/cli/src/components/UnifiedManager.js +0 -324
- package/dist/apps/cli/src/core/audit.js +0 -184
- package/dist/apps/cli/src/core/completion.js +0 -294
- package/dist/apps/cli/src/core/contracts.js +0 -6
- package/dist/apps/cli/src/core/engine.js +0 -124
- package/dist/apps/cli/src/core/exit-codes.js +0 -71
- package/dist/apps/cli/src/core/hooks.js +0 -181
- package/dist/apps/cli/src/core/policy.js +0 -115
- package/dist/apps/cli/src/core/profiles.js +0 -161
- package/dist/apps/cli/src/core/wizard.js +0 -203
- package/dist/apps/cli/src/index.js +0 -636
- package/dist/apps/cli/src/interactive/index.js +0 -11
- package/dist/apps/cli/src/plugins/GitStatusPlugin.js +0 -99
- package/dist/apps/cli/src/providers/ai-provider.js +0 -74
- package/dist/apps/cli/src/providers/local-provider.js +0 -302
- package/dist/apps/cli/src/providers/remote-provider.js +0 -100
- package/dist/apps/cli/src/types/api.js +0 -3
- package/dist/apps/cli/src/ui.js +0 -219
- package/dist/apps/cli/src/welcome.js +0 -81
- package/dist/auth/secure-auth.js +0 -372
- package/dist/bundle.js +0 -504
- package/dist/commands/analyze.js +0 -390
- package/dist/commands/auth-new.js +0 -37
- package/dist/commands/auth.js +0 -134
- package/dist/commands/config.js +0 -51
- package/dist/commands/deploy.js +0 -6
- package/dist/commands/init.js +0 -47
- package/dist/commands/logout.js +0 -31
- package/dist/commands/plugins.js +0 -21
- package/dist/commands/status.js +0 -82
- package/dist/commands/sync.js +0 -6
- package/dist/commands/whoami.js +0 -72
- package/dist/components/Dashboard.js +0 -169
- package/dist/components/DeltaApp.js +0 -57
- package/dist/components/UnifiedManager.js +0 -344
- package/dist/core/audit.js +0 -184
- package/dist/core/completion.js +0 -294
- package/dist/core/contracts.js +0 -6
- package/dist/core/engine.js +0 -124
- package/dist/core/exit-codes.js +0 -71
- package/dist/core/hooks.js +0 -181
- package/dist/core/index.js +0 -7
- package/dist/core/policy.js +0 -115
- package/dist/core/profiles.js +0 -161
- package/dist/core/wizard.js +0 -203
- package/dist/index.js +0 -387
- package/dist/interactive/index.js +0 -11
- package/dist/packages/domain/src/constitution/contracts/index.js +0 -43
- package/dist/packages/domain/src/constitution/contracts/ts.rules.js +0 -268
- package/dist/packages/domain/src/constitution/index.js +0 -139
- package/dist/packages/domain/src/constitution/maintainability/index.js +0 -43
- package/dist/packages/domain/src/constitution/maintainability/ts.rules.js +0 -344
- package/dist/packages/domain/src/constitution/observability/index.js +0 -43
- package/dist/packages/domain/src/constitution/observability/ts.rules.js +0 -307
- package/dist/packages/domain/src/constitution/performance/index.js +0 -43
- package/dist/packages/domain/src/constitution/performance/ts.rules.js +0 -325
- package/dist/packages/domain/src/constitution/security/index.js +0 -50
- package/dist/packages/domain/src/constitution/security/ts.rules.js +0 -267
- package/dist/packages/domain/src/constitution/soc/index.js +0 -43
- package/dist/packages/domain/src/constitution/soc/ts.rules.js +0 -360
- package/dist/packages/domain/src/contracts/analysis.contract.js +0 -18
- package/dist/packages/domain/src/contracts/index.js +0 -7
- package/dist/packages/domain/src/contracts/projects.contract.js +0 -18
- package/dist/packages/domain/src/control/registry/rules.registry.js +0 -29
- package/dist/packages/domain/src/control/schemas/policies.js +0 -6
- package/dist/packages/domain/src/core/analysis/discovery.js +0 -163
- package/dist/packages/domain/src/core/analysis/engine.contract.js +0 -298
- package/dist/packages/domain/src/core/analysis/engine.js +0 -77
- package/dist/packages/domain/src/core/analysis/index.js +0 -14
- package/dist/packages/domain/src/core/analysis/orchestrator.js +0 -242
- package/dist/packages/domain/src/core/comparison/engine.js +0 -29
- package/dist/packages/domain/src/core/comparison/index.js +0 -5
- package/dist/packages/domain/src/core/documentation/index.js +0 -5
- package/dist/packages/domain/src/core/documentation/pipeline.js +0 -41
- package/dist/packages/domain/src/core/fs/adapter.js +0 -111
- package/dist/packages/domain/src/core/fs/index.js +0 -5
- package/dist/packages/domain/src/core/parser/unified-parser.js +0 -166
- package/dist/packages/domain/src/index.js +0 -33
- package/dist/packages/domain/src/plugin/registry.js +0 -195
- package/dist/packages/domain/src/plugin/types.js +0 -6
- package/dist/packages/domain/src/ports/analysis.engine.js +0 -7
- package/dist/packages/domain/src/ports/audit.logger.js +0 -7
- package/dist/packages/domain/src/ports/project.repository.js +0 -7
- package/dist/packages/domain/src/rules/index.js +0 -134
- package/dist/packages/domain/src/types/analysis.js +0 -6
- package/dist/packages/domain/src/types/errors.js +0 -53
- package/dist/packages/domain/src/types/fs.js +0 -6
- package/dist/packages/domain/src/types/index.js +0 -7
- package/dist/plugins/GitStatusPlugin.js +0 -93
- package/dist/providers/ai-provider.js +0 -74
- package/dist/providers/local-provider.js +0 -304
- package/dist/providers/remote-provider.js +0 -100
- package/dist/types/api.js +0 -3
- package/dist/ui.js +0 -219
- package/dist/welcome.js +0 -81
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Maintainability Validator
|
|
3
|
-
* @description Validates Maintainability rules
|
|
4
|
-
*/
|
|
5
|
-
export class MaintainabilityValidator {
|
|
6
|
-
static async validate(project, _options) {
|
|
7
|
-
const violations = [];
|
|
8
|
-
let score = 100;
|
|
9
|
-
// Check for tests
|
|
10
|
-
const testFiles = project.files.filter(f => f.includes('.test.') || f.includes('.spec.'));
|
|
11
|
-
const testRatio = testFiles.length / (project.fileCount || 1);
|
|
12
|
-
if (testRatio < 0.1) {
|
|
13
|
-
violations.push({
|
|
14
|
-
id: 'MAINT-TEST-001',
|
|
15
|
-
severity: 'warning',
|
|
16
|
-
message: `Low test coverage: ${(testRatio * 100).toFixed(1)}% of files are tests`,
|
|
17
|
-
rule: 'Testing Required',
|
|
18
|
-
});
|
|
19
|
-
score -= 20;
|
|
20
|
-
}
|
|
21
|
-
// Check for documentation
|
|
22
|
-
const hasReadme = project.files.some(f => f.toLowerCase() === 'readme.md' || f.toLowerCase().endsWith('/readme.md'));
|
|
23
|
-
if (!hasReadme) {
|
|
24
|
-
violations.push({
|
|
25
|
-
id: 'MAINT-DOC-001',
|
|
26
|
-
severity: 'warning',
|
|
27
|
-
message: 'No README.md found',
|
|
28
|
-
rule: 'Documentation Required',
|
|
29
|
-
});
|
|
30
|
-
score -= 10;
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
score: Math.max(0, score),
|
|
34
|
-
maxScore: 100,
|
|
35
|
-
percentage: Math.max(0, score),
|
|
36
|
-
violations,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=maintainability.validator.js.map
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Observability Validator
|
|
3
|
-
* @description Validates Observability rules
|
|
4
|
-
*/
|
|
5
|
-
export class ObservabilityValidator {
|
|
6
|
-
static async validate(project, _options) {
|
|
7
|
-
const violations = [];
|
|
8
|
-
let score = 100;
|
|
9
|
-
// Check for health endpoint
|
|
10
|
-
const hasHealthEndpoint = project.files.some(f => f.includes('health') || f.includes('ready') || f.includes('live'));
|
|
11
|
-
if (!hasHealthEndpoint) {
|
|
12
|
-
violations.push({
|
|
13
|
-
id: 'OBS-HEALTH-001',
|
|
14
|
-
severity: 'warning',
|
|
15
|
-
message: 'No health check endpoint found',
|
|
16
|
-
rule: 'Health Checks Required',
|
|
17
|
-
});
|
|
18
|
-
score -= 20;
|
|
19
|
-
}
|
|
20
|
-
// Check for logging
|
|
21
|
-
const hasLogging = project.files.some(f => f.includes('logger') || f.includes('log'));
|
|
22
|
-
if (!hasLogging) {
|
|
23
|
-
violations.push({
|
|
24
|
-
id: 'OBS-LOG-001',
|
|
25
|
-
severity: 'warning',
|
|
26
|
-
message: 'No logging implementation found',
|
|
27
|
-
rule: 'Structured Logging Required',
|
|
28
|
-
});
|
|
29
|
-
score -= 20;
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
score: Math.max(0, score),
|
|
33
|
-
maxScore: 100,
|
|
34
|
-
percentage: Math.max(0, score),
|
|
35
|
-
violations,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=observability.validator.js.map
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Performance Validator
|
|
3
|
-
* @description Validates performance rules
|
|
4
|
-
*/
|
|
5
|
-
export class PerformanceValidator {
|
|
6
|
-
static async validate(project, _options) {
|
|
7
|
-
const violations = [];
|
|
8
|
-
let score = 100;
|
|
9
|
-
// Check for lazy loading patterns
|
|
10
|
-
const hasDynamicImports = project.files.some(f => {
|
|
11
|
-
// Would check file content for dynamic imports
|
|
12
|
-
return f.includes('dynamic') || f.includes('lazy');
|
|
13
|
-
});
|
|
14
|
-
if (!hasDynamicImports && project.fileCount > 50) {
|
|
15
|
-
violations.push({
|
|
16
|
-
id: 'PERF-LAZY-001',
|
|
17
|
-
severity: 'warning',
|
|
18
|
-
message: 'No lazy loading patterns detected in large project',
|
|
19
|
-
rule: 'Lazy Loading Recommended',
|
|
20
|
-
});
|
|
21
|
-
score -= 10;
|
|
22
|
-
}
|
|
23
|
-
// Check for caching implementation
|
|
24
|
-
const hasCaching = project.files.some(f => f.includes('cache') || f.includes('redis') || f.includes('swr'));
|
|
25
|
-
if (!hasCaching) {
|
|
26
|
-
violations.push({
|
|
27
|
-
id: 'PERF-CACHE-001',
|
|
28
|
-
severity: 'warning',
|
|
29
|
-
message: 'No caching implementation found',
|
|
30
|
-
rule: 'Caching Layer Recommended',
|
|
31
|
-
});
|
|
32
|
-
score -= 15;
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
score: Math.max(0, score),
|
|
36
|
-
maxScore: 100,
|
|
37
|
-
percentage: Math.max(0, score),
|
|
38
|
-
violations,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=performance.validator.js.map
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Security Validator
|
|
3
|
-
* @description Validates security rules against project
|
|
4
|
-
*/
|
|
5
|
-
export class SecurityValidator {
|
|
6
|
-
static async validate(project, options) {
|
|
7
|
-
const violations = [];
|
|
8
|
-
let score = 100;
|
|
9
|
-
// Check 1: Policy Registry exists
|
|
10
|
-
const hasPolicyRegistry = project.directories.some(d => d.includes('modules') && d.includes('policies'));
|
|
11
|
-
if (!hasPolicyRegistry) {
|
|
12
|
-
violations.push({
|
|
13
|
-
id: 'SEC-POL-002',
|
|
14
|
-
severity: 'error',
|
|
15
|
-
message: 'Missing policies/ directory in modules',
|
|
16
|
-
rule: 'Policy Registry Required',
|
|
17
|
-
});
|
|
18
|
-
score -= 15;
|
|
19
|
-
}
|
|
20
|
-
// Check 2: Audit logging
|
|
21
|
-
const hasAuditFile = project.files.some(f => f.includes('audit') || f.includes('logger'));
|
|
22
|
-
if (!hasAuditFile) {
|
|
23
|
-
violations.push({
|
|
24
|
-
id: 'SEC-AUDIT-001',
|
|
25
|
-
severity: 'warning',
|
|
26
|
-
message: 'No audit logging implementation found',
|
|
27
|
-
rule: 'Audit Logging Required',
|
|
28
|
-
});
|
|
29
|
-
score -= 10;
|
|
30
|
-
}
|
|
31
|
-
// Check 3: Rate limiting
|
|
32
|
-
const hasRateLimit = project.files.some(f => f.includes('rate') || f.includes('limit'));
|
|
33
|
-
if (!hasRateLimit) {
|
|
34
|
-
violations.push({
|
|
35
|
-
id: 'SEC-RATE-001',
|
|
36
|
-
severity: 'warning',
|
|
37
|
-
message: 'No rate limiting implementation found',
|
|
38
|
-
rule: 'Rate Limiting Required',
|
|
39
|
-
});
|
|
40
|
-
score -= 10;
|
|
41
|
-
}
|
|
42
|
-
// Check 4: Security directory
|
|
43
|
-
const hasSecurityDir = project.directories.some(d => d.includes('security'));
|
|
44
|
-
if (!hasSecurityDir) {
|
|
45
|
-
violations.push({
|
|
46
|
-
id: 'SEC-DIR-001',
|
|
47
|
-
severity: 'error',
|
|
48
|
-
message: 'Missing security/ directory',
|
|
49
|
-
rule: 'Security Layer Required',
|
|
50
|
-
});
|
|
51
|
-
score -= 15;
|
|
52
|
-
}
|
|
53
|
-
// Deep scan for Fail-Open patterns (if requested)
|
|
54
|
-
if (options.depth === 'deep') {
|
|
55
|
-
// This would scan file contents for fail-open patterns
|
|
56
|
-
// For now, just check structure
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
score: Math.max(0, score),
|
|
60
|
-
maxScore: 100,
|
|
61
|
-
percentage: Math.max(0, score),
|
|
62
|
-
violations,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
//# sourceMappingURL=security.validator.js.map
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SoC Validator
|
|
3
|
-
* @description Validates Separation of Concerns rules
|
|
4
|
-
*/
|
|
5
|
-
export class SocValidator {
|
|
6
|
-
static async validate(project, _options) {
|
|
7
|
-
const violations = [];
|
|
8
|
-
let score = 100;
|
|
9
|
-
// Check for proper layer structure
|
|
10
|
-
const hasFeatures = project.directories.some(d => d.includes('features'));
|
|
11
|
-
const hasModules = project.directories.some(d => d.includes('modules'));
|
|
12
|
-
const hasCore = project.directories.some(d => d.includes('core'));
|
|
13
|
-
const hasContracts = project.directories.some(d => d.includes('contracts'));
|
|
14
|
-
if (!hasFeatures) {
|
|
15
|
-
violations.push({
|
|
16
|
-
id: 'SOC-LAYER-001',
|
|
17
|
-
severity: 'error',
|
|
18
|
-
message: 'Missing features/ layer',
|
|
19
|
-
rule: '7-Layer Architecture',
|
|
20
|
-
});
|
|
21
|
-
score -= 20;
|
|
22
|
-
}
|
|
23
|
-
if (!hasModules) {
|
|
24
|
-
violations.push({
|
|
25
|
-
id: 'SOC-LAYER-002',
|
|
26
|
-
severity: 'error',
|
|
27
|
-
message: 'Missing modules/ layer',
|
|
28
|
-
rule: '7-Layer Architecture',
|
|
29
|
-
});
|
|
30
|
-
score -= 20;
|
|
31
|
-
}
|
|
32
|
-
if (!hasCore) {
|
|
33
|
-
violations.push({
|
|
34
|
-
id: 'SOC-LAYER-003',
|
|
35
|
-
severity: 'error',
|
|
36
|
-
message: 'Missing core/ layer',
|
|
37
|
-
rule: '7-Layer Architecture',
|
|
38
|
-
});
|
|
39
|
-
score -= 20;
|
|
40
|
-
}
|
|
41
|
-
if (!hasContracts) {
|
|
42
|
-
violations.push({
|
|
43
|
-
id: 'SOC-LAYER-004',
|
|
44
|
-
severity: 'warning',
|
|
45
|
-
message: 'Missing contracts/ layer',
|
|
46
|
-
rule: '7-Layer Architecture',
|
|
47
|
-
});
|
|
48
|
-
score -= 10;
|
|
49
|
-
}
|
|
50
|
-
// Check feature structure
|
|
51
|
-
if (hasFeatures) {
|
|
52
|
-
const featureDirs = project.directories.filter(d => d.startsWith('features/'));
|
|
53
|
-
for (const featureDir of featureDirs) {
|
|
54
|
-
const hasComponents = project.directories.some(d => d.startsWith(`${featureDir}/components`));
|
|
55
|
-
const hasHooks = project.directories.some(d => d.startsWith(`${featureDir}/hooks`));
|
|
56
|
-
if (!hasComponents || !hasHooks) {
|
|
57
|
-
violations.push({
|
|
58
|
-
id: 'SOC-FEAT-001',
|
|
59
|
-
severity: 'warning',
|
|
60
|
-
message: `Feature ${featureDir} missing components/ or hooks/`,
|
|
61
|
-
rule: 'Feature Structure',
|
|
62
|
-
});
|
|
63
|
-
score -= 5;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
score: Math.max(0, score),
|
|
69
|
-
maxScore: 100,
|
|
70
|
-
percentage: Math.max(0, score),
|
|
71
|
-
violations,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
//# sourceMappingURL=soc.validator.js.map
|
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Secure Authentication System with OAuth2 + Keychain Integration
|
|
3
|
-
* Features:
|
|
4
|
-
* - OAuth2 PKCE flow
|
|
5
|
-
* - Secure token storage in OS keychain
|
|
6
|
-
* - Automatic token refresh
|
|
7
|
-
* - Session management
|
|
8
|
-
* - PAT (Personal Access Token) support for CI/CD
|
|
9
|
-
*/
|
|
10
|
-
import keytar from 'keytar';
|
|
11
|
-
import fetch from 'node-fetch';
|
|
12
|
-
import open from 'open';
|
|
13
|
-
import { createServer } from 'http';
|
|
14
|
-
import { URL } from 'url';
|
|
15
|
-
import crypto from 'crypto';
|
|
16
|
-
import chalk from 'chalk';
|
|
17
|
-
import { printSuccess, printError, printInfo, startSpinner, stopSpinner } from '../ui.js';
|
|
18
|
-
const SERVICE_NAME = 'delta-cli';
|
|
19
|
-
const ACCOUNT_NAME = 'user-token';
|
|
20
|
-
const REFRESH_ACCOUNT = 'refresh-token';
|
|
21
|
-
// PKCE Code Generator
|
|
22
|
-
function generatePKCE() {
|
|
23
|
-
const verifier = crypto.randomBytes(32).toString('base64url');
|
|
24
|
-
const challenge = crypto
|
|
25
|
-
.createHash('sha256')
|
|
26
|
-
.update(verifier)
|
|
27
|
-
.digest('base64url');
|
|
28
|
-
return { verifier, challenge };
|
|
29
|
-
}
|
|
30
|
-
// Secure Token Storage
|
|
31
|
-
export class SecureTokenStore {
|
|
32
|
-
static async saveAccessToken(token) {
|
|
33
|
-
await keytar.setPassword(SERVICE_NAME, ACCOUNT_NAME, token);
|
|
34
|
-
}
|
|
35
|
-
static async getAccessToken() {
|
|
36
|
-
return await keytar.getPassword(SERVICE_NAME, ACCOUNT_NAME);
|
|
37
|
-
}
|
|
38
|
-
static async saveRefreshToken(token) {
|
|
39
|
-
await keytar.setPassword(SERVICE_NAME, REFRESH_ACCOUNT, token);
|
|
40
|
-
}
|
|
41
|
-
static async getRefreshToken() {
|
|
42
|
-
return await keytar.getPassword(SERVICE_NAME, REFRESH_ACCOUNT);
|
|
43
|
-
}
|
|
44
|
-
static async clearTokens() {
|
|
45
|
-
await keytar.deletePassword(SERVICE_NAME, ACCOUNT_NAME);
|
|
46
|
-
await keytar.deletePassword(SERVICE_NAME, REFRESH_ACCOUNT);
|
|
47
|
-
}
|
|
48
|
-
static async hasTokens() {
|
|
49
|
-
const token = await this.getAccessToken();
|
|
50
|
-
return !!token;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
// OAuth2 Flow Handler
|
|
54
|
-
export async function startOAuthFlow(method = 'oauth') {
|
|
55
|
-
startSpinner('Starting OAuth2 authentication flow...');
|
|
56
|
-
try {
|
|
57
|
-
const { verifier, challenge } = generatePKCE();
|
|
58
|
-
const redirectUri = 'http://localhost:3456/callback';
|
|
59
|
-
const state = crypto.randomBytes(16).toString('hex');
|
|
60
|
-
// Build OAuth URL
|
|
61
|
-
const oauthUrl = new URL('https://api.delta.dev/auth/authorize');
|
|
62
|
-
oauthUrl.searchParams.set('response_type', 'code');
|
|
63
|
-
oauthUrl.searchParams.set('client_id', 'delta-cli');
|
|
64
|
-
oauthUrl.searchParams.set('redirect_uri', redirectUri);
|
|
65
|
-
oauthUrl.searchParams.set('code_challenge', challenge);
|
|
66
|
-
oauthUrl.searchParams.set('code_challenge_method', 'S256');
|
|
67
|
-
oauthUrl.searchParams.set('state', state);
|
|
68
|
-
oauthUrl.searchParams.set('scope', 'read write analyze');
|
|
69
|
-
if (method === 'github') {
|
|
70
|
-
oauthUrl.searchParams.set('provider', 'github');
|
|
71
|
-
}
|
|
72
|
-
else if (method === 'google') {
|
|
73
|
-
oauthUrl.searchParams.set('provider', 'google');
|
|
74
|
-
}
|
|
75
|
-
stopSpinner(true, 'OAuth server ready');
|
|
76
|
-
// Open browser
|
|
77
|
-
printInfo('Opening browser for authentication...');
|
|
78
|
-
await open(oauthUrl.toString());
|
|
79
|
-
// Start local server to capture callback
|
|
80
|
-
const authCode = await new Promise((resolve, reject) => {
|
|
81
|
-
const server = createServer(async (req, res) => {
|
|
82
|
-
const url = new URL(req.url || '/', `http://localhost:3456`);
|
|
83
|
-
if (url.pathname === '/callback') {
|
|
84
|
-
const code = url.searchParams.get('code');
|
|
85
|
-
const returnedState = url.searchParams.get('state');
|
|
86
|
-
const error = url.searchParams.get('error');
|
|
87
|
-
if (error) {
|
|
88
|
-
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
89
|
-
res.end(`
|
|
90
|
-
<html>
|
|
91
|
-
<body style="font-family: system-ui; text-align: center; padding: 50px;">
|
|
92
|
-
<h1 style="color: #e74c3c;">❌ Authentication Failed</h1>
|
|
93
|
-
<p>${error}</p>
|
|
94
|
-
<p>You can close this window.</p>
|
|
95
|
-
</body>
|
|
96
|
-
</html>
|
|
97
|
-
`);
|
|
98
|
-
reject(new Error(error));
|
|
99
|
-
server.close();
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
if (!code || returnedState !== state) {
|
|
103
|
-
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
104
|
-
res.end(`
|
|
105
|
-
<html>
|
|
106
|
-
<body style="font-family: system-ui; text-align: center; padding: 50px;">
|
|
107
|
-
<h1 style="color: #e74c3c;">❌ Invalid Response</h1>
|
|
108
|
-
<p>You can close this window.</p>
|
|
109
|
-
</body>
|
|
110
|
-
</html>
|
|
111
|
-
`);
|
|
112
|
-
reject(new Error('Invalid OAuth response'));
|
|
113
|
-
server.close();
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
117
|
-
res.end(`
|
|
118
|
-
<html>
|
|
119
|
-
<head>
|
|
120
|
-
<style>
|
|
121
|
-
body {
|
|
122
|
-
font-family: system-ui, -apple-system, sans-serif;
|
|
123
|
-
text-align: center;
|
|
124
|
-
padding: 50px;
|
|
125
|
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
126
|
-
color: white;
|
|
127
|
-
min-height: 100vh;
|
|
128
|
-
display: flex;
|
|
129
|
-
align-items: center;
|
|
130
|
-
justify-content: center;
|
|
131
|
-
}
|
|
132
|
-
.container {
|
|
133
|
-
background: rgba(255,255,255,0.1);
|
|
134
|
-
backdrop-filter: blur(10px);
|
|
135
|
-
padding: 40px;
|
|
136
|
-
border-radius: 20px;
|
|
137
|
-
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
138
|
-
}
|
|
139
|
-
h1 { margin: 0 0 20px; font-size: 48px; }
|
|
140
|
-
.check { font-size: 64px; margin-bottom: 20px; }
|
|
141
|
-
p { font-size: 18px; opacity: 0.9; }
|
|
142
|
-
</style>
|
|
143
|
-
</head>
|
|
144
|
-
<body>
|
|
145
|
-
<div class="container">
|
|
146
|
-
<div class="check">✓</div>
|
|
147
|
-
<h1>Successfully Signed In!</h1>
|
|
148
|
-
<p>You can close this window and return to the terminal.</p>
|
|
149
|
-
</div>
|
|
150
|
-
</body>
|
|
151
|
-
</html>
|
|
152
|
-
`);
|
|
153
|
-
resolve(code);
|
|
154
|
-
server.close();
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
server.listen(3456, () => {
|
|
158
|
-
console.log(chalk.dim(' Waiting for authentication...'));
|
|
159
|
-
});
|
|
160
|
-
// Timeout after 5 minutes
|
|
161
|
-
setTimeout(() => {
|
|
162
|
-
server.close();
|
|
163
|
-
reject(new Error('Authentication timeout'));
|
|
164
|
-
}, 5 * 60 * 1000);
|
|
165
|
-
});
|
|
166
|
-
// Exchange code for tokens
|
|
167
|
-
startSpinner('Exchanging authorization code...');
|
|
168
|
-
const tokenResponse = await fetch('https://api.delta.dev/auth/token', {
|
|
169
|
-
method: 'POST',
|
|
170
|
-
headers: { 'Content-Type': 'application/json' },
|
|
171
|
-
body: JSON.stringify({
|
|
172
|
-
grant_type: 'authorization_code',
|
|
173
|
-
code: authCode,
|
|
174
|
-
redirect_uri: redirectUri,
|
|
175
|
-
client_id: 'delta-cli',
|
|
176
|
-
code_verifier: verifier,
|
|
177
|
-
}),
|
|
178
|
-
});
|
|
179
|
-
if (!tokenResponse.ok) {
|
|
180
|
-
throw new Error('Failed to exchange authorization code');
|
|
181
|
-
}
|
|
182
|
-
const tokens = await tokenResponse.json();
|
|
183
|
-
// Store tokens securely
|
|
184
|
-
await SecureTokenStore.saveAccessToken(tokens.access_token);
|
|
185
|
-
await SecureTokenStore.saveRefreshToken(tokens.refresh_token);
|
|
186
|
-
stopSpinner(true, 'Authentication successful!');
|
|
187
|
-
printSuccess('Successfully authenticated with Delta Cloud');
|
|
188
|
-
printInfo(`Token expires in ${tokens.expires_in} seconds`);
|
|
189
|
-
return true;
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
stopSpinner(false, 'Authentication failed');
|
|
193
|
-
printError('OAuth2 authentication failed', error.message);
|
|
194
|
-
return false;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
// PAT Authentication for CI/CD
|
|
198
|
-
export async function authenticateWithPAT(token) {
|
|
199
|
-
startSpinner('Validating Personal Access Token...');
|
|
200
|
-
try {
|
|
201
|
-
// Validate token
|
|
202
|
-
const response = await fetch('https://api.delta.dev/auth/verify', {
|
|
203
|
-
headers: {
|
|
204
|
-
'Authorization': `Bearer ${token}`,
|
|
205
|
-
},
|
|
206
|
-
});
|
|
207
|
-
if (!response.ok) {
|
|
208
|
-
throw new Error('Invalid token');
|
|
209
|
-
}
|
|
210
|
-
const data = await response.json();
|
|
211
|
-
// Store token
|
|
212
|
-
await SecureTokenStore.saveAccessToken(token);
|
|
213
|
-
stopSpinner(true, 'Token validated');
|
|
214
|
-
printSuccess(`Authenticated as ${data.user.email}`);
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
catch (error) {
|
|
218
|
-
stopSpinner(false, 'Token validation failed');
|
|
219
|
-
printError('PAT authentication failed', error.message);
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
// Token Refresh
|
|
224
|
-
export async function refreshAccessToken() {
|
|
225
|
-
const refreshToken = await SecureTokenStore.getRefreshToken();
|
|
226
|
-
if (!refreshToken) {
|
|
227
|
-
printError('No refresh token available');
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
try {
|
|
231
|
-
const response = await fetch('https://api.delta.dev/auth/refresh', {
|
|
232
|
-
method: 'POST',
|
|
233
|
-
headers: { 'Content-Type': 'application/json' },
|
|
234
|
-
body: JSON.stringify({
|
|
235
|
-
grant_type: 'refresh_token',
|
|
236
|
-
refresh_token: refreshToken,
|
|
237
|
-
client_id: 'delta-cli',
|
|
238
|
-
}),
|
|
239
|
-
});
|
|
240
|
-
if (!response.ok) {
|
|
241
|
-
throw new Error('Token refresh failed');
|
|
242
|
-
}
|
|
243
|
-
const tokens = await response.json();
|
|
244
|
-
await SecureTokenStore.saveAccessToken(tokens.access_token);
|
|
245
|
-
if (tokens.refresh_token) {
|
|
246
|
-
await SecureTokenStore.saveRefreshToken(tokens.refresh_token);
|
|
247
|
-
}
|
|
248
|
-
return true;
|
|
249
|
-
}
|
|
250
|
-
catch (error) {
|
|
251
|
-
printError('Failed to refresh token', error.message);
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
// Logout
|
|
256
|
-
export async function logout() {
|
|
257
|
-
startSpinner('Clearing credentials...');
|
|
258
|
-
try {
|
|
259
|
-
await SecureTokenStore.clearTokens();
|
|
260
|
-
stopSpinner(true, 'Logged out');
|
|
261
|
-
printSuccess('Successfully logged out');
|
|
262
|
-
}
|
|
263
|
-
catch (error) {
|
|
264
|
-
stopSpinner(false, 'Logout failed');
|
|
265
|
-
printError('Failed to clear credentials', error.message);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
// Auth Status
|
|
269
|
-
export async function getAuthStatus() {
|
|
270
|
-
const token = await SecureTokenStore.getAccessToken();
|
|
271
|
-
if (!token) {
|
|
272
|
-
return { authenticated: false };
|
|
273
|
-
}
|
|
274
|
-
try {
|
|
275
|
-
const response = await fetch('https://api.delta.dev/auth/me', {
|
|
276
|
-
headers: {
|
|
277
|
-
'Authorization': `Bearer ${token}`,
|
|
278
|
-
},
|
|
279
|
-
});
|
|
280
|
-
if (!response.ok) {
|
|
281
|
-
// Try to refresh token
|
|
282
|
-
const refreshed = await refreshAccessToken();
|
|
283
|
-
if (!refreshed) {
|
|
284
|
-
return { authenticated: false };
|
|
285
|
-
}
|
|
286
|
-
// Retry with new token
|
|
287
|
-
const newToken = await SecureTokenStore.getAccessToken();
|
|
288
|
-
const retryResponse = await fetch('https://api.delta.dev/auth/me', {
|
|
289
|
-
headers: {
|
|
290
|
-
'Authorization': `Bearer ${newToken}`,
|
|
291
|
-
},
|
|
292
|
-
});
|
|
293
|
-
if (!retryResponse.ok) {
|
|
294
|
-
return { authenticated: false };
|
|
295
|
-
}
|
|
296
|
-
const userData = await retryResponse.json();
|
|
297
|
-
return {
|
|
298
|
-
authenticated: true,
|
|
299
|
-
user: userData,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
const userData = await response.json();
|
|
303
|
-
return {
|
|
304
|
-
authenticated: true,
|
|
305
|
-
user: userData,
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
catch {
|
|
309
|
-
return { authenticated: false };
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
//# sourceMappingURL=secure-auth.js.map
|