@skillsmith/core 0.4.9 → 0.4.11
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/README.md +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/analysis/__tests__/incremental.test.d.ts +1 -1
- package/dist/src/analysis/__tests__/incremental.test.js +1 -1
- package/dist/src/analysis/__tests__/integration.test.d.ts +1 -1
- package/dist/src/analysis/__tests__/integration.test.js +1 -1
- package/dist/src/analysis/__tests__/performance.test.d.ts +1 -1
- package/dist/src/analysis/__tests__/performance.test.js +1 -1
- package/dist/src/analysis/adapters/__tests__/python.test.d.ts +1 -1
- package/dist/src/analysis/adapters/__tests__/python.test.js +1 -1
- package/dist/src/analysis/adapters/__tests__/typescript.test.d.ts +1 -1
- package/dist/src/analysis/adapters/__tests__/typescript.test.js +1 -1
- package/dist/src/analysis/adapters/base.d.ts +1 -1
- package/dist/src/analysis/adapters/base.js +1 -1
- package/dist/src/analysis/adapters/factory.d.ts +1 -1
- package/dist/src/analysis/adapters/factory.js +1 -1
- package/dist/src/analysis/adapters/go.d.ts +1 -1
- package/dist/src/analysis/adapters/go.js +1 -1
- package/dist/src/analysis/adapters/index.d.ts +1 -1
- package/dist/src/analysis/adapters/index.js +1 -1
- package/dist/src/analysis/adapters/java-parsers.d.ts +1 -1
- package/dist/src/analysis/adapters/java-parsers.d.ts.map +1 -1
- package/dist/src/analysis/adapters/java-parsers.js +10 -3
- package/dist/src/analysis/adapters/java-parsers.js.map +1 -1
- package/dist/src/analysis/adapters/java.d.ts +1 -1
- package/dist/src/analysis/adapters/java.js +1 -1
- package/dist/src/analysis/adapters/python-frameworks.d.ts +1 -1
- package/dist/src/analysis/adapters/python-frameworks.js +1 -1
- package/dist/src/analysis/adapters/python.d.ts +1 -1
- package/dist/src/analysis/adapters/python.js +1 -1
- package/dist/src/analysis/adapters/rust-parsers.d.ts +1 -1
- package/dist/src/analysis/adapters/rust-parsers.js +1 -1
- package/dist/src/analysis/adapters/rust.d.ts +1 -1
- package/dist/src/analysis/adapters/rust.js +1 -1
- package/dist/src/analysis/adapters/typescript.d.ts +1 -1
- package/dist/src/analysis/adapters/typescript.js +1 -1
- package/dist/src/analysis/aggregator.d.ts +1 -1
- package/dist/src/analysis/aggregator.js +1 -1
- package/dist/src/analysis/cache.d.ts +1 -1
- package/dist/src/analysis/cache.js +1 -1
- package/dist/src/analysis/file-streamer.d.ts +1 -1
- package/dist/src/analysis/file-streamer.js +1 -1
- package/dist/src/analysis/incremental-parser.d.ts +1 -1
- package/dist/src/analysis/incremental-parser.js +1 -1
- package/dist/src/analysis/incremental.d.ts +1 -1
- package/dist/src/analysis/incremental.js +1 -1
- package/dist/src/analysis/index.d.ts +1 -1
- package/dist/src/analysis/index.js +1 -1
- package/dist/src/analysis/language-detector.d.ts +1 -1
- package/dist/src/analysis/language-detector.js +1 -1
- package/dist/src/analysis/memory-monitor.d.ts +1 -1
- package/dist/src/analysis/memory-monitor.js +1 -1
- package/dist/src/analysis/metrics.d.ts +1 -1
- package/dist/src/analysis/metrics.js +1 -1
- package/dist/src/analysis/router.d.ts +1 -1
- package/dist/src/analysis/router.js +1 -1
- package/dist/src/analysis/tree-cache.d.ts +1 -1
- package/dist/src/analysis/tree-cache.js +1 -1
- package/dist/src/analysis/tree-sitter/manager.d.ts +1 -1
- package/dist/src/analysis/tree-sitter/manager.js +1 -1
- package/dist/src/analysis/types.d.ts +1 -1
- package/dist/src/analysis/types.js +1 -1
- package/dist/src/analysis/worker-pool.d.ts +1 -1
- package/dist/src/analysis/worker-pool.js +1 -1
- package/dist/src/analysis/worker-types.d.ts +1 -1
- package/dist/src/analysis/worker-types.js +1 -1
- package/dist/src/analysis/worker-utils.d.ts +1 -1
- package/dist/src/analysis/worker-utils.js +1 -1
- package/dist/src/api/client.d.ts +1 -0
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/schemas.d.ts +11 -4
- package/dist/src/api/schemas.d.ts.map +1 -1
- package/dist/src/api/schemas.js +8 -1
- package/dist/src/api/schemas.js.map +1 -1
- package/dist/src/config/index.d.ts +49 -1
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js +166 -3
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/index.test.d.ts +11 -0
- package/dist/src/config/index.test.d.ts.map +1 -0
- package/dist/src/config/index.test.js +288 -0
- package/dist/src/config/index.test.js.map +1 -0
- package/dist/src/db/drivers/betterSqlite3Driver.d.ts.map +1 -1
- package/dist/src/db/drivers/betterSqlite3Driver.js +5 -3
- package/dist/src/db/drivers/betterSqlite3Driver.js.map +1 -1
- package/dist/src/db/quarantine-approvals-schema.d.ts +37 -0
- package/dist/src/db/quarantine-approvals-schema.d.ts.map +1 -0
- package/dist/src/db/quarantine-approvals-schema.js +71 -0
- package/dist/src/db/quarantine-approvals-schema.js.map +1 -0
- package/dist/src/exports/services.d.ts +1 -0
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.js +4 -0
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/indexer/SkillParser.d.ts +20 -0
- package/dist/src/indexer/SkillParser.d.ts.map +1 -1
- package/dist/src/indexer/SkillParser.js +58 -0
- package/dist/src/indexer/SkillParser.js.map +1 -1
- package/dist/src/repositories/quarantine/ApprovalRepository.d.ts +148 -0
- package/dist/src/repositories/quarantine/ApprovalRepository.d.ts.map +1 -0
- package/dist/src/repositories/quarantine/ApprovalRepository.js +212 -0
- package/dist/src/repositories/quarantine/ApprovalRepository.js.map +1 -0
- package/dist/src/repositories/quarantine/QuarantineRepository.d.ts.map +1 -1
- package/dist/src/repositories/quarantine/QuarantineRepository.js +4 -1
- package/dist/src/repositories/quarantine/QuarantineRepository.js.map +1 -1
- package/dist/src/repositories/quarantine/index.d.ts +2 -0
- package/dist/src/repositories/quarantine/index.d.ts.map +1 -1
- package/dist/src/repositories/quarantine/index.js +1 -0
- package/dist/src/repositories/quarantine/index.js.map +1 -1
- package/dist/src/scripts/validation/types.d.ts +2 -2
- package/dist/src/security/audit-types.d.ts +2 -2
- package/dist/src/security/audit-types.d.ts.map +1 -1
- package/dist/src/security/audit-types.js.map +1 -1
- package/dist/src/security/sanitization.d.ts.map +1 -1
- package/dist/src/security/sanitization.js +25 -17
- package/dist/src/security/sanitization.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.formatters.js +1 -1
- package/dist/src/security/scanner/SecurityScanner.formatters.js.map +1 -1
- package/dist/src/services/index.d.ts +9 -0
- package/dist/src/services/index.d.ts.map +1 -0
- package/dist/src/services/index.js +10 -0
- package/dist/src/services/index.js.map +1 -0
- package/dist/src/services/quarantine/QuarantineService.d.ts +157 -0
- package/dist/src/services/quarantine/QuarantineService.d.ts.map +1 -0
- package/dist/src/services/quarantine/QuarantineService.js +464 -0
- package/dist/src/services/quarantine/QuarantineService.js.map +1 -0
- package/dist/src/services/quarantine/index.d.ts +10 -0
- package/dist/src/services/quarantine/index.d.ts.map +1 -0
- package/dist/src/services/quarantine/index.js +14 -0
- package/dist/src/services/quarantine/index.js.map +1 -0
- package/dist/src/services/quarantine/types.d.ts +127 -0
- package/dist/src/services/quarantine/types.d.ts.map +1 -0
- package/dist/src/services/quarantine/types.js +59 -0
- package/dist/src/services/quarantine/types.js.map +1 -0
- package/dist/src/types/skill.d.ts +6 -1
- package/dist/src/types/skill.d.ts.map +1 -1
- package/dist/src/types/skill.js.map +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +2 -0
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/safe-fs.d.ts +63 -0
- package/dist/src/utils/safe-fs.d.ts.map +1 -0
- package/dist/src/utils/safe-fs.js +119 -0
- package/dist/src/utils/safe-fs.js.map +1 -0
- package/dist/src/validation/input-validators.d.ts.map +1 -1
- package/dist/src/validation/input-validators.js +11 -4
- package/dist/src/validation/input-validators.js.map +1 -1
- package/dist/tests/QuarantineRepository.test.js +39 -2
- package/dist/tests/QuarantineRepository.test.js.map +1 -1
- package/dist/tests/RawUrlSourceAdapter.security.test.js +2 -1
- package/dist/tests/RawUrlSourceAdapter.security.test.js.map +1 -1
- package/dist/tests/SecurityScanner.test.js +2 -2
- package/dist/tests/SecurityScanner.test.js.map +1 -1
- package/dist/tests/adapters-factory.test.d.ts +1 -1
- package/dist/tests/adapters-factory.test.js +1 -1
- package/dist/tests/edge-cases/EdgeCases.test.js +5 -2
- package/dist/tests/edge-cases/EdgeCases.test.js.map +1 -1
- package/dist/tests/integration/QuarantineService.test.d.ts +11 -0
- package/dist/tests/integration/QuarantineService.test.d.ts.map +1 -0
- package/dist/tests/integration/QuarantineService.test.js +426 -0
- package/dist/tests/integration/QuarantineService.test.js.map +1 -0
- package/dist/tests/integration/neural/e2e-learning.test.d.ts +1 -1
- package/dist/tests/integration/neural/e2e-learning.test.js +1 -1
- package/dist/tests/integration/neural/personalization.test.d.ts +1 -1
- package/dist/tests/integration/neural/personalization.test.js +1 -1
- package/dist/tests/integration/neural/preference-learner.test.d.ts +1 -1
- package/dist/tests/integration/neural/preference-learner.test.js +1 -1
- package/dist/tests/integration/neural/privacy.test.d.ts +1 -1
- package/dist/tests/integration/neural/privacy.test.js +1 -1
- package/dist/tests/integration/neural/signal-collection.test.d.ts +1 -1
- package/dist/tests/integration/neural/signal-collection.test.js +1 -1
- package/dist/tests/language-detector.test.d.ts +1 -1
- package/dist/tests/language-detector.test.js +1 -1
- package/dist/tests/unit/approval-repository.test.d.ts +9 -0
- package/dist/tests/unit/approval-repository.test.d.ts.map +1 -0
- package/dist/tests/unit/approval-repository.test.js +509 -0
- package/dist/tests/unit/approval-repository.test.js.map +1 -0
- package/dist/tests/unit/check-references.test.d.ts +2 -0
- package/dist/tests/unit/check-references.test.d.ts.map +1 -0
- package/dist/tests/unit/check-references.test.js +118 -0
- package/dist/tests/unit/check-references.test.js.map +1 -0
- package/dist/tests/utils/safe-fs.test.d.ts +12 -0
- package/dist/tests/utils/safe-fs.test.d.ts.map +1 -0
- package/dist/tests/utils/safe-fs.test.js +116 -0
- package/dist/tests/utils/safe-fs.test.js.map +1 -0
- package/package.json +14 -10
- package/dist/tests/db/driver-parity.integration.test.d.ts +0 -16
- package/dist/tests/db/driver-parity.integration.test.d.ts.map +0 -1
- package/dist/tests/db/driver-parity.integration.test.js +0 -555
- package/dist/tests/db/driver-parity.integration.test.js.map +0 -1
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-2269: QuarantineService Integration Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for authenticated quarantine review operations including:
|
|
5
|
+
* - Session validation
|
|
6
|
+
* - Permission checks (security_reviewer role)
|
|
7
|
+
* - Multi-approval workflow for MALICIOUS severity
|
|
8
|
+
* - Audit logging with verified identities
|
|
9
|
+
*/
|
|
10
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
11
|
+
import { QuarantineService } from '../../src/services/quarantine/QuarantineService.js';
|
|
12
|
+
import { QuarantineServiceError } from '../../src/services/quarantine/types.js';
|
|
13
|
+
import { QuarantineRepository } from '../../src/repositories/quarantine/index.js';
|
|
14
|
+
import { ApprovalRepository } from '../../src/repositories/quarantine/index.js';
|
|
15
|
+
import { AuditLogger } from '../../src/security/AuditLogger.js';
|
|
16
|
+
import { createDatabaseSync } from '../../src/db/createDatabase.js';
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Test Helpers
|
|
19
|
+
// ============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Create a mock authenticated session for testing
|
|
22
|
+
*/
|
|
23
|
+
function createMockSession(overrides = {}) {
|
|
24
|
+
return {
|
|
25
|
+
userId: 'user-123',
|
|
26
|
+
email: 'reviewer@example.com',
|
|
27
|
+
displayName: 'Test Reviewer',
|
|
28
|
+
permissions: ['quarantine:read', 'quarantine:review'],
|
|
29
|
+
sessionId: 'session-456',
|
|
30
|
+
expiresAt: new Date(Date.now() + 3600000), // 1 hour from now
|
|
31
|
+
...overrides,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a session with specific permissions
|
|
36
|
+
*/
|
|
37
|
+
function createSessionWithPermissions(permissions) {
|
|
38
|
+
return createMockSession({ permissions });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create an expired session
|
|
42
|
+
*/
|
|
43
|
+
function createExpiredSession() {
|
|
44
|
+
return createMockSession({
|
|
45
|
+
expiresAt: new Date(Date.now() - 1000), // Expired 1 second ago
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Test Suite
|
|
50
|
+
// ============================================================================
|
|
51
|
+
describe('SMI-2269: QuarantineService Authentication', () => {
|
|
52
|
+
let db;
|
|
53
|
+
let repository;
|
|
54
|
+
let approvalRepository;
|
|
55
|
+
let auditLogger;
|
|
56
|
+
let service;
|
|
57
|
+
beforeEach(() => {
|
|
58
|
+
// Create in-memory database for testing
|
|
59
|
+
db = createDatabaseSync(':memory:');
|
|
60
|
+
auditLogger = new AuditLogger(db);
|
|
61
|
+
repository = new QuarantineRepository(db, auditLogger);
|
|
62
|
+
approvalRepository = new ApprovalRepository(db);
|
|
63
|
+
service = new QuarantineService(repository, approvalRepository, auditLogger);
|
|
64
|
+
});
|
|
65
|
+
afterEach(() => {
|
|
66
|
+
db.close();
|
|
67
|
+
});
|
|
68
|
+
// ==========================================================================
|
|
69
|
+
// Session Validation Tests
|
|
70
|
+
// ==========================================================================
|
|
71
|
+
describe('Session Validation', () => {
|
|
72
|
+
it('should reject expired sessions', () => {
|
|
73
|
+
const session = createExpiredSession();
|
|
74
|
+
expect(() => service.findById(session, 'some-id')).toThrow(QuarantineServiceError);
|
|
75
|
+
expect(() => service.findById(session, 'some-id')).toThrow('Session has expired');
|
|
76
|
+
});
|
|
77
|
+
it('should accept valid sessions', () => {
|
|
78
|
+
const session = createMockSession();
|
|
79
|
+
// Should not throw
|
|
80
|
+
expect(() => service.findById(session, 'nonexistent-id')).not.toThrow();
|
|
81
|
+
});
|
|
82
|
+
it('should include session expiry in error details', () => {
|
|
83
|
+
const session = createExpiredSession();
|
|
84
|
+
try {
|
|
85
|
+
service.findById(session, 'some-id');
|
|
86
|
+
expect.fail('Should have thrown');
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
expect(error).toBeInstanceOf(QuarantineServiceError);
|
|
90
|
+
expect(error.code).toBe('SESSION_EXPIRED');
|
|
91
|
+
expect(error.details?.expiresAt).toBeDefined();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
// ==========================================================================
|
|
96
|
+
// Permission Tests
|
|
97
|
+
// ==========================================================================
|
|
98
|
+
describe('Permission Enforcement', () => {
|
|
99
|
+
it('should reject users without quarantine:read permission', () => {
|
|
100
|
+
const session = createSessionWithPermissions([]);
|
|
101
|
+
expect(() => service.findById(session, 'some-id')).toThrow(QuarantineServiceError);
|
|
102
|
+
expect(() => service.findById(session, 'some-id')).toThrow('Permission denied');
|
|
103
|
+
});
|
|
104
|
+
it('should allow read with quarantine:read permission', () => {
|
|
105
|
+
const session = createSessionWithPermissions(['quarantine:read']);
|
|
106
|
+
// Should not throw
|
|
107
|
+
expect(() => service.findById(session, 'nonexistent-id')).not.toThrow();
|
|
108
|
+
});
|
|
109
|
+
it('should reject review without quarantine:review permission', () => {
|
|
110
|
+
const session = createSessionWithPermissions(['quarantine:read']);
|
|
111
|
+
// Create a quarantine entry first
|
|
112
|
+
const entry = repository.create({
|
|
113
|
+
skillId: 'test/skill',
|
|
114
|
+
source: 'test',
|
|
115
|
+
quarantineReason: 'Test reason',
|
|
116
|
+
severity: 'SUSPICIOUS',
|
|
117
|
+
});
|
|
118
|
+
expect(() => service.review(session, entry.id, {
|
|
119
|
+
reviewStatus: 'approved',
|
|
120
|
+
})).toThrow('Permission denied');
|
|
121
|
+
});
|
|
122
|
+
it('should allow admin users to bypass permission checks', () => {
|
|
123
|
+
const session = createSessionWithPermissions(['quarantine:admin']);
|
|
124
|
+
// Admin should be able to read without explicit read permission
|
|
125
|
+
expect(() => service.findById(session, 'nonexistent-id')).not.toThrow();
|
|
126
|
+
});
|
|
127
|
+
it('should include required permission in error details', () => {
|
|
128
|
+
const session = createSessionWithPermissions([]);
|
|
129
|
+
try {
|
|
130
|
+
service.findById(session, 'some-id');
|
|
131
|
+
expect.fail('Should have thrown');
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
expect(error).toBeInstanceOf(QuarantineServiceError);
|
|
135
|
+
expect(error.code).toBe('INSUFFICIENT_PERMISSIONS');
|
|
136
|
+
expect(error.details?.required).toBe('quarantine:read');
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
// ==========================================================================
|
|
141
|
+
// Review Tests
|
|
142
|
+
// ==========================================================================
|
|
143
|
+
describe('Authenticated Review', () => {
|
|
144
|
+
it('should include verified reviewer identity in result', () => {
|
|
145
|
+
const session = createMockSession({
|
|
146
|
+
userId: 'verified-user-123',
|
|
147
|
+
email: 'verified@example.com',
|
|
148
|
+
displayName: 'Verified Reviewer',
|
|
149
|
+
});
|
|
150
|
+
const entry = repository.create({
|
|
151
|
+
skillId: 'test/skill',
|
|
152
|
+
source: 'test',
|
|
153
|
+
quarantineReason: 'Test reason',
|
|
154
|
+
severity: 'SUSPICIOUS',
|
|
155
|
+
});
|
|
156
|
+
const result = service.review(session, entry.id, {
|
|
157
|
+
reviewStatus: 'approved',
|
|
158
|
+
reviewNotes: 'Verified safe',
|
|
159
|
+
});
|
|
160
|
+
expect(result.reviewedBy.userId).toBe('verified-user-123');
|
|
161
|
+
expect(result.reviewedBy.email).toBe('verified@example.com');
|
|
162
|
+
expect(result.reviewedBy.displayName).toBe('Verified Reviewer');
|
|
163
|
+
});
|
|
164
|
+
it('should reject review of non-existent entry', () => {
|
|
165
|
+
const session = createMockSession();
|
|
166
|
+
expect(() => service.review(session, 'nonexistent-id', {
|
|
167
|
+
reviewStatus: 'approved',
|
|
168
|
+
})).toThrow('Quarantine entry not found');
|
|
169
|
+
});
|
|
170
|
+
it('should reject review of already-reviewed entry', () => {
|
|
171
|
+
const session = createMockSession();
|
|
172
|
+
const entry = repository.create({
|
|
173
|
+
skillId: 'test/skill',
|
|
174
|
+
source: 'test',
|
|
175
|
+
quarantineReason: 'Test reason',
|
|
176
|
+
severity: 'SUSPICIOUS',
|
|
177
|
+
});
|
|
178
|
+
// First review should succeed
|
|
179
|
+
service.review(session, entry.id, {
|
|
180
|
+
reviewStatus: 'approved',
|
|
181
|
+
});
|
|
182
|
+
// Second review should fail
|
|
183
|
+
expect(() => service.review(session, entry.id, {
|
|
184
|
+
reviewStatus: 'rejected',
|
|
185
|
+
})).toThrow('already reviewed');
|
|
186
|
+
});
|
|
187
|
+
it('should log audit event with session details', () => {
|
|
188
|
+
const session = createMockSession({
|
|
189
|
+
sessionId: 'audit-test-session',
|
|
190
|
+
});
|
|
191
|
+
const entry = repository.create({
|
|
192
|
+
skillId: 'test/audit-skill',
|
|
193
|
+
source: 'test',
|
|
194
|
+
quarantineReason: 'Test reason',
|
|
195
|
+
severity: 'SUSPICIOUS',
|
|
196
|
+
});
|
|
197
|
+
// Spy on audit logger
|
|
198
|
+
const logSpy = vi.spyOn(auditLogger, 'log');
|
|
199
|
+
service.review(session, entry.id, {
|
|
200
|
+
reviewStatus: 'approved',
|
|
201
|
+
});
|
|
202
|
+
// Check audit was logged
|
|
203
|
+
expect(logSpy).toHaveBeenCalledWith(expect.objectContaining({
|
|
204
|
+
event_type: 'quarantine_authenticated_review',
|
|
205
|
+
actor: 'reviewer',
|
|
206
|
+
resource: 'test/audit-skill',
|
|
207
|
+
action: 'review',
|
|
208
|
+
result: 'success',
|
|
209
|
+
metadata: expect.objectContaining({
|
|
210
|
+
sessionId: 'audit-test-session',
|
|
211
|
+
reviewer: expect.objectContaining({
|
|
212
|
+
userId: session.userId,
|
|
213
|
+
email: session.email,
|
|
214
|
+
}),
|
|
215
|
+
}),
|
|
216
|
+
}));
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
// ==========================================================================
|
|
220
|
+
// MALICIOUS Severity Multi-Approval Tests
|
|
221
|
+
// ==========================================================================
|
|
222
|
+
describe('Multi-Approval Workflow (MALICIOUS Severity)', () => {
|
|
223
|
+
it('should require quarantine:review_malicious permission for MALICIOUS reviews', () => {
|
|
224
|
+
const session = createSessionWithPermissions(['quarantine:read', 'quarantine:review']);
|
|
225
|
+
const entry = repository.create({
|
|
226
|
+
skillId: 'test/malicious-skill',
|
|
227
|
+
source: 'test',
|
|
228
|
+
quarantineReason: 'Malicious code detected',
|
|
229
|
+
severity: 'MALICIOUS',
|
|
230
|
+
});
|
|
231
|
+
expect(() => service.review(session, entry.id, {
|
|
232
|
+
reviewStatus: 'approved',
|
|
233
|
+
})).toThrow('quarantine:review_malicious required');
|
|
234
|
+
});
|
|
235
|
+
it('should start multi-approval workflow for MALICIOUS approval', () => {
|
|
236
|
+
const session = createSessionWithPermissions([
|
|
237
|
+
'quarantine:read',
|
|
238
|
+
'quarantine:review',
|
|
239
|
+
'quarantine:review_malicious',
|
|
240
|
+
]);
|
|
241
|
+
const entry = repository.create({
|
|
242
|
+
skillId: 'test/malicious-skill',
|
|
243
|
+
source: 'test',
|
|
244
|
+
quarantineReason: 'Malicious code detected',
|
|
245
|
+
severity: 'MALICIOUS',
|
|
246
|
+
});
|
|
247
|
+
const result = service.review(session, entry.id, {
|
|
248
|
+
reviewStatus: 'approved',
|
|
249
|
+
reviewNotes: 'First approval',
|
|
250
|
+
});
|
|
251
|
+
expect(result.approved).toBe(false); // Not yet approved (needs 2 approvals)
|
|
252
|
+
expect(result.multiApprovalStatus).toBeDefined();
|
|
253
|
+
expect(result.multiApprovalStatus?.currentApprovals.length).toBe(1);
|
|
254
|
+
expect(result.multiApprovalStatus?.requiredApprovals).toBe(2);
|
|
255
|
+
});
|
|
256
|
+
it('should complete approval when enough reviewers approve', () => {
|
|
257
|
+
const session1 = createSessionWithPermissions([
|
|
258
|
+
'quarantine:read',
|
|
259
|
+
'quarantine:review',
|
|
260
|
+
'quarantine:review_malicious',
|
|
261
|
+
]);
|
|
262
|
+
const session2 = createMockSession({
|
|
263
|
+
userId: 'user-456',
|
|
264
|
+
email: 'reviewer2@example.com',
|
|
265
|
+
permissions: ['quarantine:read', 'quarantine:review', 'quarantine:review_malicious'],
|
|
266
|
+
});
|
|
267
|
+
const entry = repository.create({
|
|
268
|
+
skillId: 'test/malicious-skill',
|
|
269
|
+
source: 'test',
|
|
270
|
+
quarantineReason: 'Malicious code detected',
|
|
271
|
+
severity: 'MALICIOUS',
|
|
272
|
+
});
|
|
273
|
+
// First approval
|
|
274
|
+
const result1 = service.review(session1, entry.id, {
|
|
275
|
+
reviewStatus: 'approved',
|
|
276
|
+
reviewNotes: 'First approval',
|
|
277
|
+
});
|
|
278
|
+
expect(result1.approved).toBe(false);
|
|
279
|
+
// Second approval
|
|
280
|
+
const result2 = service.review(session2, entry.id, {
|
|
281
|
+
reviewStatus: 'approved',
|
|
282
|
+
reviewNotes: 'Second approval',
|
|
283
|
+
});
|
|
284
|
+
expect(result2.approved).toBe(true);
|
|
285
|
+
expect(result2.multiApprovalStatus?.isComplete).toBe(true);
|
|
286
|
+
});
|
|
287
|
+
it('should prevent same user from approving twice', () => {
|
|
288
|
+
const session = createSessionWithPermissions([
|
|
289
|
+
'quarantine:read',
|
|
290
|
+
'quarantine:review',
|
|
291
|
+
'quarantine:review_malicious',
|
|
292
|
+
]);
|
|
293
|
+
const entry = repository.create({
|
|
294
|
+
skillId: 'test/malicious-skill',
|
|
295
|
+
source: 'test',
|
|
296
|
+
quarantineReason: 'Malicious code detected',
|
|
297
|
+
severity: 'MALICIOUS',
|
|
298
|
+
});
|
|
299
|
+
// First approval should work
|
|
300
|
+
service.review(session, entry.id, {
|
|
301
|
+
reviewStatus: 'approved',
|
|
302
|
+
});
|
|
303
|
+
// Same user trying to approve again should fail
|
|
304
|
+
expect(() => service.review(session, entry.id, {
|
|
305
|
+
reviewStatus: 'approved',
|
|
306
|
+
})).toThrow('already approved');
|
|
307
|
+
});
|
|
308
|
+
it('should allow MALICIOUS rejection without multi-approval', () => {
|
|
309
|
+
const session = createSessionWithPermissions([
|
|
310
|
+
'quarantine:read',
|
|
311
|
+
'quarantine:review',
|
|
312
|
+
'quarantine:review_malicious',
|
|
313
|
+
]);
|
|
314
|
+
const entry = repository.create({
|
|
315
|
+
skillId: 'test/malicious-skill',
|
|
316
|
+
source: 'test',
|
|
317
|
+
quarantineReason: 'Malicious code detected',
|
|
318
|
+
severity: 'MALICIOUS',
|
|
319
|
+
});
|
|
320
|
+
// Rejection should work immediately (no multi-approval needed)
|
|
321
|
+
const result = service.review(session, entry.id, {
|
|
322
|
+
reviewStatus: 'rejected',
|
|
323
|
+
reviewNotes: 'Confirmed malicious',
|
|
324
|
+
});
|
|
325
|
+
expect(result.approved).toBe(false);
|
|
326
|
+
expect(result.multiApprovalStatus).toBeUndefined();
|
|
327
|
+
});
|
|
328
|
+
it('should track multi-approval status', () => {
|
|
329
|
+
const session = createSessionWithPermissions([
|
|
330
|
+
'quarantine:read',
|
|
331
|
+
'quarantine:review',
|
|
332
|
+
'quarantine:review_malicious',
|
|
333
|
+
]);
|
|
334
|
+
const entry = repository.create({
|
|
335
|
+
skillId: 'test/malicious-skill',
|
|
336
|
+
source: 'test',
|
|
337
|
+
quarantineReason: 'Malicious code detected',
|
|
338
|
+
severity: 'MALICIOUS',
|
|
339
|
+
});
|
|
340
|
+
// First approval
|
|
341
|
+
service.review(session, entry.id, {
|
|
342
|
+
reviewStatus: 'approved',
|
|
343
|
+
});
|
|
344
|
+
// Check status
|
|
345
|
+
const status = service.getMultiApprovalStatus(session, entry.id);
|
|
346
|
+
expect(status).not.toBeNull();
|
|
347
|
+
expect(status?.currentApprovals.length).toBe(1);
|
|
348
|
+
expect(status?.isComplete).toBe(false);
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
// ==========================================================================
|
|
352
|
+
// Timeout Tests
|
|
353
|
+
// ==========================================================================
|
|
354
|
+
describe('Multi-Approval Timeout', () => {
|
|
355
|
+
it('should reset workflow and log audit event when approval times out', () => {
|
|
356
|
+
const session1 = createSessionWithPermissions([
|
|
357
|
+
'quarantine:read',
|
|
358
|
+
'quarantine:review',
|
|
359
|
+
'quarantine:review_malicious',
|
|
360
|
+
]);
|
|
361
|
+
const session2 = createMockSession({
|
|
362
|
+
userId: 'user-456',
|
|
363
|
+
email: 'reviewer2@example.com',
|
|
364
|
+
permissions: ['quarantine:read', 'quarantine:review', 'quarantine:review_malicious'],
|
|
365
|
+
});
|
|
366
|
+
const entry = repository.create({
|
|
367
|
+
skillId: 'test/malicious-skill',
|
|
368
|
+
source: 'test',
|
|
369
|
+
quarantineReason: 'Malicious code detected',
|
|
370
|
+
severity: 'MALICIOUS',
|
|
371
|
+
});
|
|
372
|
+
// First approval
|
|
373
|
+
service.review(session1, entry.id, {
|
|
374
|
+
reviewStatus: 'approved',
|
|
375
|
+
reviewNotes: 'First approval',
|
|
376
|
+
});
|
|
377
|
+
// Manipulate the created_at timestamp to simulate 25 hours ago
|
|
378
|
+
db.prepare("UPDATE quarantine_approvals SET created_at = datetime('now', '-25 hours') || 'Z' WHERE skill_id = ?").run(entry.id);
|
|
379
|
+
// Spy on audit logger
|
|
380
|
+
const logSpy = vi.spyOn(auditLogger, 'log');
|
|
381
|
+
// Second reviewer triggers timeout
|
|
382
|
+
expect(() => service.review(session2, entry.id, {
|
|
383
|
+
reviewStatus: 'approved',
|
|
384
|
+
})).toThrow('timed out');
|
|
385
|
+
// Verify timeout was audit-logged
|
|
386
|
+
expect(logSpy).toHaveBeenCalledWith(expect.objectContaining({
|
|
387
|
+
event_type: 'quarantine_multi_approval_timeout',
|
|
388
|
+
actor: 'system',
|
|
389
|
+
action: 'timeout',
|
|
390
|
+
}));
|
|
391
|
+
// Verify approvals were cleared
|
|
392
|
+
const status = service.getMultiApprovalStatus(session1, entry.id);
|
|
393
|
+
expect(status).toBeNull();
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
// ==========================================================================
|
|
397
|
+
// Error Handling Tests
|
|
398
|
+
// ==========================================================================
|
|
399
|
+
describe('Error Handling', () => {
|
|
400
|
+
it('should return typed error codes', () => {
|
|
401
|
+
const session = createExpiredSession();
|
|
402
|
+
try {
|
|
403
|
+
service.findById(session, 'some-id');
|
|
404
|
+
expect.fail('Should have thrown');
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
expect(error).toBeInstanceOf(QuarantineServiceError);
|
|
408
|
+
expect(error.code).toBe('SESSION_EXPIRED');
|
|
409
|
+
expect(error.name).toBe('QuarantineServiceError');
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
it('should include error details for debugging', () => {
|
|
413
|
+
const session = createSessionWithPermissions([]);
|
|
414
|
+
try {
|
|
415
|
+
service.findById(session, 'some-id');
|
|
416
|
+
expect.fail('Should have thrown');
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
expect(error).toBeInstanceOf(QuarantineServiceError);
|
|
420
|
+
expect(error.details).toBeDefined();
|
|
421
|
+
expect(error.details?.available).toEqual([]);
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
//# sourceMappingURL=QuarantineService.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuarantineService.test.js","sourceRoot":"","sources":["../../../tests/integration/QuarantineService.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* 4. Learning persists across session restart
|
|
12
12
|
*
|
|
13
13
|
* @see packages/core/src/learning/interfaces.ts
|
|
14
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
14
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
15
15
|
*/
|
|
16
16
|
export {};
|
|
17
17
|
//# sourceMappingURL=e2e-learning.test.d.ts.map
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* 4. Learning persists across session restart
|
|
12
12
|
*
|
|
13
13
|
* @see packages/core/src/learning/interfaces.ts
|
|
14
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
14
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
15
15
|
*/
|
|
16
16
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
17
17
|
import { createNeuralTestContext, cleanupNeuralTestContext, createDefaultProfile, } from './setup.js';
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* 8. Personalization disabled by user preference
|
|
16
16
|
*
|
|
17
17
|
* @see packages/core/src/learning/interfaces.ts
|
|
18
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
18
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
19
19
|
*/
|
|
20
20
|
export {};
|
|
21
21
|
//# sourceMappingURL=personalization.test.d.ts.map
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* 8. Personalization disabled by user preference
|
|
16
16
|
*
|
|
17
17
|
* @see packages/core/src/learning/interfaces.ts
|
|
18
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
18
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
19
19
|
*/
|
|
20
20
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
21
21
|
import { createNeuralTestContext, cleanupNeuralTestContext, createDefaultProfile, } from './setup.js';
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* 10. Profile persistence across sessions
|
|
18
18
|
*
|
|
19
19
|
* @see packages/core/src/learning/interfaces.ts
|
|
20
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
20
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
21
21
|
*/
|
|
22
22
|
export {};
|
|
23
23
|
//# sourceMappingURL=preference-learner.test.d.ts.map
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* 10. Profile persistence across sessions
|
|
18
18
|
*
|
|
19
19
|
* @see packages/core/src/learning/interfaces.ts
|
|
20
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
20
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
21
21
|
*/
|
|
22
22
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
23
23
|
import { createNeuralTestContext, cleanupNeuralTestContext, createDefaultProfile, } from './setup.js';
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* 6. Privacy audit log records all operations
|
|
14
14
|
*
|
|
15
15
|
* @see packages/core/src/learning/interfaces.ts
|
|
16
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
16
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
17
17
|
*/
|
|
18
18
|
export {};
|
|
19
19
|
//# sourceMappingURL=privacy.test.d.ts.map
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* 6. Privacy audit log records all operations
|
|
14
14
|
*
|
|
15
15
|
* @see packages/core/src/learning/interfaces.ts
|
|
16
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
16
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
17
17
|
*/
|
|
18
18
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
19
19
|
import { createNeuralTestContext, cleanupNeuralTestContext, createDefaultProfile, } from './setup.js';
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* 8. Query signals by date range
|
|
16
16
|
*
|
|
17
17
|
* @see packages/core/src/learning/interfaces.ts
|
|
18
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
18
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
19
19
|
*/
|
|
20
20
|
export {};
|
|
21
21
|
//# sourceMappingURL=signal-collection.test.d.ts.map
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* 8. Query signals by date range
|
|
16
16
|
*
|
|
17
17
|
* @see packages/core/src/learning/interfaces.ts
|
|
18
|
-
* @see docs/execution/phase5-testing-execution.md
|
|
18
|
+
* @see docs/internal/execution/phase5-testing-execution.md
|
|
19
19
|
*/
|
|
20
20
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
21
21
|
import { createNeuralTestContext, cleanupNeuralTestContext, } from './setup.js';
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Statistical keyword analysis
|
|
8
8
|
* - Confidence scoring
|
|
9
9
|
*
|
|
10
|
-
* @see docs/architecture/multi-language-analysis.md
|
|
10
|
+
* @see docs/internal/architecture/multi-language-analysis.md
|
|
11
11
|
*/
|
|
12
12
|
import { describe, it, expect } from 'vitest';
|
|
13
13
|
import { LanguageDetector, detectLanguage } from '../src/analysis/language-detector.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-2277: ApprovalRepository Unit Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for the database-persisted multi-approval workflow state.
|
|
5
|
+
* Verifies that approval state survives across repository instances
|
|
6
|
+
* (simulating service restarts).
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=approval-repository.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-repository.test.d.ts","sourceRoot":"","sources":["../../../tests/unit/approval-repository.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|