verification-layer 0.27.7 → 0.27.9

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "verification-layer",
3
- "version": "0.27.7",
3
+ "version": "0.27.9",
4
4
  "total": 143,
5
5
  "counts": {
6
6
  "phi-exposure": 29,
@@ -663,7 +663,7 @@
663
663
  "severity": "critical",
664
664
  "title": "Authentication Configuration Without MFA Enabled",
665
665
  "description": "Auth provider configuration (NextAuth, Clerk, Auth0, Supabase) does not have MFA/2FA/TOTP enabled",
666
- "recommendation": "Enable MFA in your auth provider configuration. For NextAuth: add adapter with MFA support. For Clerk: enable MFA in dashboard. For Auth0: enable MFA in tenant settings. For Supabase: enable MFA in auth settings.",
666
+ "recommendation": "Enable MFA in your auth provider configuration. For NextAuth: add adapter with MFA support. For Clerk: enable MFA in dashboard. For Auth0: enable MFA in tenant settings. For Supabase, verify MFA policy at the project/provider configuration level rather than inferring it from runtime auth calls.",
667
667
  "hipaaReference": "NPRM §164.312(d) - Person or Entity Authentication",
668
668
  "source": "pattern",
669
669
  "scanner": "authentication"
@@ -67,13 +67,26 @@ export const authenticationScanner = {
67
67
  * Scan auth configuration files for missing MFA
68
68
  */
69
69
  async function scanAuthConfig(file, content, lines, pattern, findings) {
70
+ // A Supabase SDK client is used for database/storage/admin operations as well
71
+ // as authentication, so createClient() alone is not auth configuration evidence.
72
+ // Preserve the existing auth-config heuristic only when the file itself is
73
+ // auth-oriented or actually invokes a Supabase auth API. This prevents service-
74
+ // role clients in webhooks/background jobs from being mislabeled as missing MFA.
75
+ const hasDirectSupabaseSdkImport = /(?:from\s+['"]@supabase\/supabase-js['"]|require\(\s*['"]@supabase\/supabase-js['"]\s*\))/i.test(content);
76
+ const hasDirectClientConstruction = lines.some((line) => !isImportLine(line) && /createClient\s*\(/i.test(line));
77
+ const hasSupabaseAuthUsage = /\bsupabase\w*\.auth\./i.test(content);
78
+ const hasAuthOrSupabaseConfigFilename = /(?:^|[\\/])(?:auth|supabase(?:-config)?)(?:[.\\/_-]|$)/i.test(file);
79
+ const supabaseClientConfig = hasDirectSupabaseSdkImport &&
80
+ hasDirectClientConstruction &&
81
+ (hasSupabaseAuthUsage || hasAuthOrSupabaseConfigFilename);
70
82
  // Check if this is an auth-related file
71
83
  const isAuthFile = /(?:auth|clerk|supabase|next-auth)/i.test(file) ||
72
- pattern.patterns.some((p) => p.test(content));
84
+ pattern.patterns.some((p) => p.test(content)) ||
85
+ supabaseClientConfig;
73
86
  if (!isAuthFile)
74
87
  return;
75
88
  // Check if file has any auth provider configuration
76
- const hasAuthConfig = pattern.patterns.some((p) => p.test(content));
89
+ const hasAuthConfig = pattern.patterns.some((p) => p.test(content)) || supabaseClientConfig;
77
90
  if (!hasAuthConfig)
78
91
  return;
79
92
  // Check if MFA is configured
@@ -81,9 +94,7 @@ async function scanAuthConfig(file, content, lines, pattern, findings) {
81
94
  if (hasMfaConfig)
82
95
  return;
83
96
  // Find the line with auth configuration. Skip import/require lines — anchoring
84
- // an "auth config without MFA" finding to an `import { createClient } from
85
- // '@supabase/...'` line is a false-positive-looking trigger. If the only
86
- // evidence is an import, don't fire at all.
97
+ // an "auth config without MFA" finding to an import line is misleading.
87
98
  let configLine = 0;
88
99
  for (let i = 0; i < lines.length; i++) {
89
100
  if (isImportLine(lines[i]))
@@ -93,6 +104,15 @@ async function scanAuthConfig(file, content, lines, pattern, findings) {
93
104
  break;
94
105
  }
95
106
  }
107
+ // For direct Supabase auth config, anchor the finding to the client constructor.
108
+ if (configLine === 0 && supabaseClientConfig) {
109
+ for (let i = 0; i < lines.length; i++) {
110
+ if (/createClient\s*\(/i.test(lines[i]) && !isImportLine(lines[i])) {
111
+ configLine = i + 1;
112
+ break;
113
+ }
114
+ }
115
+ }
96
116
  if (configLine === 0)
97
117
  return;
98
118
  // Create finding for auth config without MFA
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scanners/authentication/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scanners/authentication/index.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,11 @@ export interface MFAPattern {
15
15
  }
16
16
  /**
17
17
  * MFA-001: Auth Provider Configuration Without MFA
18
- * Detects NextAuth, Clerk, Auth0, Supabase Auth configs without MFA enabled
18
+ * Detects code-local auth provider configuration without MFA enabled.
19
+ *
20
+ * Supabase runtime calls such as `supabase.auth.signUp()` are intentionally
21
+ * excluded. Supabase configuration is handled in the scanner with stronger
22
+ * evidence: a direct client construction that contains a Supabase project URL.
19
23
  */
20
24
  export declare const AUTH_CONFIG_NO_MFA: MFAPattern;
21
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../../src/scanners/authentication/patterns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,UA6ChC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,UAmCpC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,UA2CxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,UAAU,EAIxC,CAAC"}
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../../src/scanners/authentication/patterns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,UAyChC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,UAmCpC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,UA2CxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,UAAU,EAIxC,CAAC"}
@@ -4,7 +4,11 @@
4
4
  */
5
5
  /**
6
6
  * MFA-001: Auth Provider Configuration Without MFA
7
- * Detects NextAuth, Clerk, Auth0, Supabase Auth configs without MFA enabled
7
+ * Detects code-local auth provider configuration without MFA enabled.
8
+ *
9
+ * Supabase runtime calls such as `supabase.auth.signUp()` are intentionally
10
+ * excluded. Supabase configuration is handled in the scanner with stronger
11
+ * evidence: a direct client construction that contains a Supabase project URL.
8
12
  */
9
13
  export const AUTH_CONFIG_NO_MFA = {
10
14
  id: 'MFA-001',
@@ -24,9 +28,6 @@ export const AUTH_CONFIG_NO_MFA = {
24
28
  /Auth0Provider/i,
25
29
  /auth0\.WebAuth/i,
26
30
  /new\s+Auth0Client/i,
27
- // Supabase Auth configuration
28
- /supabase\.auth\.signUp/i,
29
- /createClient.*?supabase/i,
30
31
  // Generic auth configs
31
32
  /authConfig\s*[:=]/i,
32
33
  /authentication\s*:\s*\{/i,
@@ -43,7 +44,7 @@ export const AUTH_CONFIG_NO_MFA = {
43
44
  /two[-_]factor/i,
44
45
  /authenticator/i,
45
46
  ],
46
- recommendation: 'Enable MFA in your auth provider configuration. For NextAuth: add adapter with MFA support. For Clerk: enable MFA in dashboard. For Auth0: enable MFA in tenant settings. For Supabase: enable MFA in auth settings.',
47
+ recommendation: 'Enable MFA in your auth provider configuration. For NextAuth: add adapter with MFA support. For Clerk: enable MFA in dashboard. For Auth0: enable MFA in tenant settings. For Supabase, verify MFA policy at the project/provider configuration level rather than inferring it from runtime auth calls.',
47
48
  category: 'authentication',
48
49
  };
49
50
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../src/scanners/authentication/patterns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAe;IAC5C,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,kDAAkD;IACxD,WAAW,EACT,mGAAmG;IACrG,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,oDAAoD;IACpE,QAAQ,EAAE;QACR,yBAAyB;QACzB,gBAAgB;QAChB,mCAAmC;QACnC,qBAAqB;QAErB,sBAAsB;QACtB,gBAAgB;QAChB,6BAA6B;QAE7B,sBAAsB;QACtB,gBAAgB;QAChB,iBAAiB;QACjB,oBAAoB;QAEpB,8BAA8B;QAC9B,yBAAyB;QACzB,0BAA0B;QAE1B,uBAAuB;QACvB,oBAAoB;QACpB,0BAA0B;KAC3B;IACD,gBAAgB,EAAE;QAChB,iCAAiC;QACjC,MAAM;QACN,MAAM;QACN,OAAO;QACP,MAAM;QACN,cAAc;QACd,kBAAkB;QAClB,YAAY;QACZ,gBAAgB;QAChB,gBAAgB;KACjB;IACD,cAAc,EACZ,sNAAsN;IACxN,QAAQ,EAAE,gBAAgB;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAe;IAChD,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,iDAAiD;IACvD,WAAW,EACT,4GAA4G;IAC9G,QAAQ,EAAE,MAAM;IAChB,cAAc,EAAE,oDAAoD;IACpE,QAAQ,EAAE;QACR,6BAA6B;QAC7B,yEAAyE;QACzE,qFAAqF;QAErF,qCAAqC;QACrC,kEAAkE;QAElE,iCAAiC;QACjC,yCAAyC;QACzC,yCAAyC;KAC1C;IACD,gBAAgB,EAAE;QAChB,iCAAiC;QACjC,WAAW;QACX,WAAW;QACX,mBAAmB;QACnB,gBAAgB;QAChB,oBAAoB;QACpB,MAAM;QACN,cAAc;QACd,aAAa;QACb,WAAW;QACX,YAAY;KACb;IACD,cAAc,EACZ,yNAAyN;IAC3N,QAAQ,EAAE,gBAAgB;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAe;IACpC,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,6BAA6B;IACnC,WAAW,EACT,+DAA+D;IACjE,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,oDAAoD;IACpE,QAAQ,EAAE;QACR,4BAA4B;QAC5B,UAAU;QACV,YAAY;QACZ,aAAa;QACb,YAAY;QAEZ,yBAAyB;QACzB,4BAA4B;QAC5B,4BAA4B;QAC5B,wCAAwC;QACxC,qCAAqC;QACrC,wBAAwB;QAExB,qBAAqB;QACrB,wBAAwB;QACxB,kCAAkC;QAElC,iDAAiD;QACjD,6CAA6C;KAC9C;IACD,gBAAgB,EAAE;QAChB,4CAA4C;QAC5C,aAAa;QACb,aAAa;QACb,aAAa;QACb,OAAO;QACP,SAAS;QACT,WAAW;QACX,WAAW;QACX,8BAA8B;QAC9B,eAAe;KAChB;IACD,cAAc,EACZ,2KAA2K;IAC7K,QAAQ,EAAE,gBAAgB;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,kBAAkB;IAClB,sBAAsB;IACtB,UAAU;CACX,CAAC"}
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../src/scanners/authentication/patterns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAe;IAC5C,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,kDAAkD;IACxD,WAAW,EACT,mGAAmG;IACrG,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,oDAAoD;IACpE,QAAQ,EAAE;QACR,yBAAyB;QACzB,gBAAgB;QAChB,mCAAmC;QACnC,qBAAqB;QAErB,sBAAsB;QACtB,gBAAgB;QAChB,6BAA6B;QAE7B,sBAAsB;QACtB,gBAAgB;QAChB,iBAAiB;QACjB,oBAAoB;QAEpB,uBAAuB;QACvB,oBAAoB;QACpB,0BAA0B;KAC3B;IACD,gBAAgB,EAAE;QAChB,iCAAiC;QACjC,MAAM;QACN,MAAM;QACN,OAAO;QACP,MAAM;QACN,cAAc;QACd,kBAAkB;QAClB,YAAY;QACZ,gBAAgB;QAChB,gBAAgB;KACjB;IACD,cAAc,EACZ,ySAAyS;IAC3S,QAAQ,EAAE,gBAAgB;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAe;IAChD,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,iDAAiD;IACvD,WAAW,EACT,4GAA4G;IAC9G,QAAQ,EAAE,MAAM;IAChB,cAAc,EAAE,oDAAoD;IACpE,QAAQ,EAAE;QACR,6BAA6B;QAC7B,yEAAyE;QACzE,qFAAqF;QAErF,qCAAqC;QACrC,kEAAkE;QAElE,iCAAiC;QACjC,yCAAyC;QACzC,yCAAyC;KAC1C;IACD,gBAAgB,EAAE;QAChB,iCAAiC;QACjC,WAAW;QACX,WAAW;QACX,mBAAmB;QACnB,gBAAgB;QAChB,oBAAoB;QACpB,MAAM;QACN,cAAc;QACd,aAAa;QACb,WAAW;QACX,YAAY;KACb;IACD,cAAc,EACZ,yNAAyN;IAC3N,QAAQ,EAAE,gBAAgB;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAe;IACpC,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,6BAA6B;IACnC,WAAW,EACT,+DAA+D;IACjE,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,oDAAoD;IACpE,QAAQ,EAAE;QACR,4BAA4B;QAC5B,UAAU;QACV,YAAY;QACZ,aAAa;QACb,YAAY;QAEZ,yBAAyB;QACzB,4BAA4B;QAC5B,4BAA4B;QAC5B,wCAAwC;QACxC,qCAAqC;QACrC,wBAAwB;QAExB,qBAAqB;QACrB,wBAAwB;QACxB,kCAAkC;QAElC,iDAAiD;QACjD,6CAA6C;KAC9C;IACD,gBAAgB,EAAE;QAChB,4CAA4C;QAC5C,aAAa;QACb,aAAa;QACb,aAAa;QACb,OAAO;QACP,SAAS;QACT,WAAW;QACX,WAAW;QACX,8BAA8B;QAC9B,eAAe;KAChB;IACD,cAAc,EACZ,2KAA2K;IAC7K,QAAQ,EAAE,gBAAgB;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,kBAAkB;IAClB,sBAAsB;IACtB,UAAU;CACX,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=supabase-admin-client.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-admin-client.test.d.ts","sourceRoot":"","sources":["../../../src/scanners/authentication/supabase-admin-client.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { authenticationScanner } from './index.js';
3
+ import * as fs from 'fs/promises';
4
+ import * as path from 'path';
5
+ import * as os from 'os';
6
+ describe('MFA-001 Supabase non-auth client precision', () => {
7
+ let tempDir = '';
8
+ beforeEach(async () => {
9
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mfa-supabase-admin-'));
10
+ });
11
+ afterEach(async () => {
12
+ await fs.rm(tempDir, { recursive: true, force: true });
13
+ });
14
+ const options = () => ({ path: tempDir });
15
+ it('does not flag a service-role Supabase client used only for database operations', async () => {
16
+ const routeDir = path.join(tempDir, 'app', 'api', 'stripe', 'webhook');
17
+ await fs.mkdir(routeDir, { recursive: true });
18
+ const file = path.join(routeDir, 'route.ts');
19
+ await fs.writeFile(file, `
20
+ import { createClient } from '@supabase/supabase-js';
21
+
22
+ function getSupabaseAdmin() {
23
+ return createClient(
24
+ process.env.NEXT_PUBLIC_SUPABASE_URL || '',
25
+ process.env.SUPABASE_SERVICE_ROLE_KEY || ''
26
+ );
27
+ }
28
+
29
+ export async function POST() {
30
+ const supabaseAdmin = getSupabaseAdmin();
31
+ await supabaseAdmin.from('profiles').update({ plan: 'pro' }).eq('id', '123');
32
+ }
33
+ `, 'utf-8');
34
+ const findings = await authenticationScanner.scan([file], options());
35
+ expect(findings.filter((f) => f.id === 'MFA-001')).toHaveLength(0);
36
+ });
37
+ });
38
+ //# sourceMappingURL=supabase-admin-client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-admin-client.test.js","sourceRoot":"","sources":["../../../src/scanners/authentication/supabase-admin-client.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,GAAgB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAEvD,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QACvE,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC7C,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,EACJ;;;;;;;;;;;;;;CAcL,EACK,OAAO,CACR,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=supabase-callsite.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-callsite.test.d.ts","sourceRoot":"","sources":["../../../src/scanners/authentication/supabase-callsite.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import { authenticationScanner } from './index.js';
3
+ import * as fs from 'fs/promises';
4
+ import * as path from 'path';
5
+ import * as os from 'os';
6
+ describe('MFA-001 Supabase call-site precision', () => {
7
+ let tempDir = '';
8
+ afterEach(async () => {
9
+ if (tempDir) {
10
+ await fs.rm(tempDir, { recursive: true, force: true });
11
+ }
12
+ });
13
+ it('does not treat a shared-client signup route as provider MFA configuration', async () => {
14
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'supabase-callsite-'));
15
+ const file = path.join(tempDir, 'route.ts');
16
+ await fs.writeFile(file, `
17
+ import { createClient } from '@/lib/supabase/server';
18
+
19
+ export async function POST(req: Request) {
20
+ const supabase = await createClient();
21
+ const { data, error } = await supabase.auth.signUp({
22
+ email: 'user@example.com',
23
+ password: 'example-password',
24
+ });
25
+ return Response.json({ data, error });
26
+ }
27
+ `, 'utf-8');
28
+ const options = { path: tempDir };
29
+ const findings = await authenticationScanner.scan([file], options);
30
+ const mfaConfigFindings = findings.filter((finding) => finding.id === 'MFA-001');
31
+ expect(mfaConfigFindings).toHaveLength(0);
32
+ });
33
+ });
34
+ //# sourceMappingURL=supabase-callsite.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-callsite.test.js","sourceRoot":"","sources":["../../../src/scanners/authentication/supabase-callsite.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAE5C,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,EACJ;;;;;;;;;;;CAWL,EACK,OAAO,CACR,CAAC;QAEF,MAAM,OAAO,GAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QACnE,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QAEjF,MAAM,CAAC,iBAAiB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "verification-layer",
3
- "version": "0.27.7",
3
+ "version": "0.27.9",
4
4
  "description": "Open-source HIPAA compliance scanner for healthcare code. 143 rules, 5 HIPAA categories. CLI + CI/CD + VS Code.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",