@skillsmith/core 0.4.10 → 0.4.12
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/.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.js +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/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/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/embeddings/embedding-utils.d.ts +3 -3
- package/dist/src/embeddings/embedding-utils.d.ts.map +1 -1
- package/dist/src/embeddings/embedding-utils.js +3 -3
- package/dist/src/embeddings/embedding-utils.js.map +1 -1
- package/dist/src/embeddings/index.d.ts +1 -1
- package/dist/src/embeddings/index.js +3 -3
- package/dist/src/embeddings/index.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.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/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/security/audit-types.d.ts +1 -1
- 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/scanner/SecurityScanner.formatters.js +1 -1
- package/dist/src/security/scanner/SecurityScanner.formatters.js.map +1 -1
- package/dist/src/services/quarantine/QuarantineService.d.ts +17 -9
- package/dist/src/services/quarantine/QuarantineService.d.ts.map +1 -1
- package/dist/src/services/quarantine/QuarantineService.js +114 -56
- package/dist/src/services/quarantine/QuarantineService.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/integration/QuarantineService.test.js +49 -1
- package/dist/tests/integration/QuarantineService.test.js.map +1 -1
- 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/package.json +2 -2
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-2277: Approval Repository
|
|
3
|
+
*
|
|
4
|
+
* Persists multi-approval state to SQLite instead of in-memory Map.
|
|
5
|
+
* This ensures pending approvals survive service restarts.
|
|
6
|
+
*
|
|
7
|
+
* @module @skillsmith/core/repositories/quarantine/ApprovalRepository
|
|
8
|
+
*/
|
|
9
|
+
import { randomUUID } from 'crypto';
|
|
10
|
+
import { initializeQuarantineApprovalsSchema } from '../../db/quarantine-approvals-schema.js';
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// SQL Queries
|
|
13
|
+
// ============================================================================
|
|
14
|
+
const INSERT_APPROVAL_QUERY = `
|
|
15
|
+
INSERT INTO quarantine_approvals (
|
|
16
|
+
id, skill_id, reviewer_id, reviewer_email, decision, reason,
|
|
17
|
+
created_at, required_approvals, is_complete
|
|
18
|
+
)
|
|
19
|
+
VALUES (?, ?, ?, ?, ?, ?, datetime('now') || 'Z', ?, 0)
|
|
20
|
+
`;
|
|
21
|
+
const SELECT_BY_SKILL_ID_QUERY = `
|
|
22
|
+
SELECT * FROM quarantine_approvals
|
|
23
|
+
WHERE skill_id = ?
|
|
24
|
+
ORDER BY created_at ASC
|
|
25
|
+
`;
|
|
26
|
+
const SELECT_PENDING_BY_SKILL_ID_QUERY = `
|
|
27
|
+
SELECT * FROM quarantine_approvals
|
|
28
|
+
WHERE skill_id = ? AND is_complete = 0
|
|
29
|
+
ORDER BY created_at ASC
|
|
30
|
+
`;
|
|
31
|
+
const COUNT_PENDING_APPROVALS_QUERY = `
|
|
32
|
+
SELECT COUNT(*) as count FROM quarantine_approvals
|
|
33
|
+
WHERE skill_id = ? AND is_complete = 0 AND decision = 'approved'
|
|
34
|
+
`;
|
|
35
|
+
const CHECK_REVIEWER_EXISTS_QUERY = `
|
|
36
|
+
SELECT id FROM quarantine_approvals
|
|
37
|
+
WHERE skill_id = ? AND reviewer_id = ? AND is_complete = 0
|
|
38
|
+
`;
|
|
39
|
+
const MARK_COMPLETE_QUERY = `
|
|
40
|
+
UPDATE quarantine_approvals
|
|
41
|
+
SET is_complete = 1, completed_at = datetime('now') || 'Z'
|
|
42
|
+
WHERE skill_id = ? AND is_complete = 0
|
|
43
|
+
`;
|
|
44
|
+
const DELETE_BY_SKILL_ID_QUERY = `
|
|
45
|
+
DELETE FROM quarantine_approvals WHERE skill_id = ?
|
|
46
|
+
`;
|
|
47
|
+
const SELECT_FIRST_PENDING_QUERY = `
|
|
48
|
+
SELECT created_at FROM quarantine_approvals
|
|
49
|
+
WHERE skill_id = ? AND is_complete = 0
|
|
50
|
+
ORDER BY created_at ASC
|
|
51
|
+
LIMIT 1
|
|
52
|
+
`;
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Repository Implementation
|
|
55
|
+
// ============================================================================
|
|
56
|
+
/**
|
|
57
|
+
* Repository for persisting multi-approval workflow state.
|
|
58
|
+
*
|
|
59
|
+
* Replaces the in-memory Map<string, MultiApprovalStatus> with
|
|
60
|
+
* database-backed storage to survive service restarts.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const repo = new ApprovalRepository(db)
|
|
65
|
+
*
|
|
66
|
+
* // Record a reviewer's approval
|
|
67
|
+
* repo.recordApproval({
|
|
68
|
+
* skillId: 'quarantine-123',
|
|
69
|
+
* reviewerId: 'user-456',
|
|
70
|
+
* reviewerRole: 'reviewer@example.com',
|
|
71
|
+
* decision: 'approved',
|
|
72
|
+
* reason: 'Code verified safe',
|
|
73
|
+
* })
|
|
74
|
+
*
|
|
75
|
+
* // Check if enough approvals have been collected
|
|
76
|
+
* const complete = repo.isComplete('quarantine-123')
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export class ApprovalRepository {
|
|
80
|
+
db;
|
|
81
|
+
constructor(db) {
|
|
82
|
+
this.db = db;
|
|
83
|
+
this.ensureTableExists();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Ensure the quarantine_approvals table exists
|
|
87
|
+
*/
|
|
88
|
+
ensureTableExists() {
|
|
89
|
+
initializeQuarantineApprovalsSchema(this.db);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Record a new approval or rejection for a quarantine entry
|
|
93
|
+
*
|
|
94
|
+
* @param input - Approval details
|
|
95
|
+
* @returns The created approval entry
|
|
96
|
+
* @throws Error if reviewer has already submitted for this skill
|
|
97
|
+
*/
|
|
98
|
+
recordApproval(input) {
|
|
99
|
+
const id = randomUUID();
|
|
100
|
+
const requiredApprovals = input.requiredApprovals ?? 2;
|
|
101
|
+
this.db
|
|
102
|
+
.prepare(INSERT_APPROVAL_QUERY)
|
|
103
|
+
.run(id, input.skillId, input.reviewerId, input.reviewerEmail, input.decision, input.reason ?? null, requiredApprovals);
|
|
104
|
+
const row = this.db
|
|
105
|
+
.prepare('SELECT * FROM quarantine_approvals WHERE id = ?')
|
|
106
|
+
.get(id);
|
|
107
|
+
return rowToEntry(row);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get all approvals for a quarantine entry (both pending and complete)
|
|
111
|
+
*
|
|
112
|
+
* @param skillId - The quarantine entry ID
|
|
113
|
+
* @returns All approval entries for this skill
|
|
114
|
+
*/
|
|
115
|
+
getApprovals(skillId) {
|
|
116
|
+
const rows = this.db.prepare(SELECT_BY_SKILL_ID_QUERY).all(skillId);
|
|
117
|
+
return rows.map(rowToEntry);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get only pending (non-complete) approvals for a quarantine entry
|
|
121
|
+
*
|
|
122
|
+
* @param skillId - The quarantine entry ID
|
|
123
|
+
* @returns Pending approval entries
|
|
124
|
+
*/
|
|
125
|
+
getPendingApprovals(skillId) {
|
|
126
|
+
const rows = this.db.prepare(SELECT_PENDING_BY_SKILL_ID_QUERY).all(skillId);
|
|
127
|
+
return rows.map(rowToEntry);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if a specific reviewer has already submitted for a skill
|
|
131
|
+
*
|
|
132
|
+
* @param skillId - The quarantine entry ID
|
|
133
|
+
* @param reviewerId - The reviewer's user ID
|
|
134
|
+
* @returns True if the reviewer already has a pending approval
|
|
135
|
+
*/
|
|
136
|
+
hasReviewerApproved(skillId, reviewerId) {
|
|
137
|
+
const row = this.db.prepare(CHECK_REVIEWER_EXISTS_QUERY).get(skillId, reviewerId);
|
|
138
|
+
return !!row;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Check if the required number of approvals have been reached
|
|
142
|
+
*
|
|
143
|
+
* @param skillId - The quarantine entry ID
|
|
144
|
+
* @param requiredApprovals - Number of approvals needed (default: 2)
|
|
145
|
+
* @returns True if approval count meets or exceeds required
|
|
146
|
+
*/
|
|
147
|
+
isComplete(skillId, requiredApprovals = 2) {
|
|
148
|
+
const { count } = this.db.prepare(COUNT_PENDING_APPROVALS_QUERY).get(skillId);
|
|
149
|
+
return count >= requiredApprovals;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Mark all pending approvals for a skill as complete
|
|
153
|
+
*
|
|
154
|
+
* @param skillId - The quarantine entry ID
|
|
155
|
+
* @returns Number of rows updated
|
|
156
|
+
*/
|
|
157
|
+
markComplete(skillId) {
|
|
158
|
+
const result = this.db.prepare(MARK_COMPLETE_QUERY).run(skillId);
|
|
159
|
+
return result.changes;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Delete all approvals for a skill (for cleanup/reset/cancellation)
|
|
163
|
+
*
|
|
164
|
+
* @param skillId - The quarantine entry ID
|
|
165
|
+
* @returns Number of rows deleted
|
|
166
|
+
*/
|
|
167
|
+
clearApprovals(skillId) {
|
|
168
|
+
const result = this.db.prepare(DELETE_BY_SKILL_ID_QUERY).run(skillId);
|
|
169
|
+
return result.changes;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get the timestamp of the first pending approval for timeout checks
|
|
173
|
+
*
|
|
174
|
+
* @param skillId - The quarantine entry ID
|
|
175
|
+
* @returns ISO date string of the first approval, or null if none
|
|
176
|
+
*/
|
|
177
|
+
getWorkflowStartTime(skillId) {
|
|
178
|
+
const row = this.db.prepare(SELECT_FIRST_PENDING_QUERY).get(skillId);
|
|
179
|
+
return row?.created_at ?? null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Get the count of pending approvals for a skill
|
|
183
|
+
*
|
|
184
|
+
* @param skillId - The quarantine entry ID
|
|
185
|
+
* @returns Count of pending approved entries
|
|
186
|
+
*/
|
|
187
|
+
getPendingApprovalCount(skillId) {
|
|
188
|
+
const { count } = this.db.prepare(COUNT_PENDING_APPROVALS_QUERY).get(skillId);
|
|
189
|
+
return count;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// ============================================================================
|
|
193
|
+
// Helpers
|
|
194
|
+
// ============================================================================
|
|
195
|
+
/**
|
|
196
|
+
* Convert a database row to a domain object
|
|
197
|
+
*/
|
|
198
|
+
function rowToEntry(row) {
|
|
199
|
+
return {
|
|
200
|
+
id: row.id,
|
|
201
|
+
skillId: row.skill_id,
|
|
202
|
+
reviewerId: row.reviewer_id,
|
|
203
|
+
reviewerEmail: row.reviewer_email,
|
|
204
|
+
decision: row.decision,
|
|
205
|
+
reason: row.reason,
|
|
206
|
+
createdAt: row.created_at,
|
|
207
|
+
completedAt: row.completed_at,
|
|
208
|
+
requiredApprovals: row.required_approvals,
|
|
209
|
+
isComplete: row.is_complete === 1,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=ApprovalRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApprovalRepository.js","sourceRoot":"","sources":["../../../../src/repositories/quarantine/ApprovalRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,4 +7,6 @@ export * from './types.js';
|
|
|
7
7
|
export * from './queries.js';
|
|
8
8
|
export * from './query-builder.js';
|
|
9
9
|
export { QuarantineRepository } from './QuarantineRepository.js';
|
|
10
|
+
export { ApprovalRepository } from './ApprovalRepository.js';
|
|
11
|
+
export type { ApprovalRow, ApprovalEntry, RecordApprovalInput } from './ApprovalRepository.js';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/repositories/quarantine/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/repositories/quarantine/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/repositories/quarantine/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/repositories/quarantine/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
/**
|
|
8
8
|
* Types of security events that are audited
|
|
9
9
|
*/
|
|
10
|
-
export type AuditEventType = 'url_fetch' | 'file_access' | 'skill_install' | 'skill_uninstall' | 'security_scan' | 'cache_operation' | 'source_sync' | 'config_change' | 'quarantine_authenticated_review' | 'quarantine_multi_approval' | 'quarantine_multi_approval_complete' | 'quarantine_multi_approval_cancelled' | 'security_feature_flag_override';
|
|
10
|
+
export type AuditEventType = 'url_fetch' | 'file_access' | 'skill_install' | 'skill_uninstall' | 'security_scan' | 'cache_operation' | 'source_sync' | 'config_change' | 'quarantine_authenticated_review' | 'quarantine_multi_approval' | 'quarantine_multi_approval_complete' | 'quarantine_multi_approval_cancelled' | 'quarantine_multi_approval_timeout' | 'security_feature_flag_override';
|
|
11
11
|
/**
|
|
12
12
|
* Actor performing the action
|
|
13
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-types.d.ts","sourceRoot":"","sources":["../../../src/security/audit-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,aAAa,GACb,eAAe,GAEf,iCAAiC,GACjC,2BAA2B,GAC3B,oCAAoC,GACpC,qCAAqC,
|
|
1
|
+
{"version":3,"file":"audit-types.d.ts","sourceRoot":"","sources":["../../../src/security/audit-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,aAAa,GACb,eAAe,GAEf,iCAAiC,GACjC,2BAA2B,GAC3B,oCAAoC,GACpC,qCAAqC,GACrC,mCAAmC,GAEnC,gCAAgC,CAAA;AAEpC;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAA;AAE/E;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,cAAc,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,UAAU,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,cAAc,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,UAAU,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,cAAc,CAAA;IAC3B,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC;;GAEG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAA;AAEtC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;IAC9C,gBAAgB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAC7C,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-types.js","sourceRoot":"","sources":["../../../src/security/audit-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"audit-types.js","sourceRoot":"","sources":["../../../src/security/audit-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6EH;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAA;AAEnC;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAA,CAAC,WAAW"}
|
|
@@ -19,7 +19,7 @@ export function toMinimalRefs(report) {
|
|
|
19
19
|
return report.findings.map((finding) => {
|
|
20
20
|
const line = finding.lineNumber ?? 0;
|
|
21
21
|
const severity = finding.severity.toUpperCase();
|
|
22
|
-
const message = finding.message.replace(/"/g, '\\"');
|
|
22
|
+
const message = finding.message.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
23
23
|
// Format: skill_id:line:severity:type:message
|
|
24
24
|
return `${report.skillId}:${line}:${severity}:${finding.type}:${message}`;
|
|
25
25
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityScanner.formatters.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.formatters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,MAAkB;IAC9C,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAA;QAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"SecurityScanner.formatters.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.formatters.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SMI-2269: Quarantine Service with Authentication
|
|
3
|
+
* SMI-2277: Persist multi-approval state to database
|
|
3
4
|
*
|
|
4
5
|
* Service layer for quarantine operations that enforces authentication
|
|
5
6
|
* and authorization. Wraps QuarantineRepository with security controls.
|
|
@@ -13,10 +14,12 @@
|
|
|
13
14
|
* - Enforces security_reviewer permission for review access
|
|
14
15
|
* - Multi-approval workflow for MALICIOUS severity
|
|
15
16
|
* - Audit logs include verified reviewer identity
|
|
17
|
+
* - Approval state persisted to database (survives restarts)
|
|
16
18
|
*
|
|
17
19
|
* @module @skillsmith/core/services/quarantine/QuarantineService
|
|
18
20
|
*/
|
|
19
21
|
import type { QuarantineRepository } from '../../repositories/quarantine/index.js';
|
|
22
|
+
import type { ApprovalRepository } from '../../repositories/quarantine/ApprovalRepository.js';
|
|
20
23
|
import type { AuditLogger } from '../../security/AuditLogger.js';
|
|
21
24
|
import type { AuthenticatedSession, AuthenticatedReviewInput, AuthenticatedReviewResult, MultiApprovalStatus } from './types.js';
|
|
22
25
|
/**
|
|
@@ -27,10 +30,11 @@ import type { AuthenticatedSession, AuthenticatedReviewInput, AuthenticatedRevie
|
|
|
27
30
|
* - Permission checks (security_reviewer role)
|
|
28
31
|
* - Multi-approval workflow for MALICIOUS severity
|
|
29
32
|
* - Audit logging with verified identities
|
|
33
|
+
* - Database-persisted approval state (SMI-2277)
|
|
30
34
|
*
|
|
31
35
|
* @example
|
|
32
36
|
* ```typescript
|
|
33
|
-
* const service = new QuarantineService(repository, auditLogger)
|
|
37
|
+
* const service = new QuarantineService(repository, approvalRepository, auditLogger)
|
|
34
38
|
*
|
|
35
39
|
* // Review a quarantined skill (requires authentication)
|
|
36
40
|
* const result = await service.review(
|
|
@@ -42,15 +46,9 @@ import type { AuthenticatedSession, AuthenticatedReviewInput, AuthenticatedRevie
|
|
|
42
46
|
*/
|
|
43
47
|
export declare class QuarantineService {
|
|
44
48
|
private readonly repository;
|
|
49
|
+
private readonly approvalRepository;
|
|
45
50
|
private readonly auditLogger;
|
|
46
|
-
|
|
47
|
-
* In-memory store for pending multi-approvals
|
|
48
|
-
* Key: quarantineId, Value: MultiApprovalStatus
|
|
49
|
-
*
|
|
50
|
-
* Note: In production, this should be persisted to database
|
|
51
|
-
*/
|
|
52
|
-
private pendingApprovals;
|
|
53
|
-
constructor(repository: QuarantineRepository, auditLogger: AuditLogger);
|
|
51
|
+
constructor(repository: QuarantineRepository, approvalRepository: ApprovalRepository, auditLogger: AuditLogger);
|
|
54
52
|
/**
|
|
55
53
|
* Find a quarantine entry by ID
|
|
56
54
|
*
|
|
@@ -106,6 +104,9 @@ export declare class QuarantineService {
|
|
|
106
104
|
* before a skill can be unquarantined. This prevents single
|
|
107
105
|
* reviewer compromise from allowing malicious skills.
|
|
108
106
|
*
|
|
107
|
+
* Approval state is persisted to the database (SMI-2277) so
|
|
108
|
+
* pending approvals survive service restarts.
|
|
109
|
+
*
|
|
109
110
|
* @param session - Authenticated session
|
|
110
111
|
* @param quarantineId - Quarantine entry ID
|
|
111
112
|
* @param skillId - Skill ID
|
|
@@ -145,5 +146,12 @@ export declare class QuarantineService {
|
|
|
145
146
|
* @returns Whether the entry was deleted
|
|
146
147
|
*/
|
|
147
148
|
delete(session: AuthenticatedSession, id: string): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Build a MultiApprovalStatus from database rows
|
|
151
|
+
*
|
|
152
|
+
* Converts persisted approval entries into the MultiApprovalStatus
|
|
153
|
+
* interface expected by consumers.
|
|
154
|
+
*/
|
|
155
|
+
private buildMultiApprovalStatus;
|
|
148
156
|
}
|
|
149
157
|
//# sourceMappingURL=QuarantineService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuarantineService.d.ts","sourceRoot":"","sources":["../../../../src/services/quarantine/QuarantineService.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"QuarantineService.d.ts","sourceRoot":"","sources":["../../../../src/services/quarantine/QuarantineService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAA;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAA;AAC7F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EAEpB,MAAM,YAAY,CAAA;AAqBnB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFX,UAAU,EAAE,oBAAoB,EAChC,kBAAkB,EAAE,kBAAkB,EACtC,WAAW,EAAE,WAAW;IAO3C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM;IAKlD;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM;IAK5D;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAK9F;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IAStC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CACJ,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,wBAAwB,GAC9B,yBAAyB;IAoF5B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,uBAAuB;IA2K/B;;;;;;OAMG;IACH,sBAAsB,CACpB,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,MAAM,GACnB,mBAAmB,GAAG,IAAI;IAW7B;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IA8BjF;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAK1F;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAa1D;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;CA+BjC"}
|