Skip to content

refactor(middleware): convert protect, headers, and missing middlewares to TypeScript - #615

Merged
bkendall merged 5 commits into
prioritize_js_to_tsfrom
convert_middleware_headers_missing_protect
Nov 7, 2026
Merged

bkendall merged 5 commits into
prioritize_js_to_tsfrom
convert_middleware_headers_missing_protect

Conversation

@bkendall

@bkendall bkendall commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Converts src/middleware/protect.js, src/middleware/headers.js, src/middleware/missing.js, and their unit specs to TypeScript (src/middleware/protect.ts, src/middleware/headers.ts, src/middleware/missing.ts, test/unit/middleware/headers.spec.ts, and test/unit/middleware/missing.spec.ts).

  • Reuses Configuration, Header, Matcher, SuperstaticRequest, and SuperstaticResponse types and patterns.configMatcher from src/utils/patterns.ts.
  • Defaults spec = {} across protect, headers, and missing factories and preserves CommonJS middleware exports for unconverted JS callers.

@bkendall
bkendall requested review from Berlioz and joehan November 2, 2026 23:33

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates several middleware modules (headers, missing, and protect) and their corresponding unit tests from JavaScript to TypeScript, introducing robust type definitions and expanding test coverage. The review feedback highlights a few key improvement opportunities: adding a defensive check in headers.ts to prevent a potential runtime crash if a header key is missing, simplifying the object mapping logic in normalizedConfigHeaders to reduce redundancy, and replacing the deprecated url.parse API with the modern URL constructor.

Comment thread src/middleware/headers.ts Resolved
Comment thread src/middleware/headers.ts Resolved
Comment thread src/middleware/headers.ts Resolved

@joehan joehan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: PR #615 (refactor(middleware): convert protect, headers, and missing middlewares to TypeScript)

Strengths & LGTM Aspects

  • Consolidates three key middlewares into TypeScript with clean structure.
  • Adopts WHATWG URL for modern URL parsing.
  • Expands unit test coverage for headers and missing handlers.

Key Findings to Address

  1. Security-header bypass via backslash authority confusion (headers.ts): Passing raw URLs to new URL(normalizedUrl, "http://localhost") before slashPath allows GET /�dmin/secret.js to parse "admin" as the hostname and "/secret.js" as the pathname. Headers configured for /admin/** (CSP, X-Frame-Options, Cache-Control: no-store) are completely bypassed, while downstream middlewares serve /admin/secret.js with 200 OK.
  2. Fail-open authentication bypass in protect.ts: Changing spec.protect || config.protect to spec.protect ?? req.superstatic?.protect causes { protect: "" } to evaluate to "", calling next() and bypassing authentication entirely.
  3. Server crash and password leak in protect.ts: Colon-less credentials crash the server synchronously on the first request. Also credentials.split(":") truncates passwords containing : and leaks the password suffix in cleartext inside the WWW-Authenticate header.
  4. connect().use() fails TS2769 under strictFunctionTypes: Typing handler parameters as SuperstaticRequest rather than IncomingMessage & Partial<SuperstaticRequest> breaks connect().use(missing()) and connect().use(protect()).
  5. entry.glob is unslashed: entry.source is normalized with slashPath, but entry.glob is left unslashed.

Comment thread src/middleware/headers.ts Resolved
Comment thread src/middleware/protect.ts Resolved
Comment thread src/middleware/protect.ts Resolved
Comment thread src/middleware/missing.ts Outdated
provider?: unknown;
} = {},
): (
req: SuperstaticRequest,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 [P2 Typing] SuperstaticRequest breaks connect().use(missing()) under strictFunctionTypes

Requiring req: SuperstaticRequest, res: SuperstaticResponse causes connect().use(missing()) to fail compilation with TS2769: No overload matches this call because connect.IncomingMessage is not assignable to SuperstaticRequest.
Typing parameters as connect.IncomingMessage & Partial<SuperstaticRequest> and ServerResponse & Partial<SuperstaticResponse> allows seamless usage with Connect.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 019e85a: typed middleware handler parameters across headers.ts, missing.ts, and protect.ts as req: connect.IncomingMessage & { superstatic?: Configuration }, res: ServerResponse & { superstatic?: Responder }, next: connect.NextFunction, and verified direct connect().use(...) calls without casts.

Comment thread src/middleware/headers.ts Resolved
Converts src/utils/patterns.js to TypeScript with typed pattern matching utilities and adds unit tests in test/unit/utils/patterns.spec.ts.
@bkendall
bkendall force-pushed the convert_utils_patterns branch from b93843e to 9b1084a Compare November 4, 2026 21:51
…es to TypeScript

Converts src/middleware/protect.js, src/middleware/headers.js, src/middleware/missing.js, and their unit specs to TypeScript (src/middleware/protect.ts, src/middleware/headers.ts, src/middleware/missing.ts, test/unit/middleware/headers.spec.ts, and test/unit/middleware/missing.spec.ts).

- Reuses Configuration, Header, Matcher, SuperstaticRequest, and SuperstaticResponse types and patterns.configMatcher from src/utils/patterns.ts.
- Defaults spec = {} across protect, headers, and missing factories and preserves CommonJS middleware exports for unconverted JS callers.
- Guard headerToSet?.key before calling toLowerCase() when filtering with allowedHeaders
- Simplify normalizedConfigHeaders object construction with conditional source spread
- Replace deprecated url.parse with WHATWG URL in extractPathname with double-slash and invalid-URL handling
… and missing

- Parse only absolute URIs via URL() in headers extractPathname so backslash paths and decoded non-ASCII error paths normalize consistently via slashPath
- Normalize entry.glob alongside entry.source in normalizedConfigHeaders
- Fall back to req.superstatic.protect when spec.protect is empty string and split credentials on the first colon only, returning 401 when missing a colon
- Type middleware handlers with connect.IncomingMessage & { superstatic?: Configuration } and ServerResponse & { superstatic?: Responder } across headers, missing, and protect
- Add unit tests covering backslash security headers, non-ASCII paths, unslashed globs, Connect direct mounting, and protect middleware edge cases
@bkendall
bkendall force-pushed the convert_middleware_headers_missing_protect branch from 03b6579 to 019e85a Compare November 4, 2026 21:55
Base automatically changed from convert_utils_patterns to prioritize_js_to_ts November 7, 2026 00:15
@bkendall
bkendall merged commit c776ba5 into prioritize_js_to_ts Nov 7, 2026
16 checks passed
@bkendall
bkendall deleted the convert_middleware_headers_missing_protect branch November 7, 2026 00:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants