driftdetect-dashboard 0.3.0 → 0.4.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"galaxy-data-transformer.d.ts","sourceRoot":"","sources":["../../src/server/galaxy-data-transformer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,562 @@
1
+ /**
2
+ * Galaxy Data Transformer
3
+ *
4
+ * Transforms Drift's boundary scanner and call graph data into the
5
+ * Galaxy visualization format. This is the bridge between Drift's
6
+ * semantic analysis and the 3D visualization.
7
+ *
8
+ * Data Sources:
9
+ * - BoundaryScanner: Tables, fields, sensitive fields, access points
10
+ * - CallGraph: Entry points, functions, call paths
11
+ * - SecurityPrioritizer: Security tiers, risk scores
12
+ */
13
+ import * as fs from 'node:fs/promises';
14
+ import * as path from 'node:path';
15
+ // ============================================================================
16
+ // Sensitivity Mapping
17
+ // ============================================================================
18
+ /**
19
+ * Map Drift sensitivity types to Galaxy sensitivity levels
20
+ */
21
+ function mapSensitivityType(type) {
22
+ switch (type?.toLowerCase()) {
23
+ case 'credentials':
24
+ return 'critical';
25
+ case 'financial':
26
+ case 'health':
27
+ return 'high';
28
+ case 'pii':
29
+ return 'medium';
30
+ case 'unknown':
31
+ default:
32
+ return 'low';
33
+ }
34
+ }
35
+ /**
36
+ * Calculate table sensitivity from its fields
37
+ */
38
+ function calculateTableSensitivity(fields) {
39
+ const priorities = ['critical', 'high', 'medium', 'low', 'public'];
40
+ for (const priority of priorities) {
41
+ if (fields.some(f => f.sensitivity === priority)) {
42
+ return priority;
43
+ }
44
+ }
45
+ return 'public';
46
+ }
47
+ /**
48
+ * Calculate security tier from sensitivity and access patterns
49
+ */
50
+ function calculateSecurityTier(sensitivity, hasWriteAccess, isPubliclyAccessible) {
51
+ if (sensitivity === 'critical') {
52
+ return hasWriteAccess ? 'P0' : 'P1';
53
+ }
54
+ if (sensitivity === 'high') {
55
+ return hasWriteAccess ? 'P1' : 'P2';
56
+ }
57
+ if (sensitivity === 'medium') {
58
+ return isPubliclyAccessible ? 'P2' : 'P3';
59
+ }
60
+ return 'P4';
61
+ }
62
+ // ============================================================================
63
+ // Cluster Detection
64
+ // ============================================================================
65
+ /**
66
+ * Detect domain cluster from table name
67
+ */
68
+ function detectCluster(tableName) {
69
+ const name = tableName.toLowerCase();
70
+ // Auth cluster
71
+ if (/^(user|account|session|token|auth|login|password|credential|role|permission)/.test(name)) {
72
+ return 'auth';
73
+ }
74
+ // Commerce cluster
75
+ if (/^(order|product|cart|payment|invoice|transaction|subscription|price|discount)/.test(name)) {
76
+ return 'commerce';
77
+ }
78
+ // Content cluster
79
+ if (/^(post|article|comment|media|file|document|image|video|content)/.test(name)) {
80
+ return 'content';
81
+ }
82
+ // Analytics cluster
83
+ if (/^(event|log|audit|metric|analytics|tracking|stat)/.test(name)) {
84
+ return 'analytics';
85
+ }
86
+ // Communication cluster
87
+ if (/^(message|notification|email|chat|conversation)/.test(name)) {
88
+ return 'communication';
89
+ }
90
+ // Organization cluster
91
+ if (/^(team|organization|company|member|department|group)/.test(name)) {
92
+ return 'organization';
93
+ }
94
+ return 'general';
95
+ }
96
+ // ============================================================================
97
+ // Entry Point Detection
98
+ // ============================================================================
99
+ /**
100
+ * Detect HTTP method from decorators/function name
101
+ */
102
+ function detectHttpMethod(decorators, name) {
103
+ const decoratorStr = decorators.join(' ').toLowerCase();
104
+ const nameLower = name.toLowerCase();
105
+ if (decoratorStr.includes('post') || nameLower.includes('create') || nameLower.includes('add')) {
106
+ return 'POST';
107
+ }
108
+ if (decoratorStr.includes('put') || nameLower.includes('update')) {
109
+ return 'PUT';
110
+ }
111
+ if (decoratorStr.includes('patch')) {
112
+ return 'PATCH';
113
+ }
114
+ if (decoratorStr.includes('delete') || nameLower.includes('delete') || nameLower.includes('remove')) {
115
+ return 'DELETE';
116
+ }
117
+ return 'GET';
118
+ }
119
+ /**
120
+ * Extract route path from decorators
121
+ */
122
+ function extractRoutePath(decorators) {
123
+ for (const dec of decorators) {
124
+ // Express/Flask style: @app.route('/path')
125
+ const routeMatch = dec.match(/route\s*\(\s*['"]([^'"]+)['"]/i);
126
+ if (routeMatch?.[1])
127
+ return routeMatch[1];
128
+ // FastAPI style: @router.get('/path')
129
+ const fastApiMatch = dec.match(/(?:get|post|put|patch|delete)\s*\(\s*['"]([^'"]+)['"]/i);
130
+ if (fastApiMatch?.[1])
131
+ return fastApiMatch[1];
132
+ // Spring style: @GetMapping("/path")
133
+ const springMatch = dec.match(/(?:Get|Post|Put|Patch|Delete)?Mapping\s*\(\s*(?:value\s*=\s*)?['"]([^'"]+)['"]/i);
134
+ if (springMatch?.[1])
135
+ return springMatch[1];
136
+ // ASP.NET style: [HttpGet("path")]
137
+ const aspMatch = dec.match(/Http(?:Get|Post|Put|Patch|Delete)\s*\(\s*['"]([^'"]+)['"]/i);
138
+ if (aspMatch?.[1])
139
+ return aspMatch[1];
140
+ }
141
+ return null;
142
+ }
143
+ /**
144
+ * Detect framework from decorators
145
+ */
146
+ function detectFramework(decorators) {
147
+ const decoratorStr = decorators.join(' ').toLowerCase();
148
+ if (decoratorStr.includes('@app.') || decoratorStr.includes('@router.')) {
149
+ return decoratorStr.includes('fastapi') ? 'FastAPI' : 'Flask';
150
+ }
151
+ if (decoratorStr.includes('mapping') || decoratorStr.includes('@rest')) {
152
+ return 'Spring';
153
+ }
154
+ if (decoratorStr.includes('http') && decoratorStr.includes('[')) {
155
+ return 'ASP.NET';
156
+ }
157
+ if (decoratorStr.includes('route') || decoratorStr.includes('controller')) {
158
+ return 'Express';
159
+ }
160
+ return 'unknown';
161
+ }
162
+ /**
163
+ * Detect auth level from decorators and function context
164
+ */
165
+ function detectAuthLevel(decorators, name) {
166
+ const decoratorStr = decorators.join(' ').toLowerCase();
167
+ const nameLower = name.toLowerCase();
168
+ if (decoratorStr.includes('admin') || nameLower.includes('admin')) {
169
+ return 'admin';
170
+ }
171
+ if (decoratorStr.includes('internal') || nameLower.includes('internal')) {
172
+ return 'internal';
173
+ }
174
+ if (decoratorStr.includes('public') || decoratorStr.includes('allowanonymous')) {
175
+ return 'public';
176
+ }
177
+ if (decoratorStr.includes('auth') || decoratorStr.includes('login') ||
178
+ decoratorStr.includes('protected') || decoratorStr.includes('authorize')) {
179
+ return 'authenticated';
180
+ }
181
+ // Default to authenticated for safety
182
+ return 'authenticated';
183
+ }
184
+ // ============================================================================
185
+ // Galaxy Data Transformer
186
+ // ============================================================================
187
+ export class GalaxyDataTransformer {
188
+ driftDir;
189
+ constructor(driftDir) {
190
+ this.driftDir = driftDir;
191
+ }
192
+ /**
193
+ * Transform Drift data into Galaxy format
194
+ */
195
+ async transform() {
196
+ // Load data sources
197
+ const accessMap = await this.loadAccessMap();
198
+ const callGraph = await this.loadCallGraph();
199
+ // Transform tables
200
+ const tables = this.transformTables(accessMap);
201
+ // Transform entry points from call graph
202
+ const entryPoints = this.transformEntryPoints(callGraph, accessMap);
203
+ // Transform data paths
204
+ const dataPaths = this.transformDataPaths(accessMap, callGraph, entryPoints);
205
+ // Extract relationships from foreign keys
206
+ const relationships = this.extractRelationships(tables);
207
+ // Calculate stats
208
+ const stats = this.calculateStats(tables, entryPoints, dataPaths);
209
+ return {
210
+ tables,
211
+ entryPoints,
212
+ dataPaths,
213
+ relationships,
214
+ stats,
215
+ lastUpdated: new Date().toISOString(),
216
+ };
217
+ }
218
+ /**
219
+ * Load access map from .drift/boundaries
220
+ */
221
+ async loadAccessMap() {
222
+ const accessMapPath = path.join(this.driftDir, 'boundaries', 'access-map.json');
223
+ try {
224
+ const content = await fs.readFile(accessMapPath, 'utf-8');
225
+ return JSON.parse(content);
226
+ }
227
+ catch {
228
+ // Return empty access map if not found
229
+ return {
230
+ version: '1.0',
231
+ generatedAt: new Date().toISOString(),
232
+ projectRoot: '',
233
+ models: [],
234
+ tables: {},
235
+ accessPoints: {},
236
+ sensitiveFields: [],
237
+ stats: {
238
+ totalTables: 0,
239
+ totalAccessPoints: 0,
240
+ totalSensitiveFields: 0,
241
+ totalModels: 0,
242
+ },
243
+ };
244
+ }
245
+ }
246
+ /**
247
+ * Load call graph from .drift/call-graph or .drift/callgraph
248
+ */
249
+ async loadCallGraph() {
250
+ const possiblePaths = [
251
+ path.join(this.driftDir, 'call-graph', 'graph.json'),
252
+ path.join(this.driftDir, 'callgraph', 'graph.json'),
253
+ ];
254
+ for (const graphPath of possiblePaths) {
255
+ try {
256
+ const content = await fs.readFile(graphPath, 'utf-8');
257
+ return JSON.parse(content);
258
+ }
259
+ catch {
260
+ // Try next path
261
+ }
262
+ }
263
+ return null;
264
+ }
265
+ /**
266
+ * Transform tables from access map
267
+ */
268
+ transformTables(accessMap) {
269
+ const tables = [];
270
+ for (const [tableName, tableInfo] of Object.entries(accessMap.tables)) {
271
+ const fields = this.transformFields(tableName, tableInfo, accessMap.sensitiveFields);
272
+ const sensitivity = calculateTableSensitivity(fields);
273
+ const hasWriteAccess = tableInfo.accessedBy.some(a => a.operation === 'write' || a.operation === 'delete');
274
+ tables.push({
275
+ id: tableName,
276
+ name: tableName,
277
+ rowCount: 0, // Not available from boundary scanner
278
+ accessCount: tableInfo.accessedBy.length,
279
+ sensitivity,
280
+ securityTier: calculateSecurityTier(sensitivity, hasWriteAccess, false),
281
+ cluster: detectCluster(tableName),
282
+ fields,
283
+ });
284
+ }
285
+ return tables;
286
+ }
287
+ /**
288
+ * Transform fields for a table
289
+ */
290
+ transformFields(tableName, tableInfo, sensitiveFields) {
291
+ const fields = [];
292
+ const fieldSet = new Set();
293
+ // Add known fields from table info
294
+ for (const fieldName of tableInfo.fields) {
295
+ if (fieldSet.has(fieldName))
296
+ continue;
297
+ fieldSet.add(fieldName);
298
+ const sensitiveField = sensitiveFields.find(sf => sf.field === fieldName && (sf.table === tableName || sf.table === null));
299
+ const foreignKeyTarget = this.inferForeignKeyTarget(fieldName);
300
+ const fieldData = {
301
+ id: `${tableName}.${fieldName}`,
302
+ name: fieldName,
303
+ dataType: 'unknown',
304
+ sensitivity: sensitiveField ? mapSensitivityType(sensitiveField.sensitivityType) : 'low',
305
+ isPrimaryKey: fieldName === 'id' || fieldName.endsWith('_id'),
306
+ isForeignKey: fieldName.endsWith('_id') && fieldName !== 'id',
307
+ accessCount: tableInfo.accessedBy.filter(a => a.fields.includes(fieldName)).length,
308
+ isTested: true, // Would need test coverage data
309
+ };
310
+ if (foreignKeyTarget) {
311
+ fieldData.foreignKeyTarget = foreignKeyTarget;
312
+ }
313
+ fields.push(fieldData);
314
+ }
315
+ // Add sensitive fields not in known fields
316
+ for (const sf of sensitiveFields) {
317
+ if (sf.table === tableName && !fieldSet.has(sf.field)) {
318
+ fieldSet.add(sf.field);
319
+ fields.push({
320
+ id: `${tableName}.${sf.field}`,
321
+ name: sf.field,
322
+ dataType: 'unknown',
323
+ sensitivity: mapSensitivityType(sf.sensitivityType),
324
+ isPrimaryKey: false,
325
+ isForeignKey: false,
326
+ accessCount: 0,
327
+ isTested: true,
328
+ });
329
+ }
330
+ }
331
+ return fields;
332
+ }
333
+ /**
334
+ * Infer foreign key target from field name
335
+ */
336
+ inferForeignKeyTarget(fieldName) {
337
+ if (!fieldName.endsWith('_id') || fieldName === 'id') {
338
+ return undefined;
339
+ }
340
+ // user_id -> users.id
341
+ const baseName = fieldName.replace(/_id$/, '');
342
+ return `${baseName}s.id`;
343
+ }
344
+ /**
345
+ * Transform entry points from call graph
346
+ */
347
+ transformEntryPoints(callGraph, accessMap) {
348
+ const entryPoints = [];
349
+ if (!callGraph) {
350
+ return entryPoints;
351
+ }
352
+ for (const entryPointId of callGraph.entryPoints) {
353
+ const func = callGraph.functions[entryPointId];
354
+ if (!func)
355
+ continue;
356
+ const routePath = extractRoutePath(func.decorators);
357
+ if (!routePath)
358
+ continue; // Skip non-HTTP entry points
359
+ const method = detectHttpMethod(func.decorators, func.name);
360
+ const authLevel = detectAuthLevel(func.decorators, func.name);
361
+ const framework = detectFramework(func.decorators);
362
+ // Find reachable tables through data access
363
+ const reachableTables = this.findReachableTables(func, callGraph);
364
+ // Calculate security tier based on reachable data
365
+ const maxSensitivity = this.getMaxSensitivityForTables(reachableTables, accessMap);
366
+ const securityTier = calculateSecurityTier(maxSensitivity, method !== 'GET', authLevel === 'public');
367
+ entryPoints.push({
368
+ id: `ep-${func.id}`,
369
+ path: routePath,
370
+ method,
371
+ authLevel,
372
+ securityTier,
373
+ file: func.file,
374
+ line: func.startLine,
375
+ framework,
376
+ reachableTables,
377
+ });
378
+ }
379
+ return entryPoints;
380
+ }
381
+ /**
382
+ * Find tables reachable from a function through call graph
383
+ */
384
+ findReachableTables(func, callGraph) {
385
+ const tables = new Set();
386
+ const visited = new Set();
387
+ const traverse = (funcId, depth) => {
388
+ if (depth > 10 || visited.has(funcId))
389
+ return;
390
+ visited.add(funcId);
391
+ const f = callGraph.functions[funcId];
392
+ if (!f)
393
+ return;
394
+ // Add directly accessed tables
395
+ for (const access of f.dataAccess) {
396
+ if (access.table !== 'unknown') {
397
+ tables.add(access.table);
398
+ }
399
+ }
400
+ // Traverse called functions
401
+ for (const call of f.calls) {
402
+ if (call.calleeId) {
403
+ traverse(call.calleeId, depth + 1);
404
+ }
405
+ }
406
+ };
407
+ traverse(func.id, 0);
408
+ return Array.from(tables);
409
+ }
410
+ /**
411
+ * Get maximum sensitivity level for a set of tables
412
+ */
413
+ getMaxSensitivityForTables(tableNames, accessMap) {
414
+ let maxSensitivity = 'public';
415
+ const priorities = ['critical', 'high', 'medium', 'low', 'public'];
416
+ for (const tableName of tableNames) {
417
+ const tableInfo = accessMap.tables[tableName];
418
+ if (!tableInfo)
419
+ continue;
420
+ for (const sf of tableInfo.sensitiveFields) {
421
+ const sensitivity = mapSensitivityType(sf.sensitivityType);
422
+ if (priorities.indexOf(sensitivity) < priorities.indexOf(maxSensitivity)) {
423
+ maxSensitivity = sensitivity;
424
+ }
425
+ }
426
+ }
427
+ return maxSensitivity;
428
+ }
429
+ /**
430
+ * Transform data paths from access points
431
+ */
432
+ transformDataPaths(accessMap, callGraph, entryPoints) {
433
+ const paths = [];
434
+ let pathId = 0;
435
+ // Create paths from entry points to their reachable tables
436
+ for (const ep of entryPoints) {
437
+ for (const tableName of ep.reachableTables) {
438
+ const tableInfo = accessMap.tables[tableName];
439
+ const sensitivity = tableInfo
440
+ ? calculateTableSensitivity(this.transformFields(tableName, tableInfo, accessMap.sensitiveFields))
441
+ : 'low';
442
+ // Determine operation from HTTP method
443
+ let operation = 'read';
444
+ if (ep.method === 'POST')
445
+ operation = 'write';
446
+ else if (ep.method === 'PUT' || ep.method === 'PATCH')
447
+ operation = 'write';
448
+ else if (ep.method === 'DELETE')
449
+ operation = 'delete';
450
+ paths.push({
451
+ id: `path-${++pathId}`,
452
+ sourceId: ep.id,
453
+ sourceType: 'entryPoint',
454
+ targetTableId: tableName,
455
+ operation,
456
+ frequency: tableInfo?.accessedBy.length ?? 1,
457
+ depth: 1, // Would need call graph traversal for accurate depth
458
+ isTested: true, // Would need test coverage data
459
+ callChain: [],
460
+ sensitivity,
461
+ });
462
+ }
463
+ }
464
+ // Also create paths from direct access points if no call graph
465
+ if (!callGraph) {
466
+ for (const accessPoint of Object.values(accessMap.accessPoints)) {
467
+ if (accessPoint.table === 'unknown')
468
+ continue;
469
+ const tableInfo = accessMap.tables[accessPoint.table];
470
+ const sensitivity = tableInfo
471
+ ? calculateTableSensitivity(this.transformFields(accessPoint.table, tableInfo, accessMap.sensitiveFields))
472
+ : 'low';
473
+ paths.push({
474
+ id: `path-${++pathId}`,
475
+ sourceId: `func-${accessPoint.file}:${accessPoint.line}`,
476
+ sourceType: 'function',
477
+ targetTableId: accessPoint.table,
478
+ operation: accessPoint.operation,
479
+ frequency: 1,
480
+ depth: 1,
481
+ isTested: true,
482
+ callChain: [],
483
+ sensitivity,
484
+ });
485
+ }
486
+ }
487
+ return paths;
488
+ }
489
+ /**
490
+ * Extract relationships from foreign keys
491
+ */
492
+ extractRelationships(tables) {
493
+ const relationships = [];
494
+ let relId = 0;
495
+ for (const table of tables) {
496
+ for (const field of table.fields) {
497
+ if (field.isForeignKey && field.foreignKeyTarget) {
498
+ const [targetTable, targetField] = field.foreignKeyTarget.split('.');
499
+ if (targetTable && tables.some(t => t.id === targetTable)) {
500
+ relationships.push({
501
+ id: `rel-${++relId}`,
502
+ sourceTableId: table.id,
503
+ sourceFieldId: field.id,
504
+ targetTableId: targetTable,
505
+ targetFieldId: `${targetTable}.${targetField || 'id'}`,
506
+ type: 'one-to-many',
507
+ });
508
+ }
509
+ }
510
+ }
511
+ }
512
+ return relationships;
513
+ }
514
+ /**
515
+ * Calculate Galaxy statistics
516
+ */
517
+ calculateStats(tables, entryPoints, paths) {
518
+ const sensitiveFields = {
519
+ critical: 0,
520
+ high: 0,
521
+ medium: 0,
522
+ low: 0,
523
+ public: 0,
524
+ };
525
+ let fieldCount = 0;
526
+ for (const table of tables) {
527
+ for (const field of table.fields) {
528
+ fieldCount++;
529
+ sensitiveFields[field.sensitivity]++;
530
+ }
531
+ }
532
+ const untestedPaths = paths.filter(p => !p.isTested).length;
533
+ // Calculate health score
534
+ let healthScore = 100;
535
+ healthScore -= Math.min(30, untestedPaths * 2);
536
+ // Penalize public endpoints accessing sensitive data
537
+ const publicEndpoints = entryPoints.filter(e => e.authLevel === 'public').length;
538
+ healthScore -= Math.min(30, publicEndpoints * 5);
539
+ healthScore -= Math.min(20, (sensitiveFields.critical + sensitiveFields.high) * 0.5);
540
+ healthScore = Math.max(0, Math.round(healthScore));
541
+ return {
542
+ tableCount: tables.length,
543
+ fieldCount,
544
+ entryPointCount: entryPoints.length,
545
+ pathCount: paths.length,
546
+ sensitiveFields,
547
+ untestedPaths,
548
+ deadCodeCount: 0,
549
+ healthScore,
550
+ };
551
+ }
552
+ }
553
+ // ============================================================================
554
+ // Factory
555
+ // ============================================================================
556
+ /**
557
+ * Create a new Galaxy data transformer
558
+ */
559
+ export function createGalaxyDataTransformer(driftDir) {
560
+ return new GalaxyDataTransformer(driftDir);
561
+ }
562
+ //# sourceMappingURL=galaxy-data-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"galaxy-data-transformer.js","sourceRoot":"","sources":["../../src/server/galaxy-data-transformer.ts"],"names":[],"mappings":"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"}