@oculum/scanner 1.0.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/formatters/cli-terminal.d.ts +27 -0
- package/dist/formatters/cli-terminal.d.ts.map +1 -0
- package/dist/formatters/cli-terminal.js +412 -0
- package/dist/formatters/cli-terminal.js.map +1 -0
- package/dist/formatters/github-comment.d.ts +41 -0
- package/dist/formatters/github-comment.d.ts.map +1 -0
- package/dist/formatters/github-comment.js +306 -0
- package/dist/formatters/github-comment.js.map +1 -0
- package/dist/formatters/grouping.d.ts +52 -0
- package/dist/formatters/grouping.d.ts.map +1 -0
- package/dist/formatters/grouping.js +152 -0
- package/dist/formatters/grouping.js.map +1 -0
- package/dist/formatters/index.d.ts +9 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +35 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/vscode-diagnostic.d.ts +103 -0
- package/dist/formatters/vscode-diagnostic.d.ts.map +1 -0
- package/dist/formatters/vscode-diagnostic.js +151 -0
- package/dist/formatters/vscode-diagnostic.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +648 -0
- package/dist/index.js.map +1 -0
- package/dist/layer1/comments.d.ts +8 -0
- package/dist/layer1/comments.d.ts.map +1 -0
- package/dist/layer1/comments.js +203 -0
- package/dist/layer1/comments.js.map +1 -0
- package/dist/layer1/config-audit.d.ts +8 -0
- package/dist/layer1/config-audit.d.ts.map +1 -0
- package/dist/layer1/config-audit.js +252 -0
- package/dist/layer1/config-audit.js.map +1 -0
- package/dist/layer1/entropy.d.ts +8 -0
- package/dist/layer1/entropy.d.ts.map +1 -0
- package/dist/layer1/entropy.js +500 -0
- package/dist/layer1/entropy.js.map +1 -0
- package/dist/layer1/file-flags.d.ts +7 -0
- package/dist/layer1/file-flags.d.ts.map +1 -0
- package/dist/layer1/file-flags.js +112 -0
- package/dist/layer1/file-flags.js.map +1 -0
- package/dist/layer1/index.d.ts +36 -0
- package/dist/layer1/index.d.ts.map +1 -0
- package/dist/layer1/index.js +132 -0
- package/dist/layer1/index.js.map +1 -0
- package/dist/layer1/patterns.d.ts +8 -0
- package/dist/layer1/patterns.d.ts.map +1 -0
- package/dist/layer1/patterns.js +482 -0
- package/dist/layer1/patterns.js.map +1 -0
- package/dist/layer1/urls.d.ts +8 -0
- package/dist/layer1/urls.d.ts.map +1 -0
- package/dist/layer1/urls.js +296 -0
- package/dist/layer1/urls.js.map +1 -0
- package/dist/layer1/weak-crypto.d.ts +7 -0
- package/dist/layer1/weak-crypto.d.ts.map +1 -0
- package/dist/layer1/weak-crypto.js +291 -0
- package/dist/layer1/weak-crypto.js.map +1 -0
- package/dist/layer2/ai-agent-tools.d.ts +19 -0
- package/dist/layer2/ai-agent-tools.d.ts.map +1 -0
- package/dist/layer2/ai-agent-tools.js +528 -0
- package/dist/layer2/ai-agent-tools.js.map +1 -0
- package/dist/layer2/ai-endpoint-protection.d.ts +36 -0
- package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -0
- package/dist/layer2/ai-endpoint-protection.js +332 -0
- package/dist/layer2/ai-endpoint-protection.js.map +1 -0
- package/dist/layer2/ai-execution-sinks.d.ts +18 -0
- package/dist/layer2/ai-execution-sinks.d.ts.map +1 -0
- package/dist/layer2/ai-execution-sinks.js +496 -0
- package/dist/layer2/ai-execution-sinks.js.map +1 -0
- package/dist/layer2/ai-fingerprinting.d.ts +7 -0
- package/dist/layer2/ai-fingerprinting.d.ts.map +1 -0
- package/dist/layer2/ai-fingerprinting.js +654 -0
- package/dist/layer2/ai-fingerprinting.js.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts +19 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.js +356 -0
- package/dist/layer2/ai-prompt-hygiene.js.map +1 -0
- package/dist/layer2/ai-rag-safety.d.ts +21 -0
- package/dist/layer2/ai-rag-safety.d.ts.map +1 -0
- package/dist/layer2/ai-rag-safety.js +459 -0
- package/dist/layer2/ai-rag-safety.js.map +1 -0
- package/dist/layer2/ai-schema-validation.d.ts +25 -0
- package/dist/layer2/ai-schema-validation.d.ts.map +1 -0
- package/dist/layer2/ai-schema-validation.js +375 -0
- package/dist/layer2/ai-schema-validation.js.map +1 -0
- package/dist/layer2/auth-antipatterns.d.ts +20 -0
- package/dist/layer2/auth-antipatterns.d.ts.map +1 -0
- package/dist/layer2/auth-antipatterns.js +333 -0
- package/dist/layer2/auth-antipatterns.js.map +1 -0
- package/dist/layer2/byok-patterns.d.ts +12 -0
- package/dist/layer2/byok-patterns.d.ts.map +1 -0
- package/dist/layer2/byok-patterns.js +299 -0
- package/dist/layer2/byok-patterns.js.map +1 -0
- package/dist/layer2/dangerous-functions.d.ts +7 -0
- package/dist/layer2/dangerous-functions.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions.js +1375 -0
- package/dist/layer2/dangerous-functions.js.map +1 -0
- package/dist/layer2/data-exposure.d.ts +16 -0
- package/dist/layer2/data-exposure.d.ts.map +1 -0
- package/dist/layer2/data-exposure.js +279 -0
- package/dist/layer2/data-exposure.js.map +1 -0
- package/dist/layer2/framework-checks.d.ts +7 -0
- package/dist/layer2/framework-checks.d.ts.map +1 -0
- package/dist/layer2/framework-checks.js +388 -0
- package/dist/layer2/framework-checks.js.map +1 -0
- package/dist/layer2/index.d.ts +58 -0
- package/dist/layer2/index.d.ts.map +1 -0
- package/dist/layer2/index.js +380 -0
- package/dist/layer2/index.js.map +1 -0
- package/dist/layer2/logic-gates.d.ts +7 -0
- package/dist/layer2/logic-gates.d.ts.map +1 -0
- package/dist/layer2/logic-gates.js +182 -0
- package/dist/layer2/logic-gates.js.map +1 -0
- package/dist/layer2/risky-imports.d.ts +7 -0
- package/dist/layer2/risky-imports.d.ts.map +1 -0
- package/dist/layer2/risky-imports.js +161 -0
- package/dist/layer2/risky-imports.js.map +1 -0
- package/dist/layer2/variables.d.ts +8 -0
- package/dist/layer2/variables.d.ts.map +1 -0
- package/dist/layer2/variables.js +152 -0
- package/dist/layer2/variables.js.map +1 -0
- package/dist/layer3/anthropic.d.ts +83 -0
- package/dist/layer3/anthropic.d.ts.map +1 -0
- package/dist/layer3/anthropic.js +1745 -0
- package/dist/layer3/anthropic.js.map +1 -0
- package/dist/layer3/index.d.ts +24 -0
- package/dist/layer3/index.d.ts.map +1 -0
- package/dist/layer3/index.js +119 -0
- package/dist/layer3/index.js.map +1 -0
- package/dist/layer3/openai.d.ts +25 -0
- package/dist/layer3/openai.d.ts.map +1 -0
- package/dist/layer3/openai.js +238 -0
- package/dist/layer3/openai.js.map +1 -0
- package/dist/layer3/package-check.d.ts +63 -0
- package/dist/layer3/package-check.d.ts.map +1 -0
- package/dist/layer3/package-check.js +508 -0
- package/dist/layer3/package-check.js.map +1 -0
- package/dist/modes/incremental.d.ts +66 -0
- package/dist/modes/incremental.d.ts.map +1 -0
- package/dist/modes/incremental.js +200 -0
- package/dist/modes/incremental.js.map +1 -0
- package/dist/tiers.d.ts +125 -0
- package/dist/tiers.d.ts.map +1 -0
- package/dist/tiers.js +234 -0
- package/dist/tiers.js.map +1 -0
- package/dist/types.d.ts +175 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +50 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/auth-helper-detector.d.ts +56 -0
- package/dist/utils/auth-helper-detector.d.ts.map +1 -0
- package/dist/utils/auth-helper-detector.js +360 -0
- package/dist/utils/auth-helper-detector.js.map +1 -0
- package/dist/utils/context-helpers.d.ts +96 -0
- package/dist/utils/context-helpers.d.ts.map +1 -0
- package/dist/utils/context-helpers.js +493 -0
- package/dist/utils/context-helpers.js.map +1 -0
- package/dist/utils/diff-detector.d.ts +53 -0
- package/dist/utils/diff-detector.d.ts.map +1 -0
- package/dist/utils/diff-detector.js +104 -0
- package/dist/utils/diff-detector.js.map +1 -0
- package/dist/utils/diff-parser.d.ts +80 -0
- package/dist/utils/diff-parser.d.ts.map +1 -0
- package/dist/utils/diff-parser.js +202 -0
- package/dist/utils/diff-parser.js.map +1 -0
- package/dist/utils/imported-auth-detector.d.ts +37 -0
- package/dist/utils/imported-auth-detector.d.ts.map +1 -0
- package/dist/utils/imported-auth-detector.js +251 -0
- package/dist/utils/imported-auth-detector.js.map +1 -0
- package/dist/utils/middleware-detector.d.ts +55 -0
- package/dist/utils/middleware-detector.d.ts.map +1 -0
- package/dist/utils/middleware-detector.js +260 -0
- package/dist/utils/middleware-detector.js.map +1 -0
- package/dist/utils/oauth-flow-detector.d.ts +41 -0
- package/dist/utils/oauth-flow-detector.d.ts.map +1 -0
- package/dist/utils/oauth-flow-detector.js +202 -0
- package/dist/utils/oauth-flow-detector.js.map +1 -0
- package/dist/utils/path-exclusions.d.ts +55 -0
- package/dist/utils/path-exclusions.d.ts.map +1 -0
- package/dist/utils/path-exclusions.js +222 -0
- package/dist/utils/path-exclusions.js.map +1 -0
- package/dist/utils/project-context-builder.d.ts +119 -0
- package/dist/utils/project-context-builder.d.ts.map +1 -0
- package/dist/utils/project-context-builder.js +534 -0
- package/dist/utils/project-context-builder.js.map +1 -0
- package/dist/utils/registry-clients.d.ts +93 -0
- package/dist/utils/registry-clients.d.ts.map +1 -0
- package/dist/utils/registry-clients.js +273 -0
- package/dist/utils/registry-clients.js.map +1 -0
- package/dist/utils/trpc-analyzer.d.ts +78 -0
- package/dist/utils/trpc-analyzer.d.ts.map +1 -0
- package/dist/utils/trpc-analyzer.js +297 -0
- package/dist/utils/trpc-analyzer.js.map +1 -0
- package/package.json +45 -0
- package/src/__tests__/benchmark/fixtures/false-positives.ts +227 -0
- package/src/__tests__/benchmark/fixtures/index.ts +68 -0
- package/src/__tests__/benchmark/fixtures/layer1/config-audit.ts +364 -0
- package/src/__tests__/benchmark/fixtures/layer1/hardcoded-secrets.ts +173 -0
- package/src/__tests__/benchmark/fixtures/layer1/high-entropy.ts +234 -0
- package/src/__tests__/benchmark/fixtures/layer1/index.ts +31 -0
- package/src/__tests__/benchmark/fixtures/layer1/sensitive-urls.ts +90 -0
- package/src/__tests__/benchmark/fixtures/layer1/weak-crypto.ts +197 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-agent-tools.ts +170 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-endpoint-protection.ts +418 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +189 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-fingerprinting.ts +316 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +178 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +184 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-schema-validation.ts +434 -0
- package/src/__tests__/benchmark/fixtures/layer2/auth-antipatterns.ts +159 -0
- package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +112 -0
- package/src/__tests__/benchmark/fixtures/layer2/dangerous-functions.ts +246 -0
- package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +168 -0
- package/src/__tests__/benchmark/fixtures/layer2/framework-checks.ts +346 -0
- package/src/__tests__/benchmark/fixtures/layer2/index.ts +67 -0
- package/src/__tests__/benchmark/fixtures/layer2/injection-vulnerabilities.ts +239 -0
- package/src/__tests__/benchmark/fixtures/layer2/logic-gates.ts +246 -0
- package/src/__tests__/benchmark/fixtures/layer2/risky-imports.ts +231 -0
- package/src/__tests__/benchmark/fixtures/layer2/variables.ts +167 -0
- package/src/__tests__/benchmark/index.ts +29 -0
- package/src/__tests__/benchmark/run-benchmark.ts +144 -0
- package/src/__tests__/benchmark/run-depth-validation.ts +206 -0
- package/src/__tests__/benchmark/run-real-world-test.ts +243 -0
- package/src/__tests__/benchmark/security-benchmark-script.ts +1737 -0
- package/src/__tests__/benchmark/tier-integration-script.ts +177 -0
- package/src/__tests__/benchmark/types.ts +144 -0
- package/src/__tests__/benchmark/utils/test-runner.ts +475 -0
- package/src/__tests__/regression/known-false-positives.test.ts +467 -0
- package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +178 -0
- package/src/__tests__/snapshots/scan-depth.test.ts +258 -0
- package/src/__tests__/validation/analyze-results.ts +542 -0
- package/src/__tests__/validation/extract-for-triage.ts +146 -0
- package/src/__tests__/validation/fp-deep-analysis.ts +327 -0
- package/src/__tests__/validation/run-validation.ts +364 -0
- package/src/__tests__/validation/triage-template.md +132 -0
- package/src/formatters/cli-terminal.ts +446 -0
- package/src/formatters/github-comment.ts +382 -0
- package/src/formatters/grouping.ts +190 -0
- package/src/formatters/index.ts +47 -0
- package/src/formatters/vscode-diagnostic.ts +243 -0
- package/src/index.ts +823 -0
- package/src/layer1/comments.ts +218 -0
- package/src/layer1/config-audit.ts +289 -0
- package/src/layer1/entropy.ts +583 -0
- package/src/layer1/file-flags.ts +127 -0
- package/src/layer1/index.ts +181 -0
- package/src/layer1/patterns.ts +516 -0
- package/src/layer1/urls.ts +334 -0
- package/src/layer1/weak-crypto.ts +328 -0
- package/src/layer2/ai-agent-tools.ts +601 -0
- package/src/layer2/ai-endpoint-protection.ts +387 -0
- package/src/layer2/ai-execution-sinks.ts +580 -0
- package/src/layer2/ai-fingerprinting.ts +758 -0
- package/src/layer2/ai-prompt-hygiene.ts +411 -0
- package/src/layer2/ai-rag-safety.ts +511 -0
- package/src/layer2/ai-schema-validation.ts +421 -0
- package/src/layer2/auth-antipatterns.ts +394 -0
- package/src/layer2/byok-patterns.ts +336 -0
- package/src/layer2/dangerous-functions.ts +1563 -0
- package/src/layer2/data-exposure.ts +315 -0
- package/src/layer2/framework-checks.ts +433 -0
- package/src/layer2/index.ts +473 -0
- package/src/layer2/logic-gates.ts +206 -0
- package/src/layer2/risky-imports.ts +186 -0
- package/src/layer2/variables.ts +166 -0
- package/src/layer3/anthropic.ts +2030 -0
- package/src/layer3/index.ts +130 -0
- package/src/layer3/package-check.ts +604 -0
- package/src/modes/incremental.ts +293 -0
- package/src/tiers.ts +318 -0
- package/src/types.ts +284 -0
- package/src/utils/auth-helper-detector.ts +443 -0
- package/src/utils/context-helpers.ts +535 -0
- package/src/utils/diff-detector.ts +135 -0
- package/src/utils/diff-parser.ts +272 -0
- package/src/utils/imported-auth-detector.ts +320 -0
- package/src/utils/middleware-detector.ts +333 -0
- package/src/utils/oauth-flow-detector.ts +246 -0
- package/src/utils/path-exclusions.ts +266 -0
- package/src/utils/project-context-builder.ts +707 -0
- package/src/utils/registry-clients.ts +351 -0
- package/src/utils/trpc-analyzer.ts +382 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Imported Auth Detector
|
|
4
|
+
*
|
|
5
|
+
* Detects auth middleware/helpers imported from other files to avoid
|
|
6
|
+
* false positives on routes that are actually protected via imports.
|
|
7
|
+
*
|
|
8
|
+
* Example: A route file that does `import { authMiddleware } from '@/lib/auth'`
|
|
9
|
+
* and wraps handlers with it should not be flagged as "missing auth".
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.extractImports = extractImports;
|
|
13
|
+
exports.detectImportedAuthUsage = detectImportedAuthUsage;
|
|
14
|
+
exports.buildFileAuthImports = buildFileAuthImports;
|
|
15
|
+
exports.fileUsesImportedAuth = fileUsesImportedAuth;
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Patterns
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Patterns that indicate auth-related imports by name
|
|
21
|
+
*/
|
|
22
|
+
const AUTH_NAME_PATTERNS = [
|
|
23
|
+
/auth/i,
|
|
24
|
+
/middleware/i,
|
|
25
|
+
/protect/i,
|
|
26
|
+
/guard/i,
|
|
27
|
+
/session/i,
|
|
28
|
+
/verify/i,
|
|
29
|
+
/secure/i,
|
|
30
|
+
/jwt/i,
|
|
31
|
+
/token/i,
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Specific auth import names commonly used
|
|
35
|
+
*/
|
|
36
|
+
const KNOWN_AUTH_IMPORTS = new Set([
|
|
37
|
+
// Next.js / NextAuth
|
|
38
|
+
'auth',
|
|
39
|
+
'getServerSession',
|
|
40
|
+
'getSession',
|
|
41
|
+
'withAuth',
|
|
42
|
+
'getToken',
|
|
43
|
+
'NextAuth',
|
|
44
|
+
'NextAuthOptions',
|
|
45
|
+
// Clerk
|
|
46
|
+
'auth',
|
|
47
|
+
'currentUser',
|
|
48
|
+
'clerkMiddleware',
|
|
49
|
+
'getAuth',
|
|
50
|
+
'SignedIn',
|
|
51
|
+
'SignedOut',
|
|
52
|
+
// Auth0
|
|
53
|
+
'withPageAuthRequired',
|
|
54
|
+
'withApiAuthRequired',
|
|
55
|
+
'getSession',
|
|
56
|
+
'getAccessToken',
|
|
57
|
+
// Custom auth patterns
|
|
58
|
+
'authMiddleware',
|
|
59
|
+
'requireAuth',
|
|
60
|
+
'requireAuthentication',
|
|
61
|
+
'checkAuth',
|
|
62
|
+
'verifyAuth',
|
|
63
|
+
'protectRoute',
|
|
64
|
+
'withAuthentication',
|
|
65
|
+
'authenticated',
|
|
66
|
+
'getCurrentUser',
|
|
67
|
+
'getCurrentUserId',
|
|
68
|
+
'getUser',
|
|
69
|
+
'getUserId',
|
|
70
|
+
]);
|
|
71
|
+
/**
|
|
72
|
+
* Patterns indicating auth-related import paths
|
|
73
|
+
*/
|
|
74
|
+
const AUTH_PATH_PATTERNS = [
|
|
75
|
+
/\/auth\//i,
|
|
76
|
+
/\/middleware/i,
|
|
77
|
+
/\/lib\/auth/i,
|
|
78
|
+
/\/utils\/auth/i,
|
|
79
|
+
/\/helpers\/auth/i,
|
|
80
|
+
/next-auth/i,
|
|
81
|
+
/@clerk/i,
|
|
82
|
+
/@auth0/i,
|
|
83
|
+
/lucia/i,
|
|
84
|
+
];
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// Import Extraction
|
|
87
|
+
// ============================================================================
|
|
88
|
+
/**
|
|
89
|
+
* Extract all imports from a file's content
|
|
90
|
+
*/
|
|
91
|
+
function extractImports(content) {
|
|
92
|
+
const imports = [];
|
|
93
|
+
// ES6 named imports: import { x, y } from 'path'
|
|
94
|
+
const es6NamedPattern = /import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g;
|
|
95
|
+
let match;
|
|
96
|
+
while ((match = es6NamedPattern.exec(content)) !== null) {
|
|
97
|
+
const names = match[1]
|
|
98
|
+
.split(',')
|
|
99
|
+
.map(n => n.trim().split(/\s+as\s+/)[0].trim()) // Handle 'x as y'
|
|
100
|
+
.filter(n => n.length > 0);
|
|
101
|
+
const importPath = match[2];
|
|
102
|
+
const isAuthRelated = isAuthRelatedImport(names, importPath);
|
|
103
|
+
imports.push({
|
|
104
|
+
importPath,
|
|
105
|
+
importedNames: names,
|
|
106
|
+
isAuthRelated,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// ES6 default imports: import x from 'path'
|
|
110
|
+
const defaultPattern = /import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g;
|
|
111
|
+
while ((match = defaultPattern.exec(content)) !== null) {
|
|
112
|
+
const name = match[1];
|
|
113
|
+
const importPath = match[2];
|
|
114
|
+
// Skip if already captured as named import
|
|
115
|
+
if (imports.some(imp => imp.importPath === importPath))
|
|
116
|
+
continue;
|
|
117
|
+
const isAuthRelated = isAuthRelatedImport([name], importPath);
|
|
118
|
+
imports.push({
|
|
119
|
+
importPath,
|
|
120
|
+
importedNames: [name],
|
|
121
|
+
isAuthRelated,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
// CommonJS require: const { x } = require('path')
|
|
125
|
+
const requireDestructurePattern = /(?:const|let|var)\s+\{([^}]+)\}\s*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
126
|
+
while ((match = requireDestructurePattern.exec(content)) !== null) {
|
|
127
|
+
const names = match[1]
|
|
128
|
+
.split(',')
|
|
129
|
+
.map(n => n.trim().split(/\s*:\s*/)[0].trim()) // Handle 'x: y' renaming
|
|
130
|
+
.filter(n => n.length > 0);
|
|
131
|
+
const importPath = match[2];
|
|
132
|
+
const isAuthRelated = isAuthRelatedImport(names, importPath);
|
|
133
|
+
imports.push({
|
|
134
|
+
importPath,
|
|
135
|
+
importedNames: names,
|
|
136
|
+
isAuthRelated,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
// CommonJS require: const x = require('path')
|
|
140
|
+
const requireDefaultPattern = /(?:const|let|var)\s+(\w+)\s*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
141
|
+
while ((match = requireDefaultPattern.exec(content)) !== null) {
|
|
142
|
+
const name = match[1];
|
|
143
|
+
const importPath = match[2];
|
|
144
|
+
// Skip if already captured
|
|
145
|
+
if (imports.some(imp => imp.importPath === importPath))
|
|
146
|
+
continue;
|
|
147
|
+
const isAuthRelated = isAuthRelatedImport([name], importPath);
|
|
148
|
+
imports.push({
|
|
149
|
+
importPath,
|
|
150
|
+
importedNames: [name],
|
|
151
|
+
isAuthRelated,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return imports;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check if an import is auth-related based on names and path
|
|
158
|
+
*/
|
|
159
|
+
function isAuthRelatedImport(names, importPath) {
|
|
160
|
+
// Check if path is auth-related
|
|
161
|
+
if (AUTH_PATH_PATTERNS.some(p => p.test(importPath))) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
// Check if any imported name is auth-related
|
|
165
|
+
for (const name of names) {
|
|
166
|
+
// Known auth imports
|
|
167
|
+
if (KNOWN_AUTH_IMPORTS.has(name)) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
// Pattern-based detection
|
|
171
|
+
if (AUTH_NAME_PATTERNS.some(p => p.test(name))) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
// ============================================================================
|
|
178
|
+
// Auth Usage Detection
|
|
179
|
+
// ============================================================================
|
|
180
|
+
/**
|
|
181
|
+
* Check if imported auth is actually used to protect routes/handlers
|
|
182
|
+
*/
|
|
183
|
+
function detectImportedAuthUsage(content, authImports) {
|
|
184
|
+
if (authImports.length === 0)
|
|
185
|
+
return false;
|
|
186
|
+
const authNames = authImports.flatMap(imp => imp.importedNames);
|
|
187
|
+
for (const name of authNames) {
|
|
188
|
+
// Pattern 1: Handler wrapping - export const GET = authMiddleware(...)
|
|
189
|
+
const wrapperPattern = new RegExp(`(?:export\\s+(?:const|function)\\s+(?:GET|POST|PUT|PATCH|DELETE|handler)\\s*=\\s*${escapeRegex(name)}\\s*\\()` +
|
|
190
|
+
`|(?:${escapeRegex(name)}\\s*\\(\\s*(?:async\\s+)?(?:function|\\())`);
|
|
191
|
+
if (wrapperPattern.test(content)) {
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
// Pattern 2: Middleware chain - app.use(authMiddleware)
|
|
195
|
+
const middlewareChainPattern = new RegExp(`\\.(?:use|all|get|post|put|patch|delete)\\s*\\([^)]*${escapeRegex(name)}`);
|
|
196
|
+
if (middlewareChainPattern.test(content)) {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
// Pattern 3: Express/Fastify route with middleware - router.get('/', requireAuth, handler)
|
|
200
|
+
const routeMiddlewarePattern = new RegExp(`\\.(?:get|post|put|patch|delete)\\s*\\([^,]+,\\s*${escapeRegex(name)}`);
|
|
201
|
+
if (routeMiddlewarePattern.test(content)) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
// Pattern 4: HOC pattern - withAuth(Component)
|
|
205
|
+
const hocPattern = new RegExp(`${escapeRegex(name)}\\s*\\(\\s*\\w+\\s*\\)`);
|
|
206
|
+
if (hocPattern.test(content)) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
// Pattern 5: Auth function call at top of handler - const session = await auth()
|
|
210
|
+
const authCallPattern = new RegExp(`(?:await\\s+)?${escapeRegex(name)}\\s*\\(\\s*\\)` +
|
|
211
|
+
`|${escapeRegex(name)}\\s*\\(\\s*(?:req|request|ctx|context)\\s*[,)]`);
|
|
212
|
+
if (authCallPattern.test(content)) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Escape special regex characters in a string
|
|
220
|
+
*/
|
|
221
|
+
function escapeRegex(str) {
|
|
222
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
223
|
+
}
|
|
224
|
+
// ============================================================================
|
|
225
|
+
// Registry Builder
|
|
226
|
+
// ============================================================================
|
|
227
|
+
/**
|
|
228
|
+
* Build a registry of files and their auth imports
|
|
229
|
+
*/
|
|
230
|
+
function buildFileAuthImports(files) {
|
|
231
|
+
const registry = new Map();
|
|
232
|
+
for (const file of files) {
|
|
233
|
+
const allImports = extractImports(file.content);
|
|
234
|
+
const authImports = allImports.filter(imp => imp.isAuthRelated);
|
|
235
|
+
const usesImportedAuth = authImports.length > 0 &&
|
|
236
|
+
detectImportedAuthUsage(file.content, authImports);
|
|
237
|
+
registry.set(file.path, {
|
|
238
|
+
filePath: file.path,
|
|
239
|
+
imports: authImports,
|
|
240
|
+
usesImportedAuth,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
return registry;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Check if a specific file uses imported auth protection
|
|
247
|
+
*/
|
|
248
|
+
function fileUsesImportedAuth(filePath, registry) {
|
|
249
|
+
return registry.get(filePath)?.usesImportedAuth ?? false;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=imported-auth-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imported-auth-detector.js","sourceRoot":"","sources":["../../src/utils/imported-auth-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Auth Detection
|
|
3
|
+
* Detects global authentication middleware (Next.js, Express, etc.)
|
|
4
|
+
* and determines which routes are protected
|
|
5
|
+
*/
|
|
6
|
+
import type { ScanFile } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Configuration describing detected auth middleware
|
|
9
|
+
*/
|
|
10
|
+
export interface MiddlewareAuthConfig {
|
|
11
|
+
/** Whether auth middleware was detected */
|
|
12
|
+
hasAuthMiddleware: boolean;
|
|
13
|
+
/** The type of auth detected */
|
|
14
|
+
authType?: 'clerk' | 'nextauth' | 'auth0' | 'custom' | 'unknown';
|
|
15
|
+
/** File path where middleware was found */
|
|
16
|
+
middlewareFile?: string;
|
|
17
|
+
/** Protected path patterns (glob-like) */
|
|
18
|
+
protectedPaths: string[];
|
|
19
|
+
/** Public/excluded path patterns */
|
|
20
|
+
publicPaths: string[];
|
|
21
|
+
/** Raw matcher patterns found */
|
|
22
|
+
matchers: string[];
|
|
23
|
+
/** Additional context about the auth setup */
|
|
24
|
+
context: {
|
|
25
|
+
usesAuthProtect: boolean;
|
|
26
|
+
usesGetToken: boolean;
|
|
27
|
+
usesSession: boolean;
|
|
28
|
+
hasPublicRoutes: boolean;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Detect global auth middleware from scanned files
|
|
33
|
+
* Looks for Next.js middleware.ts, Express auth patterns, etc.
|
|
34
|
+
*/
|
|
35
|
+
export declare function detectGlobalAuthMiddleware(files: ScanFile[]): MiddlewareAuthConfig;
|
|
36
|
+
/**
|
|
37
|
+
* Check if a given route path is protected by the middleware
|
|
38
|
+
*/
|
|
39
|
+
export declare function isRouteProtectedByMiddleware(routePath: string, config: MiddlewareAuthConfig): {
|
|
40
|
+
isProtected: boolean;
|
|
41
|
+
reason: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Extract route path from a file path (e.g., app/api/users/route.ts -> /api/users)
|
|
45
|
+
*/
|
|
46
|
+
export declare function getRoutePathFromFile(filePath: string): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Get user-scoping patterns from file content
|
|
49
|
+
* Detects patterns like: user_id, userId, session.user.id
|
|
50
|
+
*/
|
|
51
|
+
export declare function detectUserScopingPatterns(content: string): {
|
|
52
|
+
hasUserScoping: boolean;
|
|
53
|
+
patterns: string[];
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=middleware-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-detector.d.ts","sourceRoot":"","sources":["../../src/utils/middleware-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAA;IAChE,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0CAA0C;IAC1C,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,oCAAoC;IACpC,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,8CAA8C;IAC9C,OAAO,EAAE;QACP,eAAe,EAAE,OAAO,CAAA;QACxB,YAAY,EAAE,OAAO,CAAA;QACrB,WAAW,EAAE,OAAO,CAAA;QACpB,eAAe,EAAE,OAAO,CAAA;KACzB,CAAA;CACF;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAwDlF;AA0GD;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,oBAAoB,GAC3B;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA6C1C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBpE;AA2BD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG;IAC1D,cAAc,EAAE,OAAO,CAAA;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB,CA2BA"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Middleware Auth Detection
|
|
4
|
+
* Detects global authentication middleware (Next.js, Express, etc.)
|
|
5
|
+
* and determines which routes are protected
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.detectGlobalAuthMiddleware = detectGlobalAuthMiddleware;
|
|
9
|
+
exports.isRouteProtectedByMiddleware = isRouteProtectedByMiddleware;
|
|
10
|
+
exports.getRoutePathFromFile = getRoutePathFromFile;
|
|
11
|
+
exports.detectUserScopingPatterns = detectUserScopingPatterns;
|
|
12
|
+
/**
|
|
13
|
+
* Detect global auth middleware from scanned files
|
|
14
|
+
* Looks for Next.js middleware.ts, Express auth patterns, etc.
|
|
15
|
+
*/
|
|
16
|
+
function detectGlobalAuthMiddleware(files) {
|
|
17
|
+
const result = {
|
|
18
|
+
hasAuthMiddleware: false,
|
|
19
|
+
protectedPaths: [],
|
|
20
|
+
publicPaths: [],
|
|
21
|
+
matchers: [],
|
|
22
|
+
context: {
|
|
23
|
+
usesAuthProtect: false,
|
|
24
|
+
usesGetToken: false,
|
|
25
|
+
usesSession: false,
|
|
26
|
+
hasPublicRoutes: false,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
// Find middleware files
|
|
30
|
+
const middlewareFile = files.find(f => /^(src\/)?middleware\.(ts|js)$/.test(f.path) ||
|
|
31
|
+
f.path.endsWith('/middleware.ts') ||
|
|
32
|
+
f.path.endsWith('/middleware.js'));
|
|
33
|
+
if (!middlewareFile) {
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
result.middlewareFile = middlewareFile.path;
|
|
37
|
+
const content = middlewareFile.content;
|
|
38
|
+
// Detect auth provider type
|
|
39
|
+
result.authType = detectAuthType(content);
|
|
40
|
+
if (result.authType) {
|
|
41
|
+
result.hasAuthMiddleware = true;
|
|
42
|
+
}
|
|
43
|
+
// Extract protected path matchers
|
|
44
|
+
const { protectedPaths, publicPaths, matchers } = extractPathMatchers(content);
|
|
45
|
+
result.protectedPaths = protectedPaths;
|
|
46
|
+
result.publicPaths = publicPaths;
|
|
47
|
+
result.matchers = matchers;
|
|
48
|
+
// Detect specific auth patterns
|
|
49
|
+
result.context.usesAuthProtect = /auth\.protect\(\)|auth\(\)\.protect\(\)|requireAuth\(\)/i.test(content);
|
|
50
|
+
result.context.usesGetToken = /getToken\(|getAuth\(/i.test(content);
|
|
51
|
+
result.context.usesSession = /getSession\(|getServerSession\(/i.test(content);
|
|
52
|
+
result.context.hasPublicRoutes = /isPublicRoute|publicRoutes|ignoredRoutes|excludedPaths/i.test(content);
|
|
53
|
+
// If we found auth imports but no explicit matchers, assume /api/** is protected
|
|
54
|
+
if (result.hasAuthMiddleware && result.protectedPaths.length === 0) {
|
|
55
|
+
// Check if middleware runs on all routes or has default API protection
|
|
56
|
+
if (!result.context.hasPublicRoutes || /\/api/i.test(content)) {
|
|
57
|
+
result.protectedPaths.push('/api/**');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Detect which auth provider/library is being used
|
|
64
|
+
*/
|
|
65
|
+
function detectAuthType(content) {
|
|
66
|
+
// Clerk patterns
|
|
67
|
+
if (/clerkMiddleware|@clerk\/nextjs|clerkClient|auth\(\)\.protect/i.test(content)) {
|
|
68
|
+
return 'clerk';
|
|
69
|
+
}
|
|
70
|
+
// NextAuth patterns
|
|
71
|
+
if (/next-auth|NextAuth|getServerSession|withAuth\(/i.test(content)) {
|
|
72
|
+
return 'nextauth';
|
|
73
|
+
}
|
|
74
|
+
// Auth0 patterns
|
|
75
|
+
if (/@auth0\/nextjs|withPageAuthRequired|withApiAuthRequired/i.test(content)) {
|
|
76
|
+
return 'auth0';
|
|
77
|
+
}
|
|
78
|
+
// Generic auth middleware patterns
|
|
79
|
+
if (/authMiddleware|requireAuth|verifyToken|checkAuth|isAuthenticated/i.test(content)) {
|
|
80
|
+
return 'custom';
|
|
81
|
+
}
|
|
82
|
+
// Check for common auth imports/usage that suggest middleware is doing auth
|
|
83
|
+
if (/authorization|bearer|jwt|session\.user|getToken/i.test(content)) {
|
|
84
|
+
return 'unknown';
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Extract path matchers from middleware config
|
|
90
|
+
*/
|
|
91
|
+
function extractPathMatchers(content) {
|
|
92
|
+
const protectedPaths = [];
|
|
93
|
+
const publicPaths = [];
|
|
94
|
+
const matchers = [];
|
|
95
|
+
// Next.js config.matcher pattern
|
|
96
|
+
// export const config = { matcher: [...] }
|
|
97
|
+
const matcherArrayMatch = content.match(/config\s*=\s*\{[^}]*matcher\s*:\s*\[([\s\S]*?)\]/m);
|
|
98
|
+
if (matcherArrayMatch) {
|
|
99
|
+
const matcherContent = matcherArrayMatch[1];
|
|
100
|
+
// Extract string patterns from the array
|
|
101
|
+
const patterns = matcherContent.match(/['"`]([^'"`]+)['"`]/g) || [];
|
|
102
|
+
for (const p of patterns) {
|
|
103
|
+
const path = p.replace(/['"`]/g, '');
|
|
104
|
+
matchers.push(path);
|
|
105
|
+
// Classify as protected or public based on common patterns
|
|
106
|
+
if (path.includes('/api') || path.includes('/(protected)') || path.includes('/dashboard')) {
|
|
107
|
+
protectedPaths.push(path);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Single matcher pattern
|
|
112
|
+
// export const config = { matcher: '/api/:path*' }
|
|
113
|
+
const singleMatcherMatch = content.match(/config\s*=\s*\{[^}]*matcher\s*:\s*['"`]([^'"`]+)['"`]/m);
|
|
114
|
+
if (singleMatcherMatch) {
|
|
115
|
+
const path = singleMatcherMatch[1];
|
|
116
|
+
matchers.push(path);
|
|
117
|
+
if (path.includes('/api')) {
|
|
118
|
+
protectedPaths.push(path);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Clerk-specific: createRouteMatcher for public routes
|
|
122
|
+
// const isPublicRoute = createRouteMatcher(['/sign-in', '/sign-up', ...])
|
|
123
|
+
const publicRouteMatch = content.match(/createRouteMatcher\s*\(\s*\[([\s\S]*?)\]/m);
|
|
124
|
+
if (publicRouteMatch) {
|
|
125
|
+
const routeContent = publicRouteMatch[1];
|
|
126
|
+
const patterns = routeContent.match(/['"`]([^'"`]+)['"`]/g) || [];
|
|
127
|
+
for (const p of patterns) {
|
|
128
|
+
const path = p.replace(/['"`]/g, '');
|
|
129
|
+
publicPaths.push(path);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Look for publicRoutes/ignoredRoutes arrays
|
|
133
|
+
const publicRoutesMatch = content.match(/(publicRoutes|ignoredRoutes|excludedPaths)\s*[=:]\s*\[([\s\S]*?)\]/m);
|
|
134
|
+
if (publicRoutesMatch) {
|
|
135
|
+
const routeContent = publicRoutesMatch[2];
|
|
136
|
+
const patterns = routeContent.match(/['"`]([^'"`]+)['"`]/g) || [];
|
|
137
|
+
for (const p of patterns) {
|
|
138
|
+
const path = p.replace(/['"`]/g, '');
|
|
139
|
+
publicPaths.push(path);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// If we found public paths but no explicit protected paths,
|
|
143
|
+
// assume everything else under /api is protected
|
|
144
|
+
if (publicPaths.length > 0 && protectedPaths.length === 0) {
|
|
145
|
+
protectedPaths.push('/api/**');
|
|
146
|
+
}
|
|
147
|
+
return { protectedPaths, publicPaths, matchers };
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Check if a given route path is protected by the middleware
|
|
151
|
+
*/
|
|
152
|
+
function isRouteProtectedByMiddleware(routePath, config) {
|
|
153
|
+
if (!config.hasAuthMiddleware) {
|
|
154
|
+
return { isProtected: false, reason: 'No auth middleware detected' };
|
|
155
|
+
}
|
|
156
|
+
// Normalize path
|
|
157
|
+
const normalizedPath = routePath.startsWith('/') ? routePath : `/${routePath}`;
|
|
158
|
+
// Check if explicitly public
|
|
159
|
+
for (const publicPath of config.publicPaths) {
|
|
160
|
+
if (matchPath(normalizedPath, publicPath)) {
|
|
161
|
+
return { isProtected: false, reason: `Matches public route pattern: ${publicPath}` };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Check if explicitly protected
|
|
165
|
+
for (const protectedPath of config.protectedPaths) {
|
|
166
|
+
if (matchPath(normalizedPath, protectedPath)) {
|
|
167
|
+
return {
|
|
168
|
+
isProtected: true,
|
|
169
|
+
reason: `Protected by ${config.authType || 'auth'} middleware (matches: ${protectedPath})`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Check matchers
|
|
174
|
+
for (const matcher of config.matchers) {
|
|
175
|
+
if (matchPath(normalizedPath, matcher)) {
|
|
176
|
+
return {
|
|
177
|
+
isProtected: true,
|
|
178
|
+
reason: `Protected by middleware matcher: ${matcher}`,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Default: if we have auth middleware and no explicit public match,
|
|
183
|
+
// consider API routes as protected
|
|
184
|
+
if (normalizedPath.startsWith('/api/')) {
|
|
185
|
+
return {
|
|
186
|
+
isProtected: true,
|
|
187
|
+
reason: `API route likely protected by ${config.authType || 'auth'} middleware`,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return { isProtected: false, reason: 'Route not covered by middleware matchers' };
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Extract route path from a file path (e.g., app/api/users/route.ts -> /api/users)
|
|
194
|
+
*/
|
|
195
|
+
function getRoutePathFromFile(filePath) {
|
|
196
|
+
// Next.js App Router: app/api/users/route.ts -> /api/users
|
|
197
|
+
const appRouterMatch = filePath.match(/app(\/.*?)\/route\.(ts|js)$/i);
|
|
198
|
+
if (appRouterMatch) {
|
|
199
|
+
return appRouterMatch[1];
|
|
200
|
+
}
|
|
201
|
+
// Next.js Pages Router: pages/api/users.ts -> /api/users
|
|
202
|
+
const pagesRouterMatch = filePath.match(/pages(\/api\/.*?)\.(ts|js)$/i);
|
|
203
|
+
if (pagesRouterMatch) {
|
|
204
|
+
return pagesRouterMatch[1];
|
|
205
|
+
}
|
|
206
|
+
// Express-style routes: routes/users.ts (harder to determine path)
|
|
207
|
+
// Return null for now - would need more context
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Simple glob-like path matching
|
|
212
|
+
* Supports: ** (any path), * (single segment), :param (path params)
|
|
213
|
+
*/
|
|
214
|
+
function matchPath(actualPath, pattern) {
|
|
215
|
+
// Normalize
|
|
216
|
+
const normActual = actualPath.replace(/\/+/g, '/');
|
|
217
|
+
let normPattern = pattern.replace(/\/+/g, '/');
|
|
218
|
+
// Handle Next.js :path* patterns
|
|
219
|
+
normPattern = normPattern
|
|
220
|
+
.replace(/:path\*/g, '**')
|
|
221
|
+
.replace(/:\w+/g, '[^/]+');
|
|
222
|
+
// Convert glob to regex
|
|
223
|
+
const regexPattern = normPattern
|
|
224
|
+
.replace(/\*\*/g, '<<<DOUBLESTAR>>>')
|
|
225
|
+
.replace(/\*/g, '[^/]*')
|
|
226
|
+
.replace(/<<<DOUBLESTAR>>>/g, '.*')
|
|
227
|
+
.replace(/\//g, '\\/');
|
|
228
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
229
|
+
return regex.test(normActual);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Get user-scoping patterns from file content
|
|
233
|
+
* Detects patterns like: user_id, userId, session.user.id
|
|
234
|
+
*/
|
|
235
|
+
function detectUserScopingPatterns(content) {
|
|
236
|
+
const patterns = [];
|
|
237
|
+
// Common user ID patterns in queries/operations
|
|
238
|
+
const userIdPatterns = [
|
|
239
|
+
/\.eq\s*\(\s*['"`]user_id['"`]/i, // Supabase .eq('user_id', ...)
|
|
240
|
+
/\.filter\s*\(\s*user_id\s*=/i, // Django-style
|
|
241
|
+
/where\s*\(\s*['"`]?user_id['"`]?\s*=/i, // SQL-like
|
|
242
|
+
/userId\s*[=:]/i, // Generic userId
|
|
243
|
+
/user\.id\s*[=:]/i, // user.id
|
|
244
|
+
/session\.user\.id/i, // Next.js session
|
|
245
|
+
/req\.user\.id/i, // Express req.user
|
|
246
|
+
/getCurrentUserId\s*\(/i, // Custom helper
|
|
247
|
+
/getAuthUser\s*\(/i, // Auth helper
|
|
248
|
+
/auth\(\).*\.userId/i, // Clerk auth().userId
|
|
249
|
+
];
|
|
250
|
+
for (const pattern of userIdPatterns) {
|
|
251
|
+
if (pattern.test(content)) {
|
|
252
|
+
patterns.push(pattern.source);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
hasUserScoping: patterns.length > 0,
|
|
257
|
+
patterns,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=middleware-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-detector.js","sourceRoot":"","sources":["../../src/utils/middleware-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Flow Detector
|
|
3
|
+
* Detects OAuth state generation and validation across multiple files
|
|
4
|
+
* to prevent false positives when state is implemented correctly but split across files.
|
|
5
|
+
*/
|
|
6
|
+
import type { ScanFile } from '../types';
|
|
7
|
+
export interface OAuthFlowContext {
|
|
8
|
+
/** Whether state generation is detected in any file */
|
|
9
|
+
hasStateGeneration: boolean;
|
|
10
|
+
/** File where state is generated */
|
|
11
|
+
stateGenerationFile?: string;
|
|
12
|
+
/** Line number where state is generated */
|
|
13
|
+
stateGenerationLine?: number;
|
|
14
|
+
/** Whether state validation is detected in any file */
|
|
15
|
+
hasStateValidation: boolean;
|
|
16
|
+
/** File where state is validated */
|
|
17
|
+
stateValidationFile?: string;
|
|
18
|
+
/** Line number where state is validated */
|
|
19
|
+
stateValidationLine?: number;
|
|
20
|
+
/** Whether PKCE code_verifier is used */
|
|
21
|
+
hasCodeVerifier: boolean;
|
|
22
|
+
/** File where code_verifier is generated */
|
|
23
|
+
codeVerifierFile?: string;
|
|
24
|
+
/** Detected OAuth flow type */
|
|
25
|
+
flowType: 'authorization_code' | 'client_credentials' | 'implicit' | 'pkce' | 'unknown';
|
|
26
|
+
/** OAuth providers detected */
|
|
27
|
+
providers: string[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Detect OAuth flow patterns across multiple files
|
|
31
|
+
*/
|
|
32
|
+
export declare function detectOAuthFlow(files: ScanFile[]): OAuthFlowContext;
|
|
33
|
+
/**
|
|
34
|
+
* Check if OAuth state is properly implemented across files
|
|
35
|
+
*/
|
|
36
|
+
export declare function isOAuthStateImplemented(context: OAuthFlowContext): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Get a summary of the OAuth flow for logging/context
|
|
39
|
+
*/
|
|
40
|
+
export declare function getOAuthFlowSummary(context: OAuthFlowContext): string;
|
|
41
|
+
//# sourceMappingURL=oauth-flow-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-flow-detector.d.ts","sourceRoot":"","sources":["../../src/utils/oauth-flow-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,kBAAkB,EAAE,OAAO,CAAA;IAC3B,oCAAoC;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,uDAAuD;IACvD,kBAAkB,EAAE,OAAO,CAAA;IAC3B,oCAAoC;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,yCAAyC;IACzC,eAAe,EAAE,OAAO,CAAA;IACxB,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,+BAA+B;IAC/B,QAAQ,EAAE,oBAAoB,GAAG,oBAAoB,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAA;IACvF,+BAA+B;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAoFD;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,gBAAgB,CA4EnE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAa1E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CA8BrE"}
|