teamshare-bridge 0.3.0 → 0.4.0
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/bridge/daemon.js +36 -0
- package/dist/bridge/daemon.js.map +1 -1
- package/dist/bridge/local-server.d.ts +1 -1
- package/dist/bridge/spawn.d.ts +2 -0
- package/dist/bridge/spawn.js +17 -0
- package/dist/bridge/spawn.js.map +1 -1
- package/dist/cli/commands/audit.d.ts +1 -0
- package/dist/cli/commands/audit.js +75 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/build.js +9 -6
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/doc.js +1 -1
- package/dist/cli/commands/doc.js.map +1 -1
- package/dist/cli/commands/run.js +3 -2
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/scaffold.d.ts +1 -0
- package/dist/cli/commands/scaffold.js +111 -0
- package/dist/cli/commands/scaffold.js.map +1 -0
- package/dist/cli/commands/worker.d.ts +2 -0
- package/dist/cli/commands/worker.js +110 -0
- package/dist/cli/commands/worker.js.map +1 -0
- package/dist/cli/index.js +16 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/lib/api.d.ts +22 -3
- package/dist/lib/api.js +9 -2
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/audit/docs.d.ts +5 -0
- package/dist/lib/audit/docs.js +52 -0
- package/dist/lib/audit/docs.js.map +1 -0
- package/dist/lib/audit/errors.d.ts +15 -0
- package/dist/lib/audit/errors.js +154 -0
- package/dist/lib/audit/errors.js.map +1 -0
- package/dist/lib/audit/gates.d.ts +2 -0
- package/dist/lib/audit/gates.js +57 -0
- package/dist/lib/audit/gates.js.map +1 -0
- package/dist/lib/audit/modularity.d.ts +13 -0
- package/dist/lib/audit/modularity.js +200 -0
- package/dist/lib/audit/modularity.js.map +1 -0
- package/dist/lib/audit/quality.d.ts +9 -0
- package/dist/lib/audit/quality.js +128 -0
- package/dist/lib/audit/quality.js.map +1 -0
- package/dist/lib/audit/rbac.d.ts +14 -0
- package/dist/lib/audit/rbac.js +139 -0
- package/dist/lib/audit/rbac.js.map +1 -0
- package/dist/lib/audit/reporter.d.ts +5 -0
- package/dist/lib/audit/reporter.js +107 -0
- package/dist/lib/audit/reporter.js.map +1 -0
- package/dist/lib/audit/runner.d.ts +2 -0
- package/dist/lib/audit/runner.js +150 -0
- package/dist/lib/audit/runner.js.map +1 -0
- package/dist/lib/audit/security.d.ts +9 -0
- package/dist/lib/audit/security.js +151 -0
- package/dist/lib/audit/security.js.map +1 -0
- package/dist/lib/audit/types.d.ts +67 -0
- package/dist/lib/audit/types.js +26 -0
- package/dist/lib/audit/types.js.map +1 -0
- package/dist/lib/audit/ux.d.ts +9 -0
- package/dist/lib/audit/ux.js +112 -0
- package/dist/lib/audit/ux.js.map +1 -0
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/llm.js +1 -0
- package/dist/lib/llm.js.map +1 -1
- package/dist/lib/lock.d.ts +1 -1
- package/dist/lib/scaffold/renderer.d.ts +7 -0
- package/dist/lib/scaffold/renderer.js +37 -0
- package/dist/lib/scaffold/renderer.js.map +1 -0
- package/dist/lib/scaffold/structure.d.ts +3 -0
- package/dist/lib/scaffold/structure.js +73 -0
- package/dist/lib/scaffold/structure.js.map +1 -0
- package/dist/lib/scaffold/types.d.ts +34 -0
- package/dist/lib/scaffold/types.js +6 -0
- package/dist/lib/scaffold/types.js.map +1 -0
- package/dist/lib/scaffold/verify.d.ts +9 -0
- package/dist/lib/scaffold/verify.js +48 -0
- package/dist/lib/scaffold/verify.js.map +1 -0
- package/dist/lib/skills.d.ts +2 -2
- package/dist/lib/skills.js +2 -1
- package/dist/lib/skills.js.map +1 -1
- package/package.json +3 -2
- package/skills/teamshare-orchestrator-ask/SKILL.md +14 -0
- package/skills/teamshare-scaffold/SKILL.md +133 -0
- package/templates/backend/.env.example.tpl +13 -0
- package/templates/backend/nest-cli.json.tpl +8 -0
- package/templates/backend/package.json.tpl +41 -0
- package/templates/backend/prisma/schema.prisma.tpl +39 -0
- package/templates/backend/src/app.module.ts.tpl +24 -0
- package/templates/backend/src/common/filters/all-exceptions.filter.ts.tpl +59 -0
- package/templates/backend/src/common/guards/jwt-auth.guard.ts.tpl +27 -0
- package/templates/backend/src/common/guards/rbac.guard.ts.tpl +48 -0
- package/templates/backend/src/common/interceptors/transform.interceptor.ts.tpl +44 -0
- package/templates/backend/src/common/pipes/zod-validation.pipe.ts.tpl +29 -0
- package/templates/backend/src/common/swagger/envelope.schemas.ts.tpl +53 -0
- package/templates/backend/src/common/swagger/error.schemas.ts.tpl +62 -0
- package/templates/backend/src/main.ts.tpl +27 -0
- package/templates/backend/src/modules/example/example.controller.ts.tpl +102 -0
- package/templates/backend/src/modules/example/example.dto.ts.tpl +14 -0
- package/templates/backend/src/modules/example/example.module.ts.tpl +10 -0
- package/templates/backend/src/modules/example/example.service.ts.tpl +45 -0
- package/templates/backend/tsconfig.json.tpl +26 -0
- package/templates/common/.gitignore.tpl +42 -0
- package/templates/common/AGENTS.md.tpl +58 -0
- package/templates/common/docs/adr/README.md +25 -0
- package/templates/common/docs/api-contract.md.tpl +72 -0
- package/templates/web/next.config.ts.tpl +7 -0
- package/templates/web/package.json.tpl +37 -0
- package/templates/web/src/app/globals.css.tpl +48 -0
- package/templates/web/src/app/layout.tsx.tpl +25 -0
- package/templates/web/src/components/shared/app-button.tsx.tpl +59 -0
- package/templates/web/src/components/shared/app-empty-state.tsx.tpl +39 -0
- package/templates/web/src/components/shared/app-list-toolbar.tsx.tpl +63 -0
- package/templates/web/src/components/shared/app-skeleton.tsx.tpl +14 -0
- package/templates/web/src/components/shared/app-table.tsx.tpl +128 -0
- package/templates/web/src/components/shared/index.ts.tpl +5 -0
- package/templates/web/src/hooks/use-list-state.ts.tpl +72 -0
- package/templates/web/src/hooks/use-url-tab.ts.tpl +25 -0
- package/templates/web/src/lib/api/client.ts.tpl +123 -0
- package/templates/web/src/lib/providers.tsx.tpl +35 -0
- package/templates/web/src/lib/query-keys.ts.tpl +21 -0
- package/templates/web/src/lib/utils.ts.tpl +7 -0
- package/templates/web/src/lib/validation/schemas.ts.tpl +15 -0
- package/templates/web/src/modules/example/views/example-list-view.tsx.tpl +98 -0
- package/templates/web/tsconfig.json.tpl +23 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RBAC checker — verifies that backend controllers have proper access
|
|
4
|
+
* metadata on every method, that auth guards exist and are registered
|
|
5
|
+
* globally, and that the RBAC constants file is present.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.runRBACChecks = runRBACChecks;
|
|
9
|
+
const types_1 = require("./types");
|
|
10
|
+
const ACCESS_METADATA = [
|
|
11
|
+
/@Permissions\(/,
|
|
12
|
+
/@Public\(/,
|
|
13
|
+
/@UseGuards\(/,
|
|
14
|
+
/@ApiKeyScopes\(/,
|
|
15
|
+
];
|
|
16
|
+
/**
|
|
17
|
+
* Check a controller file for methods missing access metadata.
|
|
18
|
+
* A method is any line with @Get, @Post, @Put, @Patch, @Delete, @All decorator.
|
|
19
|
+
*/
|
|
20
|
+
function checkControllerMethods(content, rel) {
|
|
21
|
+
const findings = [];
|
|
22
|
+
const lines = content.split('\n');
|
|
23
|
+
const METHOD_DECORATORS = /@(Get|Post|Put|Patch|Delete|All)\(/;
|
|
24
|
+
for (let i = 0; i < lines.length; i++) {
|
|
25
|
+
if (!METHOD_DECORATORS.test(lines[i]))
|
|
26
|
+
continue;
|
|
27
|
+
// Scan backwards from the method decorator to find the block start,
|
|
28
|
+
// and forwards to find the method body — check all decorators in between
|
|
29
|
+
let hasAccessControl = false;
|
|
30
|
+
const start = Math.max(0, i - 15);
|
|
31
|
+
const end = Math.min(lines.length - 1, i + 20);
|
|
32
|
+
for (let j = start; j <= end; j++) {
|
|
33
|
+
for (const pattern of ACCESS_METADATA) {
|
|
34
|
+
if (pattern.test(lines[j])) {
|
|
35
|
+
hasAccessControl = true;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (hasAccessControl)
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
if (!hasAccessControl) {
|
|
43
|
+
findings.push({
|
|
44
|
+
severity: types_1.Severity.High,
|
|
45
|
+
category: types_1.Category.RBAC,
|
|
46
|
+
file: rel,
|
|
47
|
+
line: i + 1,
|
|
48
|
+
message: 'Controller method missing access metadata (@Permissions, @Public, or @UseGuards)',
|
|
49
|
+
evidence: lines[i].trim(),
|
|
50
|
+
suggestedFix: 'Add @Permissions(), @Public(), or @UseGuards() to this endpoint.',
|
|
51
|
+
rule: 'RBAC-001',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return findings;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check that the RBAC constants file exists.
|
|
59
|
+
*/
|
|
60
|
+
function checkRBACConstants(ctx) {
|
|
61
|
+
const findings = [];
|
|
62
|
+
if (!ctx.fileExists('src/common/constants/rbac.ts')) {
|
|
63
|
+
findings.push({
|
|
64
|
+
severity: types_1.Severity.Medium,
|
|
65
|
+
category: types_1.Category.RBAC,
|
|
66
|
+
file: 'src/common/constants/rbac.ts',
|
|
67
|
+
message: 'Missing RBAC constants file — permissions matrix not defined',
|
|
68
|
+
suggestedFix: 'Create src/common/constants/rbac.ts with the roles/permissions matrix.',
|
|
69
|
+
rule: 'RBAC-002',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return findings;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check that the JWT auth guard exists.
|
|
76
|
+
*/
|
|
77
|
+
function checkJWTGuard(ctx) {
|
|
78
|
+
const findings = [];
|
|
79
|
+
if (!ctx.fileExists('src/common/guards/jwt-auth.guard.ts') &&
|
|
80
|
+
!ctx.fileExists('src/common/guards/jwt.guard.ts')) {
|
|
81
|
+
findings.push({
|
|
82
|
+
severity: types_1.Severity.High,
|
|
83
|
+
category: types_1.Category.RBAC,
|
|
84
|
+
file: 'src/common/guards/jwt-auth.guard.ts',
|
|
85
|
+
message: 'Missing JWT auth guard — authentication cannot be enforced',
|
|
86
|
+
suggestedFix: 'Create src/common/guards/jwt-auth.guard.ts implementing AuthGuard("jwt").',
|
|
87
|
+
rule: 'RBAC-003',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return findings;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check that global guards are registered in app.module.ts.
|
|
94
|
+
*/
|
|
95
|
+
function checkGlobalGuardRegistration(ctx) {
|
|
96
|
+
const findings = [];
|
|
97
|
+
if (!ctx.fileExists('src/app.module.ts'))
|
|
98
|
+
return findings;
|
|
99
|
+
const content = ctx.readFile('src/app.module.ts');
|
|
100
|
+
if (!content)
|
|
101
|
+
return findings;
|
|
102
|
+
if (!/APP_GUARD/.test(content)) {
|
|
103
|
+
findings.push({
|
|
104
|
+
severity: types_1.Severity.High,
|
|
105
|
+
category: types_1.Category.RBAC,
|
|
106
|
+
file: 'src/app.module.ts',
|
|
107
|
+
message: 'app.module.ts does not register a global APP_GUARD — RBAC not enforced globally',
|
|
108
|
+
suggestedFix: 'Add { provide: APP_GUARD, useClass: RbacGuard } (or JwtAuthGuard) to the providers array.',
|
|
109
|
+
rule: 'RBAC-004',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return findings;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Run all RBAC checks against the repository.
|
|
116
|
+
*
|
|
117
|
+
* Type-aware: all checks are NestJS-backend-specific, so they run only
|
|
118
|
+
* when the repo is a backend. Generic repos (repoType "unknown") are not
|
|
119
|
+
* flagged for missing guards/rbac constants they never promised to have.
|
|
120
|
+
*/
|
|
121
|
+
function runRBACChecks(ctx) {
|
|
122
|
+
const findings = [];
|
|
123
|
+
if (ctx.repoType === 'backend') {
|
|
124
|
+
const controllers = ctx.listFiles('**/*.controller.ts');
|
|
125
|
+
for (const rel of controllers) {
|
|
126
|
+
if (/node_modules|dist|generated/.test(rel))
|
|
127
|
+
continue;
|
|
128
|
+
const content = ctx.readFile(rel);
|
|
129
|
+
if (!content)
|
|
130
|
+
continue;
|
|
131
|
+
findings.push(...checkControllerMethods(content, rel));
|
|
132
|
+
}
|
|
133
|
+
findings.push(...checkRBACConstants(ctx));
|
|
134
|
+
findings.push(...checkJWTGuard(ctx));
|
|
135
|
+
findings.push(...checkGlobalGuardRegistration(ctx));
|
|
136
|
+
}
|
|
137
|
+
return findings;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=rbac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rbac.js","sourceRoot":"","sources":["../../../src/lib/audit/rbac.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateReport = generateReport;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const SEVERITY_ORDER = [
|
|
6
|
+
types_1.Severity.Critical,
|
|
7
|
+
types_1.Severity.High,
|
|
8
|
+
types_1.Severity.Medium,
|
|
9
|
+
types_1.Severity.Low,
|
|
10
|
+
types_1.Severity.Advisory,
|
|
11
|
+
];
|
|
12
|
+
const CATEGORY_LABELS = {
|
|
13
|
+
[types_1.Category.Security]: 'Security',
|
|
14
|
+
[types_1.Category.Modularity]: 'Modularity',
|
|
15
|
+
[types_1.Category.RBAC]: 'RBAC / Access Control',
|
|
16
|
+
[types_1.Category.Errors]: 'Error Handling',
|
|
17
|
+
[types_1.Category.Quality]: 'Code Quality',
|
|
18
|
+
[types_1.Category.UX]: 'UX / Loading States',
|
|
19
|
+
[types_1.Category.Docs]: 'Documentation',
|
|
20
|
+
[types_1.Category.Gates]: 'Build Gates',
|
|
21
|
+
};
|
|
22
|
+
function generateReport(result) {
|
|
23
|
+
const lines = [];
|
|
24
|
+
lines.push(`# Audit Report — ${result.repoName}`);
|
|
25
|
+
lines.push('');
|
|
26
|
+
lines.push(`**Date:** ${new Date(result.startedAt).toISOString().slice(0, 10)}`);
|
|
27
|
+
lines.push(`**Path:** ${result.repoPath}`);
|
|
28
|
+
lines.push(`**Type:** ${result.repoType}`);
|
|
29
|
+
lines.push(`**Existing repo:** ${result.isExistingRepo ? 'Yes (advisory findings only for structural issues)' : 'No'}`);
|
|
30
|
+
lines.push(`**Files scanned:** ${result.scannedFiles}`);
|
|
31
|
+
lines.push('');
|
|
32
|
+
// Gate results
|
|
33
|
+
if (result.gateResults.length > 0) {
|
|
34
|
+
lines.push('## Build Gates');
|
|
35
|
+
lines.push('');
|
|
36
|
+
for (const gate of result.gateResults) {
|
|
37
|
+
const icon = gate.passed ? 'PASS' : 'FAIL';
|
|
38
|
+
lines.push(`- **${gate.name}:** ${icon}`);
|
|
39
|
+
if (!gate.passed && gate.error) {
|
|
40
|
+
const snippet = gate.error.split('\n').slice(0, 5).join('\n ');
|
|
41
|
+
lines.push(` \`\`\`\n ${snippet}\n \`\`\``);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
lines.push('');
|
|
45
|
+
}
|
|
46
|
+
// Group findings by severity
|
|
47
|
+
const bySeverity = new Map();
|
|
48
|
+
for (const sev of SEVERITY_ORDER) {
|
|
49
|
+
const items = result.findings.filter((f) => f.severity === sev);
|
|
50
|
+
if (items.length > 0)
|
|
51
|
+
bySeverity.set(sev, items);
|
|
52
|
+
}
|
|
53
|
+
for (const [sev, items] of bySeverity) {
|
|
54
|
+
const label = sev.charAt(0).toUpperCase() + sev.slice(1);
|
|
55
|
+
lines.push(`## ${label} (${items.length})`);
|
|
56
|
+
lines.push('');
|
|
57
|
+
// Group by category within severity
|
|
58
|
+
const byCategory = new Map();
|
|
59
|
+
for (const cat of Object.values(types_1.Category)) {
|
|
60
|
+
const catItems = items.filter((f) => f.category === cat);
|
|
61
|
+
if (catItems.length > 0)
|
|
62
|
+
byCategory.set(cat, catItems);
|
|
63
|
+
}
|
|
64
|
+
for (const [cat, catItems] of byCategory) {
|
|
65
|
+
lines.push(`### ${CATEGORY_LABELS[cat]}`);
|
|
66
|
+
lines.push('');
|
|
67
|
+
for (const f of catItems) {
|
|
68
|
+
const loc = f.line ? `${f.file}:${f.line}` : f.file;
|
|
69
|
+
lines.push(`- **${loc}** — ${f.message}`);
|
|
70
|
+
if (f.evidence)
|
|
71
|
+
lines.push(` Evidence: \`${f.evidence}\``);
|
|
72
|
+
if (f.suggestedFix)
|
|
73
|
+
lines.push(` Fix: ${f.suggestedFix}`);
|
|
74
|
+
if (f.rule)
|
|
75
|
+
lines.push(` Rule: \`${f.rule}\``);
|
|
76
|
+
}
|
|
77
|
+
lines.push('');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Summary
|
|
81
|
+
lines.push('## Summary');
|
|
82
|
+
lines.push('');
|
|
83
|
+
const counts = new Map();
|
|
84
|
+
for (const sev of SEVERITY_ORDER) {
|
|
85
|
+
counts.set(sev, result.findings.filter((f) => f.severity === sev).length);
|
|
86
|
+
}
|
|
87
|
+
const total = result.findings.length;
|
|
88
|
+
lines.push(`- **Total findings:** ${total}`);
|
|
89
|
+
lines.push(` - Critical: ${counts.get(types_1.Severity.Critical) ?? 0}`);
|
|
90
|
+
lines.push(` - High: ${counts.get(types_1.Severity.High) ?? 0}`);
|
|
91
|
+
lines.push(` - Medium: ${counts.get(types_1.Severity.Medium) ?? 0}`);
|
|
92
|
+
lines.push(` - Low: ${counts.get(types_1.Severity.Low) ?? 0}`);
|
|
93
|
+
lines.push(` - Advisory: ${counts.get(types_1.Severity.Advisory) ?? 0}`);
|
|
94
|
+
lines.push('');
|
|
95
|
+
const gatePass = result.gateResults.every((g) => g.passed);
|
|
96
|
+
lines.push(`- **Gate status:** ${gatePass ? 'All passing' : 'Some failing'}`);
|
|
97
|
+
for (const gate of result.gateResults) {
|
|
98
|
+
lines.push(` - ${gate.name}: ${gate.passed ? 'PASS' : 'FAIL'}`);
|
|
99
|
+
}
|
|
100
|
+
lines.push('');
|
|
101
|
+
if (result.isExistingRepo) {
|
|
102
|
+
lines.push('**Note:** This is an existing repo. Structural findings are advisory only — no forced restructure.');
|
|
103
|
+
lines.push('');
|
|
104
|
+
}
|
|
105
|
+
return lines.join('\n');
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../../src/lib/audit/reporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAudit = runAudit;
|
|
4
|
+
/**
|
|
5
|
+
* Audit runner — orchestrates all checkers and produces an AuditResult.
|
|
6
|
+
*/
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const types_1 = require("./types");
|
|
10
|
+
const security_1 = require("./security");
|
|
11
|
+
const modularity_1 = require("./modularity");
|
|
12
|
+
const rbac_1 = require("./rbac");
|
|
13
|
+
const errors_1 = require("./errors");
|
|
14
|
+
const quality_1 = require("./quality");
|
|
15
|
+
const ux_1 = require("./ux");
|
|
16
|
+
const docs_1 = require("./docs");
|
|
17
|
+
const gates_1 = require("./gates");
|
|
18
|
+
function detectRepoType(root) {
|
|
19
|
+
const pkgPath = (0, node_path_1.join)(root, 'package.json');
|
|
20
|
+
try {
|
|
21
|
+
const pkg = JSON.parse((0, node_fs_1.readFileSync)(pkgPath, 'utf-8'));
|
|
22
|
+
const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
|
|
23
|
+
if (deps['next'] || deps['next.js'])
|
|
24
|
+
return 'web';
|
|
25
|
+
if (deps['@nestjs/core'] || deps['@nestjs/common'])
|
|
26
|
+
return 'backend';
|
|
27
|
+
if (deps['expo'])
|
|
28
|
+
return 'mobile';
|
|
29
|
+
}
|
|
30
|
+
catch { /* no package.json */ }
|
|
31
|
+
// Fallback: check for key files
|
|
32
|
+
try {
|
|
33
|
+
if ((0, node_fs_1.readFileSync)((0, node_path_1.join)(root, 'next.config.ts'), 'utf-8'))
|
|
34
|
+
return 'web';
|
|
35
|
+
}
|
|
36
|
+
catch { /* no next.config */ }
|
|
37
|
+
try {
|
|
38
|
+
if ((0, node_fs_1.readFileSync)((0, node_path_1.join)(root, 'nest-cli.json'), 'utf-8'))
|
|
39
|
+
return 'backend';
|
|
40
|
+
}
|
|
41
|
+
catch { /* no nest-cli */ }
|
|
42
|
+
return 'unknown';
|
|
43
|
+
}
|
|
44
|
+
function collectFiles(root, patterns) {
|
|
45
|
+
const files = [];
|
|
46
|
+
const ignoreDirs = new Set(['node_modules', 'dist', '.next', '.expo', 'generated', '.git', 'coverage']);
|
|
47
|
+
function walk(dir) {
|
|
48
|
+
let entries;
|
|
49
|
+
try {
|
|
50
|
+
entries = (0, node_fs_1.readdirSync)(dir);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
for (const name of entries) {
|
|
56
|
+
if (ignoreDirs.has(name))
|
|
57
|
+
continue;
|
|
58
|
+
const fullPath = (0, node_path_1.join)(dir, name);
|
|
59
|
+
try {
|
|
60
|
+
const stat = (0, node_fs_1.statSync)(fullPath);
|
|
61
|
+
if (stat.isDirectory()) {
|
|
62
|
+
walk(fullPath);
|
|
63
|
+
}
|
|
64
|
+
else if (stat.isFile()) {
|
|
65
|
+
const ext = name.slice(name.lastIndexOf('.'));
|
|
66
|
+
if (patterns.some((p) => ext === p)) {
|
|
67
|
+
files.push(fullPath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// skip inaccessible files
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
walk(root);
|
|
77
|
+
return files;
|
|
78
|
+
}
|
|
79
|
+
function buildContext(root, repoType, isExistingRepo) {
|
|
80
|
+
return {
|
|
81
|
+
root,
|
|
82
|
+
repoType,
|
|
83
|
+
isExistingRepo,
|
|
84
|
+
readFile(relativePath) {
|
|
85
|
+
try {
|
|
86
|
+
return (0, node_fs_1.readFileSync)((0, node_path_1.join)(root, relativePath), 'utf-8');
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
listFiles(glob) {
|
|
93
|
+
// Simple glob: only handles **/*.ext and dir/*.ext
|
|
94
|
+
const ext = glob.includes('*') ? glob.split('*').pop()?.replace('.', '') ?? 'ts' : 'ts';
|
|
95
|
+
const dirPart = glob.split('*')[0];
|
|
96
|
+
const searchDir = dirPart ? (0, node_path_1.join)(root, dirPart) : root;
|
|
97
|
+
const collected = collectFiles(searchDir, ['.' + ext]);
|
|
98
|
+
return collected.map((f) => (0, node_path_1.relative)(root, f));
|
|
99
|
+
},
|
|
100
|
+
fileExists(relativePath) {
|
|
101
|
+
try {
|
|
102
|
+
(0, node_fs_1.statSync)((0, node_path_1.join)(root, relativePath));
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
async function runAudit(options) {
|
|
112
|
+
const root = options.path;
|
|
113
|
+
const repoType = options.type === 'auto' || !options.type ? detectRepoType(root) : options.type;
|
|
114
|
+
const isExistingRepo = options.existingRepo ?? false;
|
|
115
|
+
const ctx = buildContext(root, repoType, isExistingRepo);
|
|
116
|
+
const tsFiles = collectFiles(root, ['.ts', '.tsx']);
|
|
117
|
+
const startedAt = new Date().toISOString();
|
|
118
|
+
const findings = [];
|
|
119
|
+
// Run all checkers
|
|
120
|
+
findings.push(...(0, security_1.runSecurityChecks)(ctx));
|
|
121
|
+
findings.push(...(0, modularity_1.runModularityChecks)(ctx));
|
|
122
|
+
findings.push(...(0, rbac_1.runRBACChecks)(ctx));
|
|
123
|
+
findings.push(...(0, errors_1.runErrorChecks)(ctx));
|
|
124
|
+
findings.push(...(0, quality_1.runQualityChecks)(ctx));
|
|
125
|
+
findings.push(...(0, ux_1.runUXChecks)(ctx));
|
|
126
|
+
findings.push(...(0, docs_1.runDocsChecks)(ctx));
|
|
127
|
+
// Downgrade structural findings to Advisory for existing repos
|
|
128
|
+
if (isExistingRepo) {
|
|
129
|
+
for (const f of findings) {
|
|
130
|
+
if (f.category === 'modularity' &&
|
|
131
|
+
(f.rule?.startsWith('structure') || f.message.includes('missing'))) {
|
|
132
|
+
f.severity = types_1.Severity.Advisory;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Run gates (may be slow) — skipped on request for fast structural audits
|
|
137
|
+
const gateResults = options.skipGates ? [] : (0, gates_1.runGateChecks)(ctx);
|
|
138
|
+
return {
|
|
139
|
+
repoName: root.split(/[/\\]/).pop() ?? 'unknown',
|
|
140
|
+
repoPath: root,
|
|
141
|
+
repoType,
|
|
142
|
+
isExistingRepo,
|
|
143
|
+
findings,
|
|
144
|
+
gateResults,
|
|
145
|
+
scannedFiles: tsFiles.length,
|
|
146
|
+
startedAt,
|
|
147
|
+
completedAt: new Date().toISOString(),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/lib/audit/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security checker — scans source files for hardcoded secrets,
|
|
3
|
+
* unguarded public endpoints, and dangerous React patterns.
|
|
4
|
+
*/
|
|
5
|
+
import type { Finding, CheckerContext } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Run all security checks against the repository.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runSecurityChecks(ctx: CheckerContext): Finding[];
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security checker — scans source files for hardcoded secrets,
|
|
4
|
+
* unguarded public endpoints, and dangerous React patterns.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.runSecurityChecks = runSecurityChecks;
|
|
8
|
+
const types_1 = require("./types");
|
|
9
|
+
const SECRET_PATTERNS = [
|
|
10
|
+
{ pattern: /sk_live_[A-Za-z0-9]+/, name: 'Stripe live key', severity: types_1.Severity.Critical },
|
|
11
|
+
{ pattern: /sk_test_[A-Za-z0-9]+/, name: 'Stripe test key', severity: types_1.Severity.High },
|
|
12
|
+
{ pattern: /AIza[A-Za-z0-9_-]+/, name: 'Google API key', severity: types_1.Severity.Critical },
|
|
13
|
+
{ pattern: /Bearer\s+[A-Za-z0-9]/, name: 'Hardcoded bearer token', severity: types_1.Severity.Critical },
|
|
14
|
+
{ pattern: /PASSWORD\s*=\s*['"][^'"]+['"]/, name: 'Hardcoded password', severity: types_1.Severity.Critical },
|
|
15
|
+
{ pattern: /SECRET\s*=\s*['"][^'"]+['"]/, name: 'Hardcoded secret', severity: types_1.Severity.Critical },
|
|
16
|
+
{ pattern: /KEY\s*=\s*['"][^'"]+['"]/, name: 'Hardcoded key', severity: types_1.Severity.High },
|
|
17
|
+
{
|
|
18
|
+
pattern: /['"][0-9a-f]{32,}['"]/,
|
|
19
|
+
name: 'Potential hex secret',
|
|
20
|
+
severity: types_1.Severity.Medium,
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* TeamShare agent keys start with `ts_` followed by alphanumerics.
|
|
25
|
+
* We exclude lines that look like type imports or enum values.
|
|
26
|
+
*/
|
|
27
|
+
const TS_KEY_PATTERN = /\bts_[A-Za-z0-9]{16,}\b/;
|
|
28
|
+
const TS_KEY_EXCLUSION = /import\s|type\s|enum\s|\/\//;
|
|
29
|
+
const SKIP_PATHS = /node_modules|\.env\.example|\.test\.|\.spec\.|__tests__|generated\//;
|
|
30
|
+
function shouldSkipFile(rel) {
|
|
31
|
+
return SKIP_PATHS.test(rel);
|
|
32
|
+
}
|
|
33
|
+
function isTypeDefinition(rel) {
|
|
34
|
+
return /\.d\.ts$/.test(rel);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check a single line for secret patterns.
|
|
38
|
+
*/
|
|
39
|
+
function checkLineForSecrets(line, rel, lineNum) {
|
|
40
|
+
const findings = [];
|
|
41
|
+
// ts_ key pattern — skip type imports and comments
|
|
42
|
+
if (TS_KEY_PATTERN.test(line) && !TS_KEY_EXCLUSION.test(line)) {
|
|
43
|
+
findings.push({
|
|
44
|
+
severity: types_1.Severity.Critical,
|
|
45
|
+
category: types_1.Category.Security,
|
|
46
|
+
file: rel,
|
|
47
|
+
line: lineNum,
|
|
48
|
+
message: 'Potential TeamShare agent key found in source code',
|
|
49
|
+
evidence: line.trim(),
|
|
50
|
+
suggestedFix: 'Move secrets to environment variables or the Vault; never hardcode keys.',
|
|
51
|
+
rule: 'SEC-001',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
for (const { pattern, name, severity } of SECRET_PATTERNS) {
|
|
55
|
+
if (pattern.test(line)) {
|
|
56
|
+
findings.push({
|
|
57
|
+
severity,
|
|
58
|
+
category: types_1.Category.Security,
|
|
59
|
+
file: rel,
|
|
60
|
+
line: lineNum,
|
|
61
|
+
message: `${name} detected in source code`,
|
|
62
|
+
evidence: line.trim(),
|
|
63
|
+
suggestedFix: 'Move secrets to environment variables or a secrets manager.',
|
|
64
|
+
rule: 'SEC-002',
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return findings;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Check a controller file for @Public() without any guard.
|
|
72
|
+
*/
|
|
73
|
+
function checkUnguardedPublic(content, rel) {
|
|
74
|
+
const findings = [];
|
|
75
|
+
const lines = content.split('\n');
|
|
76
|
+
const hasPublicDecorator = /@Public\(\)/.test(content);
|
|
77
|
+
if (!hasPublicDecorator)
|
|
78
|
+
return findings;
|
|
79
|
+
const hasGuard = /@UseGuards\(/.test(content) ||
|
|
80
|
+
/AgentsDualAuthGuard/.test(content) ||
|
|
81
|
+
/ApiKeyGuard/.test(content);
|
|
82
|
+
if (hasGuard)
|
|
83
|
+
return findings;
|
|
84
|
+
// Find the line with @Public()
|
|
85
|
+
for (let i = 0; i < lines.length; i++) {
|
|
86
|
+
if (/@Public\(\)/.test(lines[i])) {
|
|
87
|
+
findings.push({
|
|
88
|
+
severity: types_1.Severity.Critical,
|
|
89
|
+
category: types_1.Category.Security,
|
|
90
|
+
file: rel,
|
|
91
|
+
line: i + 1,
|
|
92
|
+
message: '@Public() decorator used without any guard — endpoint is completely unprotected',
|
|
93
|
+
evidence: lines[i].trim(),
|
|
94
|
+
suggestedFix: 'Add @UseGuards(AuthGuard) or @UseGuards(AgentsDualAuthGuard) to protect this endpoint.',
|
|
95
|
+
rule: 'SEC-003',
|
|
96
|
+
});
|
|
97
|
+
break; // Only report once per file
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return findings;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Check for dangerouslySetInnerHTML in React components.
|
|
104
|
+
*/
|
|
105
|
+
function checkDangerouslySetInnerHTML(content, rel) {
|
|
106
|
+
const findings = [];
|
|
107
|
+
const lines = content.split('\n');
|
|
108
|
+
for (let i = 0; i < lines.length; i++) {
|
|
109
|
+
if (/dangerouslySetInnerHTML/.test(lines[i])) {
|
|
110
|
+
findings.push({
|
|
111
|
+
severity: types_1.Severity.Medium,
|
|
112
|
+
category: types_1.Category.Security,
|
|
113
|
+
file: rel,
|
|
114
|
+
line: i + 1,
|
|
115
|
+
message: 'dangerouslySetInnerHTML used — potential XSS vector',
|
|
116
|
+
evidence: lines[i].trim(),
|
|
117
|
+
suggestedFix: 'Sanitize HTML input or use a library like DOMPurify before rendering.',
|
|
118
|
+
rule: 'SEC-004',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return findings;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Run all security checks against the repository.
|
|
126
|
+
*/
|
|
127
|
+
function runSecurityChecks(ctx) {
|
|
128
|
+
const findings = [];
|
|
129
|
+
const files = ctx.listFiles('**/*.{ts,tsx}');
|
|
130
|
+
for (const rel of files) {
|
|
131
|
+
if (shouldSkipFile(rel) || isTypeDefinition(rel))
|
|
132
|
+
continue;
|
|
133
|
+
const content = ctx.readFile(rel);
|
|
134
|
+
if (!content)
|
|
135
|
+
continue;
|
|
136
|
+
const lines = content.split('\n');
|
|
137
|
+
for (let i = 0; i < lines.length; i++) {
|
|
138
|
+
findings.push(...checkLineForSecrets(lines[i], rel, i + 1));
|
|
139
|
+
}
|
|
140
|
+
// Controller guard check — only for backend controllers
|
|
141
|
+
if (rel.includes('.controller.ts')) {
|
|
142
|
+
findings.push(...checkUnguardedPublic(content, rel));
|
|
143
|
+
}
|
|
144
|
+
// dangerouslySetInnerHTML — only for TSX files
|
|
145
|
+
if (rel.endsWith('.tsx')) {
|
|
146
|
+
findings.push(...checkDangerouslySetInnerHTML(content, rel));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return findings;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/lib/audit/security.ts"],"names":[],"mappings":"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"}
|