Skip to content

Add proxySessionId to provider params for forwarding requests to same…#59

Merged
adiwajshing merged 5 commits intomainfrom
same-proxy-ip
Dec 5, 2025
Merged

Add proxySessionId to provider params for forwarding requests to same…#59
adiwajshing merged 5 commits intomainfrom
same-proxy-ip

Conversation

@predatorx7
Copy link
Contributor

@predatorx7 predatorx7 commented Dec 3, 2025

… proxy ip

Description

Testing (ignore for documentation update)

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Checklist:

Additional Notes:

Summary by CodeRabbit

  • New Features

    • Optional proxy session ID to persist and reuse the same proxy IP across requests; included in tunnel creation flow and observability labels.
  • Bug Fixes / Validation

    • Enforced lowercase alphanumeric 8–14 char format for session IDs with clear rejection on invalid values.
    • Claim/create flows now validate that session IDs match to prevent mismatched reuse.
  • Tests

    • Added tests covering resolution, template substitution, validation, IP persistence and repeated-request stability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 3, 2025

Walkthrough

Adds an optional proxySessionId (string) across provider schemas, client requests, server tunnel flows, and tests; it is template-resolved and validated by the HTTP provider, propagated in CreateTunnelRequest, enforced in claim/create handlers, and used when constructing proxy URLs.

Changes

Cohort / File(s) Summary
Protocol & Generated Types
proto/api.proto, src/proto/api.ts, src/proto/tee-bundle.ts
Added proxySessionId (string, tag 5) to CreateTunnelRequest; updated base ctor, encode/decode, JSON/fromPartial; bumped protoc header comment.
Provider Schemas & Types
provider-schemas/http/parameters.yaml, src/types/providers.gen.ts, src/types/providers.ts
Added optional proxySessionId to HTTP provider schema and generated/types with docs and constraints; updated JSON schema and paramValues documentation.
HTTP Provider Implementation & Utils
src/providers/http/index.ts, src/server/utils/proxy-session.ts
Added public proxySessionId() accessor, getProxySessionId() resolution/substitution path, extraction/merge in substitute flow, and exported isValidProxySessionId(sessionId: string) for validation and errors.
Client Changes
src/client/create-claim.ts, src/client/tunnels/make-rpc-tls-tunnel.ts
Read resolved proxySessionId from provider params and include it in CreateTunnelRequest payloads.
Server Tunnel & Handlers
src/server/tunnels/make-tcp-tunnel.ts, src/server/handlers/createTunnel.ts, src/server/handlers/claimTunnel.ts
Validate and propagate proxySessionId in TCP tunnel flow; pass proxySessionId to socket/getSocket, embed session suffix in proxy URL when present, include APM label, extend logs/errors, and enforce claim mismatch checks against proxySessionId.
Types & Tunnel Signatures
src/types/tunnel.ts, src/server/index.ts
Updated TCPSocketProperties.createRequest and related types to include proxySessionId.
Tests
src/tests/http-provider-utils.test.ts, src/tests/rpc-tunnel.test.ts, src/tests/tcp-tunnel.test.ts
Added/updated tests for template resolution, missing-template errors, validation failures, RPC/TCP payloads, and session persistence (consistent IP with same proxySessionId).
sequenceDiagram
    participant Client
    participant HTTPProvider
    participant Server
    participant ProxyGW as ProxyGateway

    rect rgb(245,250,255)
    Note over Client,HTTPProvider: Client supplies provider params (may include proxySessionId template)
    Client->>HTTPProvider: resolve params (including proxySessionId)
    HTTPProvider->>HTTPProvider: extract & replace template values
    HTTPProvider->>HTTPProvider: validate via isValidProxySessionId
    HTTPProvider-->>Client: resolved provider params
    end

    rect rgb(255,250,240)
    Note over Client,Server: Create tunnel using resolved proxySessionId
    Client->>Server: CreateTunnel(createRequest with proxySessionId)
    Server->>Server: validate createRequest (including proxySessionId), label APM
    alt proxy URL available
        Server->>ProxyGW: open connection using proxy URL with session suffix (proxySessionId)
        ProxyGW-->>Server: connection established (proxy IP)
    else direct connect
        Server->>Server: connect directly (no proxy session)
    end
    Server-->>Client: tunnel ready
    end

    rect rgb(240,255,240)
    Note over Client,ProxyGW: Subsequent create with same proxySessionId
    Client->>Server: CreateTunnel(same proxySessionId)
    Server->>ProxyGW: reuse session (same proxy IP)
    ProxyGW-->>Client: response routed via same proxy IP
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Focus areas:
    • src/server/tunnels/make-tcp-tunnel.ts — proxy URL/session-suffix construction, validation branches, fallback behavior, and error messages.
    • src/providers/http/index.ts — template extraction/replacement, missing-template/error paths, and validation.
    • src/server/utils/proxy-session.ts — regex and length bounds correctness.
    • Tests (tcp/rpc/http-provider-utils) — assertions for session persistence and invalid-session handling.

Poem

🐇 I found an id of letters small and true,
I hop the tunnel path and follow through.
One session, one footprint, steady and neat,
Packets and carrots meet on the street.
A tiny hop, the proxy road feels new.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: adding proxySessionId to provider parameters for session-based proxy IP persistence. It is specific, concise, and directly reflects the core functionality introduced across proto definitions, provider schemas, and tunnel implementations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch same-proxy-ip

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1133d75 and 9c6ffcf.

📒 Files selected for processing (1)
  • src/tests/tcp-tunnel.test.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/tests/tcp-tunnel.test.ts (5)
src/server/tunnels/make-tcp-tunnel.ts (1)
  • makeTcpTunnel (41-102)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/providers/http/index.ts (1)
  • proxySessionId (57-61)
src/utils/http-parser.ts (1)
  • makeHttpResponseParser (52-232)
src/utils/generics.ts (2)
  • strToUint8Array (41-43)
  • uint8ArrayToStr (34-36)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (4)
src/tests/tcp-tunnel.test.ts (4)

10-10: Verify if skipping the entire test suite is intentional.

The entire TCP Tunnel test suite is currently skipped via describe.skip. If this is due to missing infrastructure or credentials, please document the reason. Otherwise, consider enabling these tests to validate the new proxySessionId functionality.


23-23: LGTM: proxySessionId parameter added consistently.

The addition of proxySessionId: '' to existing test cases properly extends the API surface for the new feature without altering existing test behavior.


58-58: LGTM: Test description accurately reflects expanded coverage.

The updated test name correctly indicates that both invalid geoLocation and invalid proxySessionId scenarios are now validated.


100-153: LGTM: IP consistency test correctly validates proxySessionId behavior.

The new test properly verifies that multiple sessions with the same proxySessionId route through the same proxy IP. The implementation correctly:

  • Reuses a helper function for tunnel creation and HTTP request flow
  • Asserts IP presence for each response
  • Uses assert.strictEqual to verify IP consistency across all three sessions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/tests/rpc-tunnel.test.ts (1)

180-237: Remove trailing semicolons to satisfy lint rules

The added await assert.rejects blocks end with ); on Line 208 and Line 237, whereas the rest of this file uses a no‑semicolon style. Static analysis is flagging these as “extra semicolon”.

You can fix this by dropping the semicolons:

-      )
-    );
+      )
+    )
@@
-      )
-    });
+      )
+    })

The test logic for geoLocation and proxySessionId error propagation otherwise looks good.

src/server/tunnels/make-tcp-tunnel.ts (2)

192-214: Proxy routing condition now breaks existing geoLocation-only flows

This block currently does:

if((proxySessionId || geoLocation) && !HTTPS_PROXY_URL) {
  // warn, then zero out both
}

if(!geoLocation || !proxySessionId) {
  socket.connect({ host, port })
  return socket
}

This requires both geoLocation and proxySessionId to be truthy to go through the HTTPS proxy. Previously, geoLocation alone was sufficient to trigger proxying. As a result, any client that sets only geoLocation (and no proxySessionId) will now fall back to a direct TCP connection without proxying, changing behavior in a non-obvious way.

For backwards-compatible semantics:

  • Use the proxy whenever a non-empty geoLocation is provided (as before).
  • Treat proxySessionId as an optional enhancement on top of that.

Concretely:

-  if(!geoLocation || !proxySessionId) {
-    socket.connect({ host, port })
-    return socket
-  }
+  // If no geoLocation is specified, connect directly without proxy.
+  if(!geoLocation) {
+    socket.connect({ host, port })
+    return socket
+  }

Then adjust the validation below (see next comment) so proxySessionId is optional.


216-236: Make proxySessionId optional and avoid rejecting empty values

Currently proxySessionId is validated unconditionally:

if(!isValidProxySessionId(proxySessionId)) {
  throw AttestorError.badRequest(
    `proxySessionId "${proxySessionId}" is invalid. ...`,
    { proxySessionId }
  )
}

Given callers pass proxySessionId: request.proxySessionId || '', an empty string is used to mean “no session id”. With the unconditional check, '' is treated as invalid and will 400 even when geoLocation is valid.

To treat proxySessionId as optional and allow “no session” semantics:

-  if(!isValidProxySessionId(proxySessionId)) {
+  if(proxySessionId && !isValidProxySessionId(proxySessionId)) {
     throw AttestorError.badRequest(
       `proxySessionId "${proxySessionId}" is invalid. Must be a lowercase alphanumeric string of length 8-14 characters. eg. "mystring12345", "something1234".`,
       { proxySessionId }
     )
   }

Combined with the previous suggestion (proxy on any non-empty geoLocation), this preserves existing geoLocation-only behavior while enforcing a well-formed session id when one is provided.

🧹 Nitpick comments (1)
src/server/handlers/createTunnel.ts (1)

24-31: APM label for proxySessionId is useful; optionally guard empties

Adding sessionTx?.setLabel('proxySessionId', opts.proxySessionId) is a good observability hook for correlating tunnels by proxy session.

If you want to avoid high‑cardinality labels that are often empty, you could optionally guard it:

if (opts.proxySessionId) {
	sessionTx?.setLabel('proxySessionId', opts.proxySessionId)
}

But the current behavior is functionally fine.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b372f22 and f466ef8.

📒 Files selected for processing (17)
  • proto/api.proto (1 hunks)
  • provider-schemas/http/parameters.yaml (1 hunks)
  • src/client/create-claim.ts (2 hunks)
  • src/client/tunnels/make-rpc-tls-tunnel.ts (1 hunks)
  • src/proto/api.ts (8 hunks)
  • src/proto/tee-bundle.ts (1 hunks)
  • src/providers/http/index.ts (4 hunks)
  • src/server/handlers/claimTunnel.ts (1 hunks)
  • src/server/handlers/createTunnel.ts (1 hunks)
  • src/server/tunnels/make-tcp-tunnel.ts (7 hunks)
  • src/server/utils/proxy-session.ts (1 hunks)
  • src/tests/http-provider-utils.test.ts (6 hunks)
  • src/tests/rpc-tunnel.test.ts (3 hunks)
  • src/tests/tcp-tunnel.test.ts (3 hunks)
  • src/types/providers.gen.ts (2 hunks)
  • src/types/providers.ts (1 hunks)
  • src/types/tunnel.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
src/types/tunnel.ts (1)
src/proto/api.ts (2)
  • CreateTunnelRequest (423-452)
  • CreateTunnelRequest (1407-1525)
src/providers/http/index.ts (1)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-3)
src/server/tunnels/make-tcp-tunnel.ts (4)
src/providers/http/index.ts (2)
  • proxySessionId (57-61)
  • geoLocation (52-56)
src/utils/logger.ts (1)
  • logger (10-10)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-3)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/tests/tcp-tunnel.test.ts (5)
src/providers/http/index.ts (1)
  • proxySessionId (57-61)
src/server/tunnels/make-tcp-tunnel.ts (1)
  • makeTcpTunnel (41-102)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/utils/http-parser.ts (1)
  • makeHttpResponseParser (52-232)
src/utils/generics.ts (2)
  • strToUint8Array (41-43)
  • uint8ArrayToStr (34-36)
src/client/create-claim.ts (2)
src/providers/http/index.ts (1)
  • proxySessionId (57-61)
src/utils/generics.ts (1)
  • getProviderValue (145-150)
src/tests/http-provider-utils.test.ts (3)
src/utils/generics.ts (1)
  • getProviderValue (145-150)
src/types/providers.ts (1)
  • ProviderParams (27-27)
src/providers/http/index.ts (1)
  • proxySessionId (57-61)
🪛 GitHub Actions: Test
src/providers/http/index.ts

[error] 1-1: ESLint: Run autofix to sort imports (simple-import-sort/imports).

🪛 GitHub Check: test
src/server/utils/proxy-session.ts

[failure] 2-2:
Extra semicolon


[failure] 2-2:
Expected indentation of 1 tab but found 4 spaces

src/tests/rpc-tunnel.test.ts

[failure] 237-237:
Extra semicolon


[failure] 208-208:
Extra semicolon

src/providers/http/index.ts

[failure] 698-698:
Expected blank line before this statement

src/server/tunnels/make-tcp-tunnel.ts

[failure] 13-13:
import statements should have an absolute path


[failure] 234-234:
Unexpected space(s) after "if"

src/tests/tcp-tunnel.test.ts

[failure] 12-12:
Unexpected space(s) after "for"

🔇 Additional comments (11)
src/client/tunnels/make-rpc-tls-tunnel.ts (1)

76-85: proxySessionId propagation into CreateTunnelRequest looks correct

Using proxySessionId: request.proxySessionId || '' ensures the field is always present and normalized to "" when absent, matching CreateTunnelRequest defaults and keeping server-side equality checks consistent. No issues from this change.

src/types/tunnel.ts (1)

22-25: TCPSocketProperties now correctly reflects proxySessionId

Including 'proxySessionId' in the Pick<CreateTunnelRequest, ...> keeps tunnel.createRequest aligned with the proto type and supports the additional equality check in claimTunnel. Looks good.

src/proto/tee-bundle.ts (1)

1-6: Generated header update is benign

The only modification is the protoc version comment (v6.33.1). No functional changes in this file; as long as it was regenerated with that compiler, this is fine.

src/client/create-claim.ts (1)

103-107: End-to-end wiring of proxySessionId through create/claim looks consistent

Reading proxySessionId via getProviderValue(params, provider.proxySessionId, secretParams) and threading it into createTunnelReq (then reusing the same object in ClaimTunnelRequest) keeps the tunnel creation and claim paths in sync. Combined with the TLS tunnel’s || '' normalization, this is consistent with the proto’s default semantics.

Also applies to: 130-137

src/server/handlers/claimTunnel.ts (1)

32-45: Including proxySessionId in tunnel request mismatch check is correct

Extending the mismatch guard to compare tunnel.createRequest?.proxySessionId against request?.proxySessionId aligns with the existing host/port/geo checks and prevents claims from mutating the proxy session ID post‑creation. Given both sides normalize absent values to "", this should behave correctly across versions.

src/tests/http-provider-utils.test.ts (1)

21-31: proxySessionId tests and fixtures look correct and aligned with provider behavior

The added coverage for proxySessionId:

  • Valid template resolution (should get proxy sessionId),
  • Missing template param error,
  • Treating proxySessionId: '' as undefined,
  • And updated ProviderParams fixtures (including hash expectations)

all match the intended semantics of proxySessionId being optional and resolved via paramValues.

No changes needed here.

Also applies to: 88-90, 512-530, 962-995, 1105-1111, 1159-1164, 1281-1286

src/providers/http/index.ts (2)

57-61: LGTM!

The proxySessionId method follows the same pattern as geoLocation for exposing provider parameters.


817-846: LGTM!

The getProxySessionId function follows the same pattern as getGeoLocation, correctly handling template parameter substitution and validation.

src/tests/tcp-tunnel.test.ts (2)

19-34: LGTM!

The proxySessionId: '' addition correctly propagates the new parameter through tunnel creation tests.


58-86: LGTM!

Good coverage for both invalid geoLocation and invalid proxySessionId validation, ensuring 400 errors are returned.

src/proto/api.ts (1)

1-5: Auto-generated file - changes verified correct.

This file is generated by protoc-gen-ts_proto and should not be manually edited. The proxySessionId field (field 5, string type) is correctly defined in the source proto/api.proto and has been properly added to CreateTunnelRequest in the generated code with correct encoding, decoding, and JSON conversion paths.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/server/tunnels/make-tcp-tunnel.ts (1)

216-228: Add conditional checks before validation to support optional parameters.

After fixing line 211 to use &&, either geoLocation or proxySessionId may be empty. The current validation logic will incorrectly reject empty strings:

  • isValidCountryCode('') likely returns false
  • isValidProxySessionId('') checks length > 8, so empty string fails

This prevents the intended behavior of allowing proxy usage with only one parameter.

Apply this diff to validate only when values are provided:

-	if(!isValidCountryCode(geoLocation)) {
+	if(geoLocation && !isValidCountryCode(geoLocation)) {
 		throw AttestorError.badRequest(
 			`Geolocation "${geoLocation}" is invalid. Must be 2 letter ISO country code`,
 			{ geoLocation }
 		)
 	}

-	if(!isValidProxySessionId(proxySessionId)) {
+	if(proxySessionId && !isValidProxySessionId(proxySessionId)) {
 		throw AttestorError.badRequest(
 			`proxySessionId "${proxySessionId}" is invalid. Must be a lowercase alphanumeric string of length 8-14 characters. eg. "mystring12345", "something1234".`,
 			{ proxySessionId }
 		)
 	}
♻️ Duplicate comments (6)
provider-schemas/http/parameters.yaml (1)

28-34: Grammar fix and consider adding schema constraints.

The description has "an smallcase" which should be "a lowercase". To align with isValidProxySessionId validation, consider adding schema-level constraints:

  proxySessionId:
    type: string
    nullable: true
    minLength: 8
    maxLength: 14
    pattern: '^[a-z0-9]+$'
    description: >-
      Specify the unique session ID for allowing use of the same proxy IP
      across multiple requests. Must be a lowercase alphanumeric string of length 8-14 characters.
      e.g. "mystring12345", "something1234".
src/server/utils/proxy-session.ts (1)

1-3: Length validation mismatch and style issues remain unaddressed.

The length check > 8 && < 15 allows 9–14 characters, but documentation consistently states 8–14. Additionally, the function uses 4 spaces instead of tabs and has a trailing semicolon.

proto/api.proto (1)

149-159: Contract mismatch with validator and grammar issue in documentation.

The proto comment specifies 8–14 characters, but isValidProxySessionId enforces 9–14. Also, "an smallcase" should be "a lowercase".

-	 * Can be an smallcase alphanumeric string of length 8-14 characters.
+	 * Must be a lowercase alphanumeric string of length 8-14 characters.
src/tests/tcp-tunnel.test.ts (1)

100-152: Good test coverage for proxySessionId IP persistence, but fix the assertion bug.

The test logic and helper function are well-structured. However, line 151 has a critical bug: a === b === c evaluates as (a === b) === c, comparing a boolean to a string.

-		assert.ok(resJson1.ip === resJson2.ip === resJson3.ip);
+		assert.strictEqual(resJson1.ip, resJson2.ip, 'IP should match across sessions');
+		assert.strictEqual(resJson2.ip, resJson3.ip, 'IP should match across sessions');
src/server/tunnels/make-tcp-tunnel.ts (2)

13-13: Use absolute import alias as previously suggested.

This was flagged in a previous review. The import should use the project's absolute alias form instead of a relative path.


202-209: Include proxySessionId in warning context as previously suggested.

This was flagged in a previous review. The logger.warn call should include both geoLocation and proxySessionId in its context object for better debugging.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f466ef8 and 841f400.

📒 Files selected for processing (17)
  • proto/api.proto (1 hunks)
  • provider-schemas/http/parameters.yaml (1 hunks)
  • src/client/create-claim.ts (2 hunks)
  • src/client/tunnels/make-rpc-tls-tunnel.ts (1 hunks)
  • src/proto/api.ts (8 hunks)
  • src/proto/tee-bundle.ts (1 hunks)
  • src/providers/http/index.ts (4 hunks)
  • src/server/handlers/claimTunnel.ts (1 hunks)
  • src/server/handlers/createTunnel.ts (1 hunks)
  • src/server/tunnels/make-tcp-tunnel.ts (7 hunks)
  • src/server/utils/proxy-session.ts (1 hunks)
  • src/tests/http-provider-utils.test.ts (6 hunks)
  • src/tests/rpc-tunnel.test.ts (3 hunks)
  • src/tests/tcp-tunnel.test.ts (3 hunks)
  • src/types/providers.gen.ts (2 hunks)
  • src/types/providers.ts (1 hunks)
  • src/types/tunnel.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • src/client/create-claim.ts
  • src/types/providers.gen.ts
  • src/client/tunnels/make-rpc-tls-tunnel.ts
  • src/server/handlers/createTunnel.ts
  • src/server/handlers/claimTunnel.ts
  • src/types/tunnel.ts
  • src/proto/tee-bundle.ts
  • src/tests/rpc-tunnel.test.ts
  • src/providers/http/index.ts
  • src/tests/http-provider-utils.test.ts
  • src/types/providers.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/server/tunnels/make-tcp-tunnel.ts (4)
src/providers/http/index.ts (2)
  • proxySessionId (57-61)
  • geoLocation (52-56)
src/utils/logger.ts (1)
  • logger (10-10)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-3)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/tests/tcp-tunnel.test.ts (5)
src/providers/http/index.ts (2)
  • geoLocation (52-56)
  • proxySessionId (57-61)
src/server/tunnels/make-tcp-tunnel.ts (1)
  • makeTcpTunnel (41-102)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/utils/http-parser.ts (1)
  • makeHttpResponseParser (52-232)
src/utils/generics.ts (2)
  • strToUint8Array (41-43)
  • uint8ArrayToStr (34-36)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (6)
src/proto/api.ts (1)

1404-1404: Auto-generated protobuf code correctly adds proxySessionId support.

The generated code properly handles the new proxySessionId field across encode, decode, JSON conversion, and partial construction methods, consistent with the proto definition.

Also applies to: 1421-1423, 1466-1473, 1489-1489, 1507-1509, 1522-1522

src/tests/tcp-tunnel.test.ts (1)

58-86: Test coverage for invalid proxySessionId is appropriate.

The test correctly verifies that an invalid proxySessionId (too short) triggers a 400 error. This aligns with the validation logic in isValidProxySessionId.

src/server/tunnels/make-tcp-tunnel.ts (4)

31-32: LGTM!

The documentation clearly explains the purpose of proxySessionId for session-scoped proxy IP persistence.


104-104: LGTM!

The proxySessionId parameter is correctly propagated through the connectTcpgetSocket_getSocket call chain.

Also applies to: 125-125, 197-197


230-236: LGTM!

The URL construction correctly handles optional parameters, replacing placeholders with actual values or empty strings, and properly formatting the session suffix.


255-260: LGTM!

Error logging and messages properly include proxySessionId context alongside geoLocation, which aids debugging and provides clear error information to users.

Comment on lines 73 to 85
assert.rejects(
async () => makeTcpTunnel({
host: 'lumtest.com',
port: 80,
geoLocation: '',
proxySessionId: 'xz',
logger,
}),
(err: AttestorError) => {
assert.match(err.message, /failed with status code: 400/)
return true
}
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Await the rejection assertions.

Both assert.rejects calls are not awaited, so test failures may not be caught properly.

-		assert.rejects(
+		await assert.rejects(
 			async () => makeTcpTunnel({
 				host: 'lumtest.com',
 				port: 80,
 				geoLocation: '',
 				proxySessionId: 'xz',
 				logger,
 			}),
 			(err: AttestorError) => {
 				assert.match(err.message, /failed with status code: 400/)
 				return true
 			}
 		);

Also apply await to the first assert.rejects at line 59.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert.rejects(
async () => makeTcpTunnel({
host: 'lumtest.com',
port: 80,
geoLocation: '',
proxySessionId: 'xz',
logger,
}),
(err: AttestorError) => {
assert.match(err.message, /failed with status code: 400/)
return true
}
);
await assert.rejects(
async () => makeTcpTunnel({
host: 'lumtest.com',
port: 80,
geoLocation: '',
proxySessionId: 'xz',
logger,
}),
(err: AttestorError) => {
assert.match(err.message, /failed with status code: 400/)
return true
}
);
🤖 Prompt for AI Agents
In src/tests/tcp-tunnel.test.ts around lines 59 and 73-85, the two
assert.rejects calls are not awaited so test failures can be missed; add await
before both assert.rejects invocations (the one around line 59 and the one
spanning lines 73-85) so the test runner waits for the promise assertions to
complete and failures are properly propagated.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/tests/rpc-tunnel.test.ts (1)

180-237: Remove extra semicolons flagged by lint

Static analysis reports extra semicolons on the two assert.rejects blocks’ closing lines. You can satisfy the linter by dropping those trailing ; while keeping behavior the same:

-        });
+        })-        });
+        })
♻️ Duplicate comments (7)
src/server/tunnels/make-tcp-tunnel.ts (3)

211-227: Fix proxy gating and make validations conditional

The current condition:

if(!geoLocation || !proxySessionId) {
	socket.connect({ host, port })
	return socket
}

forces BOTH geoLocation and proxySessionId to be present to use the proxy. That breaks intended behavior where either field alone should be enough to route via proxy. It also always validates both fields, even when one is intentionally omitted.

Recommend:

-	if(!geoLocation || !proxySessionId) {
+	if(!geoLocation && !proxySessionId) {
 		socket.connect({ host, port, })
 		return socket
 	}
 
-	if(!isValidCountryCode(geoLocation)) {
+	if(geoLocation && !isValidCountryCode(geoLocation)) {
 		throw AttestorError.badRequest(
 			`Geolocation "${geoLocation}" is invalid. Must be 2 letter ISO country code`,
 			{ geoLocation }
 		)
 	}
 
-	if(!isValidProxySessionId(proxySessionId)) {
+	if(proxySessionId && !isValidProxySessionId(proxySessionId)) {
 		throw AttestorError.badRequest(
 			`proxySessionId "${proxySessionId}" is invalid. Must be a lowercase alphanumeric string of length 8-14 characters. eg. "mystring12345", "something1234".`,
 			{ proxySessionId }
 		)
 	}

This keeps direct connections when both are absent, but allows proxy usage with geoLocation-only, proxySessionId-only, or both.


13-13: Use absolute import path for isValidProxySessionId

Static analysis prefers the project’s absolute alias here. Update the import to be consistent with other imports in this file:

-import { isValidProxySessionId } from '../utils/proxy-session.ts'
+import { isValidProxySessionId } from '#src/server/utils/proxy-session.ts'

201-209: Include proxySessionId in warning context when proxy URL is missing

When a geoLocation or proxySessionId is supplied but HTTPS_PROXY_URL is unset, the warn log currently only includes geoLocation. For debugging, it’s useful to see both:

-	if((proxySessionId || geoLocation) && !HTTPS_PROXY_URL) {
-		logger.warn(
-			{ geoLocation },
-			'geoLocation or proxySessionId provided but no proxy URL found'
-		)
+	if((proxySessionId || geoLocation) && !HTTPS_PROXY_URL) {
+		logger.warn(
+			{ geoLocation, proxySessionId },
+			'geoLocation or proxySessionId provided but no proxy URL found'
+		)
 		geoLocation = ''
 		proxySessionId = ''
 	}
src/tests/tcp-tunnel.test.ts (1)

58-86: Await rejection assertions and fix chained IP equality

Two issues here:

  1. assert.rejects calls are not awaited, so failures may not be caught if this suite is ever un‑skipped.
  2. resJson1.ip === resJson2.ip === resJson3.ip is a chained equality that compares a boolean to a string and doesn’t actually assert that all three IPs match.

Suggested fixes:

-	it('should gracefully fail an invalid geoLocation or ip session id', async () => {
-		assert.rejects(
+	it('should gracefully fail an invalid geoLocation or ip session id', async () => {
+		await assert.rejects(
 			async () => makeTcpTunnel({
 				host: 'lumtest.com',
 				port: 80,
 				geoLocation: 'xz',
 				proxySessionId: '',
 				logger,
 			}),
 			(err: AttestorError) => {
 				assert.match(err.message, /failed with status code: 400/)
 				return true
 			}
-		);
-
-		assert.rejects(
+		)
+
+		await assert.rejects(
 			async () => makeTcpTunnel({
 				host: 'lumtest.com',
 				port: 80,
 				geoLocation: '',
 				proxySessionId: 'xz',
 				logger,
 			}),
 			(err: AttestorError) => {
 				assert.match(err.message, /failed with status code: 400/)
 				return true
 			}
-		);
+		)
 	})
…
-		assert.ok(resJson1.ip === resJson2.ip === resJson3.ip);
+		assert.strictEqual(resJson1.ip, resJson2.ip)
+		assert.strictEqual(resJson2.ip, resJson3.ip)

Also applies to: 100-152

src/server/utils/proxy-session.ts (1)

1-3: Fix proxySessionId length range and lint issues

Current validator enforces 9–14 chars (> 8 && < 15), but the rest of the code/docs say 8–14. It also violates the project’s no‑semicolon / tabs style.

Recommend:

-export function isValidProxySessionId(sessionId: string): boolean {
-    return typeof sessionId === 'string' && sessionId.length > 8 && sessionId.length < 15 && /^[a-z0-9]+$/.test(sessionId);
-}
+export function isValidProxySessionId(sessionId: string): boolean {
+	return typeof sessionId === 'string'
+		&& sessionId.length >= 8
+		&& sessionId.length <= 14
+		&& /^[a-z0-9]+$/.test(sessionId)
+}

This matches the documented 8–14 range and satisfies the linter.

src/providers/http/index.ts (2)

33-33: Import order issue persists despite previous fix.

The pipeline is still failing due to import sorting issues. The previous fix may not have fully resolved the problem.

Run ESLint autofix to correct the import order:

#!/bin/bash
# Run ESLint autofix to sort imports
npx eslint --fix src/providers/http/index.ts

698-702: Critical bug: Wrong property name getProxySessionId should be proxySessionId.

This code uses params.getProxySessionId but the getProxySessionId function at line 818 expects v2Params.proxySessionId. Compare with the geoLocation pattern at lines 693-697 which correctly uses params.geoLocation.

Additionally, add a blank line before this statement per linting rules.

Apply this diff to fix the property name and linting issue:

+
-const proxySessionIdParams = extractAndReplaceTemplateValues(params.getProxySessionId)
+const proxySessionIdParams = extractAndReplaceTemplateValues(params.proxySessionId)
 if(proxySessionIdParams) {
-	params.getProxySessionId = proxySessionIdParams.newParam
+	params.proxySessionId = proxySessionIdParams.newParam
 	extractedValues = { ...extractedValues, ...proxySessionIdParams.extractedValues }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 841f400 and 8a860a2.

📒 Files selected for processing (17)
  • proto/api.proto (1 hunks)
  • provider-schemas/http/parameters.yaml (1 hunks)
  • src/client/create-claim.ts (2 hunks)
  • src/client/tunnels/make-rpc-tls-tunnel.ts (1 hunks)
  • src/proto/api.ts (8 hunks)
  • src/proto/tee-bundle.ts (1 hunks)
  • src/providers/http/index.ts (4 hunks)
  • src/server/handlers/claimTunnel.ts (1 hunks)
  • src/server/handlers/createTunnel.ts (1 hunks)
  • src/server/tunnels/make-tcp-tunnel.ts (7 hunks)
  • src/server/utils/proxy-session.ts (1 hunks)
  • src/tests/http-provider-utils.test.ts (6 hunks)
  • src/tests/rpc-tunnel.test.ts (3 hunks)
  • src/tests/tcp-tunnel.test.ts (3 hunks)
  • src/types/providers.gen.ts (2 hunks)
  • src/types/providers.ts (1 hunks)
  • src/types/tunnel.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/proto/tee-bundle.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/types/providers.ts
  • src/client/create-claim.ts
  • src/server/handlers/createTunnel.ts
  • src/client/tunnels/make-rpc-tls-tunnel.ts
  • provider-schemas/http/parameters.yaml
  • src/types/tunnel.ts
  • proto/api.proto
  • src/proto/api.ts
  • src/types/providers.gen.ts
🧰 Additional context used
🧬 Code graph analysis (4)
src/tests/rpc-tunnel.test.ts (2)
src/client/tunnels/make-rpc-tls-tunnel.ts (1)
  • makeRpcTlsTunnel (32-172)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/server/tunnels/make-tcp-tunnel.ts (2)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-3)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/tests/tcp-tunnel.test.ts (4)
src/providers/http/index.ts (2)
  • geoLocation (52-56)
  • proxySessionId (57-61)
src/server/tunnels/make-tcp-tunnel.ts (1)
  • makeTcpTunnel (41-102)
src/utils/http-parser.ts (1)
  • makeHttpResponseParser (52-232)
src/utils/generics.ts (2)
  • strToUint8Array (41-43)
  • uint8ArrayToStr (34-36)
src/providers/http/index.ts (2)
src/types/providers.ts (1)
  • ProviderSecretParams (29-29)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-3)
🪛 GitHub Actions: Test
src/providers/http/index.ts

[error] 1-1: eslint ./ --ext .js,.ts,.jsx,.tsx: simple-import-sort/imports - Run autofix to sort these imports!

🪛 GitHub Check: test
src/tests/rpc-tunnel.test.ts

[failure] 237-237:
Extra semicolon


[failure] 208-208:
Extra semicolon

src/server/tunnels/make-tcp-tunnel.ts

[failure] 13-13:
import statements should have an absolute path


[failure] 236-236:
Extra semicolon


[failure] 230-230:
This assertion is unnecessary since it does not change the type of the expression

src/providers/http/index.ts

[failure] 698-698:
Expected blank line before this statement

src/server/utils/proxy-session.ts

[failure] 2-2:
Extra semicolon


[failure] 2-2:
Expected indentation of 1 tab but found 4 spaces

🔇 Additional comments (6)
src/server/handlers/claimTunnel.ts (1)

38-45: Include proxySessionId in create/claim consistency checks

Adding proxySessionId to the mismatch guard is correct and keeps claim validation aligned with the extended CreateTunnelRequest surface.

src/tests/rpc-tunnel.test.ts (1)

36-38: Explicitly passing empty geoLocation/proxySessionId looks good

Initializing geoLocation and proxySessionId as empty strings in the basic RPC tunnel test clarifies intent and keeps payloads consistent with the server defaults.

src/tests/http-provider-utils.test.ts (1)

23-30: proxySessionId test coverage and plumbing look consistent

The added proxySessionId handling in HTTP provider tests is consistent with existing geoLocation patterns:

  • getProviderValue + proxySessionId template resolution.
  • Error path when the template param is missing.
  • Empty proxySessionId returning undefined.
  • Including proxySessionId in hashProviderParams and createRequest flows.

All of this aligns with the new provider surface and should help catch regressions.

Also applies to: 512-515, 962-994, 1045-1111, 1159-1183, 1281-1286

src/server/tunnels/make-tcp-tunnel.ts (1)

252-261: Proxy error message composition is correct and informative

The updated error message that conditionally mentions geoLocation and/or proxySessionId produces clear diagnostics while handling the “only one provided” cases cleanly. This is a nice improvement for debugging proxy failures.

src/providers/http/index.ts (2)

57-61: LGTM!

The proxySessionId method correctly follows the same pattern as geoLocation, delegating to getProxySessionId when the parameter is present.


817-846: LGTM!

The getProxySessionId function correctly implements template parameter resolution and validation, following the same pattern as getGeoLocation. The validation with isValidProxySessionId ensures only valid proxy session IDs are accepted.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/tests/rpc-tunnel.test.ts (1)

180-209: Remove extra semicolon.

Static analysis flags an extra semicolon that violates the project's style guidelines.

Apply this diff:

 			(err: AttestorError) => {
 				assert.match(err.message, /Geolocation "XZ" is invalid/)
 				return true
 			}
-		);
+		)
♻️ Duplicate comments (11)
proto/api.proto (1)

149-159: Contract mismatch remains unresolved between proto docs and validator.

The proto documentation states proxySessionId can be 8-14 characters, but based on past review comments, there's an inconsistency with the server-side validator. The team must decide on the canonical allowed length (either 8-14 or 9-14) and ensure:

  • Proto documentation
  • Server validation logic (isValidProxySessionId)
  • Type definitions
  • Tests

all agree on the same character range.

src/server/utils/proxy-session.ts (1)

1-3: Fix formatting issues: indentation and semicolon.

Static analysis flags incorrect indentation (4 spaces instead of 1 tab) and an extra semicolon. The project uses tab indentation.

Apply this diff:

 export function isValidProxySessionId(sessionId: string): boolean {
-    return typeof sessionId === 'string' && sessionId.length >= 8 && sessionId.length < 15 && /^[a-z0-9]+$/.test(sessionId);
+	return typeof sessionId === 'string'
+		&& sessionId.length >= 8
+		&& sessionId.length <= 14
+		&& /^[a-z0-9]+$/.test(sessionId)
 }

Note: Also changed < 15 to <= 14 for clarity, though both are semantically equivalent.

src/tests/tcp-tunnel.test.ts (4)

12-12: Fix formatting: remove space after for.

Static analysis flags unexpected whitespace after the for keyword, which violates the project's style guidelines.

Apply this diff:

-	for (const geoLocation of ALL_LOCATIONS) {
+	for(const geoLocation of ALL_LOCATIONS) {

59-71: Missing await on assertion.

The assert.rejects call is not awaited, which means test failures may not be properly caught and the test may complete before the assertion is evaluated.

Apply this diff:

-	assert.rejects(
+	await assert.rejects(
 		async () => makeTcpTunnel({

73-85: Missing await on assertion.

The assert.rejects call is not awaited, which means test failures may not be properly caught and the test may complete before the assertion is evaluated.

Apply this diff:

-	assert.rejects(
+	await assert.rejects(
 		async () => makeTcpTunnel({

151-151: Fix chained equality comparison bug.

In JavaScript, a === b === c evaluates as (a === b) === c, comparing a boolean to a string. This will never correctly verify that all three IPs are equal.

Apply this diff:

-	assert.ok(resJson1.ip === resJson2.ip === resJson3.ip);
+	assert.strictEqual(resJson1.ip, resJson2.ip, 'IP should match between requests')
+	assert.strictEqual(resJson2.ip, resJson3.ip, 'IP should match between requests')
src/server/tunnels/make-tcp-tunnel.ts (3)

13-13: Use project alias import for isValidProxySessionId

The import should follow the project’s absolute alias convention (and the lint hint) instead of a relative path.

-import { isValidProxySessionId } from '../utils/proxy-session.ts'
+import { isValidProxySessionId } from '#src/server/utils/proxy-session.ts'

This will also clear the “absolute path” ESLint error.


192-214: Proxy routing condition forces both geoLocation and proxySessionId; should allow either

_getSocket currently skips the proxy whenever either geoLocation or proxySessionId is missing:

if(!geoLocation || !proxySessionId) {
  socket.connect({ host, port })
  return socket
}

This requires both to be present to use the proxy, which contradicts the surrounding logic and intended behavior (proxy should be used when at least one of them is provided).

Update the condition so that you only bypass the proxy when both are absent:

-	if(!geoLocation || !proxySessionId) {
+	if(!geoLocation && !proxySessionId) {
 		socket.connect({ host, port })
 		return socket
 	}

201-209: Tighten logging and simplify agent URL construction

Two small cleanups here:

  1. Include proxySessionId in the warning context

You already clear proxySessionId when no proxy URL is configured; include it in the log for debugging:

-	if((proxySessionId || geoLocation) && !HTTPS_PROXY_URL) {
-		logger.warn(
-			{ geoLocation },
-			'geoLocation or proxySessionId provided but no proxy URL found'
-		)
+	if((proxySessionId || geoLocation) && !HTTPS_PROXY_URL) {
+		logger.warn(
+			{ geoLocation, proxySessionId },
+			'geoLocation or proxySessionId provided but no proxy URL found'
+		)
  1. Remove unnecessary non-null assertions and trailing semicolon on agentUrl

HTTPS_PROXY_URL already has a concrete type from getEnvVariable, so the ! assertions and the extra ; are not needed and are flagged by lint:

-	const agentUrl = HTTPS_PROXY_URL!.replace(
+	const agentUrl = HTTPS_PROXY_URL.replace(
 		'{{geoLocation}}',
 		geoLocation?.toLowerCase() || ''
-	)!.replace(
+	).replace(
 		'{{proxySessionId}}',
 		proxySessionId ? `-session-${proxySessionId}` : ''
-	);
+	)

The isValidProxySessionId check and the badRequest error look correct and give a clear message.

Also applies to: 223-227, 230-236

src/providers/http/index.ts (2)

33-33: Fix import ordering per simple-import-sort

The new isValidProxySessionId import triggers the simple-import-sort ESLint rule. Reorder imports to match the project’s configured grouping (third-party, #src/..., then relative), or just run:

npx eslint --fix src/providers/http/index.ts

to let the tool sort them.


693-702: Bug: substituteParamValues uses wrong property for proxySessionId templates

Here you attempt to resolve template values for proxySessionId, but the code reads and writes params.getProxySessionId, which doesn’t exist on HTTPProviderParams:

const proxySessionIdParams = extractAndReplaceTemplateValues(params.getProxySessionId)
if(proxySessionIdParams) {
  params.getProxySessionId = proxySessionIdParams.newParam
  extractedValues = { ...extractedValues, ...proxySessionIdParams.extractedValues }
}

This means proxySessionId templates are never actually substituted on params.proxySessionId.

Update this block to operate on the correct property:

-	const proxySessionIdParams = extractAndReplaceTemplateValues(params.getProxySessionId)
+	const proxySessionIdParams = extractAndReplaceTemplateValues(params.proxySessionId)
 	if(proxySessionIdParams) {
-		params.getProxySessionId = proxySessionIdParams.newParam
+		params.proxySessionId = proxySessionIdParams.newParam
 		extractedValues = { ...extractedValues, ...proxySessionIdParams.extractedValues }
 	}

Also, add the blank line before this const to satisfy the ESLint “expected blank line before this statement” rule.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a860a2 and f4cce1d.

📒 Files selected for processing (17)
  • proto/api.proto (1 hunks)
  • provider-schemas/http/parameters.yaml (1 hunks)
  • src/client/create-claim.ts (2 hunks)
  • src/client/tunnels/make-rpc-tls-tunnel.ts (1 hunks)
  • src/proto/api.ts (8 hunks)
  • src/proto/tee-bundle.ts (1 hunks)
  • src/providers/http/index.ts (4 hunks)
  • src/server/handlers/claimTunnel.ts (1 hunks)
  • src/server/handlers/createTunnel.ts (1 hunks)
  • src/server/tunnels/make-tcp-tunnel.ts (7 hunks)
  • src/server/utils/proxy-session.ts (1 hunks)
  • src/tests/http-provider-utils.test.ts (6 hunks)
  • src/tests/rpc-tunnel.test.ts (3 hunks)
  • src/tests/tcp-tunnel.test.ts (3 hunks)
  • src/types/providers.gen.ts (2 hunks)
  • src/types/providers.ts (1 hunks)
  • src/types/tunnel.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • provider-schemas/http/parameters.yaml
  • src/client/tunnels/make-rpc-tls-tunnel.ts
  • src/server/handlers/claimTunnel.ts
  • src/server/handlers/createTunnel.ts
  • src/client/create-claim.ts
  • src/proto/tee-bundle.ts
  • src/types/providers.ts
  • src/types/providers.gen.ts
🧰 Additional context used
🧬 Code graph analysis (6)
src/tests/rpc-tunnel.test.ts (2)
src/client/tunnels/make-rpc-tls-tunnel.ts (1)
  • makeRpcTlsTunnel (32-172)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/providers/http/index.ts (2)
src/types/providers.ts (1)
  • ProviderSecretParams (29-29)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-3)
src/server/tunnels/make-tcp-tunnel.ts (3)
src/providers/http/index.ts (2)
  • proxySessionId (57-61)
  • geoLocation (52-56)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-3)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/tests/tcp-tunnel.test.ts (4)
src/providers/http/index.ts (2)
  • geoLocation (52-56)
  • proxySessionId (57-61)
src/server/tunnels/make-tcp-tunnel.ts (1)
  • makeTcpTunnel (41-102)
src/utils/http-parser.ts (1)
  • makeHttpResponseParser (52-232)
src/utils/generics.ts (2)
  • strToUint8Array (41-43)
  • uint8ArrayToStr (34-36)
src/tests/http-provider-utils.test.ts (3)
src/utils/generics.ts (1)
  • getProviderValue (145-150)
src/types/providers.ts (1)
  • ProviderParams (27-27)
src/providers/http/index.ts (1)
  • proxySessionId (57-61)
src/types/tunnel.ts (1)
src/proto/api.ts (2)
  • CreateTunnelRequest (423-452)
  • CreateTunnelRequest (1407-1525)
🪛 GitHub Actions: Test
src/providers/http/index.ts

[error] 1-1: ESLint: simple-import-sort/imports - Run autofix to sort these imports.

🪛 GitHub Check: test
src/tests/rpc-tunnel.test.ts

[failure] 237-237:
Extra semicolon


[failure] 208-208:
Extra semicolon

src/providers/http/index.ts

[failure] 698-698:
Expected blank line before this statement

src/server/tunnels/make-tcp-tunnel.ts

[failure] 13-13:
import statements should have an absolute path


[failure] 236-236:
Extra semicolon


[failure] 230-230:
This assertion is unnecessary since it does not change the type of the expression

src/server/utils/proxy-session.ts

[failure] 2-2:
Extra semicolon


[failure] 2-2:
Expected indentation of 1 tab but found 4 spaces

🔇 Additional comments (8)
src/proto/api.ts (1)

4-4: LGTM! Generated code correctly implements proxySessionId.

The protoc-generated code properly handles the new proxySessionId field across all serialization paths (encode, decode, fromJSON, toJSON, fromPartial). The field is correctly assigned field number 5 with wire type 42 (string), and the initialization defaults to an empty string.

Also applies to: 441-451, 1404-1404, 1421-1423, 1466-1473, 1489-1489, 1507-1509, 1522-1522

src/types/tunnel.ts (1)

24-24: LGTM! Type signature correctly extended.

The TCPSocketProperties type now includes proxySessionId in the createRequest pick, properly reflecting the updated CreateTunnelRequest interface.

src/tests/rpc-tunnel.test.ts (1)

36-38: LGTM! Test properly initialized with proxySessionId.

The tunnel creation request now correctly includes the proxySessionId field with an empty string default, consistent with the API changes.

src/tests/tcp-tunnel.test.ts (1)

100-152: Good test coverage for proxySessionId IP persistence.

The new test properly verifies that multiple requests using the same proxySessionId yield consistent IP addresses, which is the core feature being implemented.

src/tests/http-provider-utils.test.ts (2)

23-30: Proxy session ID wiring in tests looks consistent with provider behavior

Destructuring proxySessionId from the HTTP provider and threading it through hash, body, and URL substitution tests (including explicit '' cases) correctly exercises the new parameter without changing existing semantics. No issues here.

Also applies to: 494-530, 1104-1111, 1159-1164, 1281-1286


962-995: Good coverage for proxySessionId resolution and edge cases

The new tests validate:

  • Template-based resolution via getProviderValue and paramValues
  • Error on missing template param
  • undefined when proxySessionId is empty

This matches the HTTP provider’s getProxySessionId logic and will catch regressions. No changes needed.

src/server/tunnels/make-tcp-tunnel.ts (1)

223-227: Proxy session ID validation aligns with shared rules

The isValidProxySessionId check and the specific AttestorError.badRequest message (including echoing the bad value and documenting constraints) correctly enforce the shared validation rule and provide structured error data for clients.

src/providers/http/index.ts (1)

57-61: HTTP provider proxySessionId wiring and validation look correct

Defining proxySessionId(params, secretParams) on HTTP_PROVIDER and delegating to getProxySessionId mirrors the existing geoLocation pattern, and getProxySessionId:

  • Resolves {{...}} placeholders from paramValues and secret paramValues
  • Throws with a clear message when a template param is missing
  • Validates format via isValidProxySessionId and errors on invalid values
  • Returns undefined when proxySessionId is unset or empty

This matches the new tests and shared validation helper; no functional issues here.

Also applies to: 785-846

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/server/tunnels/make-tcp-tunnel.ts (1)

201-228: Fix validation so geo-only and proxySessionId-only usages both work

Right now _getSocket always validates both geoLocation and proxySessionId whenever at least one is non-empty:

  • If geoLocation = 'US' and proxySessionId = '', the call to isValidProxySessionId('') will fail, breaking existing geo-only behavior.
  • If geoLocation = '' and proxySessionId = 'abcd12345', the call to isValidCountryCode('') will fail, blocking the intended “session-only” proxy use-case (as used in the new TCP tests).

The guard above (if(!geoLocation && !proxySessionId) { ... }) correctly routes the “both absent” case directly, so these validations should be conditional on the corresponding field actually being provided.

Suggested fix:

-	if(!isValidCountryCode(geoLocation)) {
-		throw AttestorError.badRequest(
-			`Geolocation "${geoLocation}" is invalid. Must be 2 letter ISO country code`,
-			{ geoLocation }
-		)
-	}
-
-	if(!isValidProxySessionId(proxySessionId)) {
-		throw AttestorError.badRequest(
-			`proxySessionId "${proxySessionId}" is invalid. Must be a lowercase alphanumeric string of length 8-14 characters. eg. "mystring12345", "something1234".`,
-			{ proxySessionId }
-		)
-	}
+	if(geoLocation && !isValidCountryCode(geoLocation)) {
+		throw AttestorError.badRequest(
+			`Geolocation "${geoLocation}" is invalid. Must be 2 letter ISO country code`,
+			{ geoLocation }
+		)
+	}
+
+	if(proxySessionId && !isValidProxySessionId(proxySessionId)) {
+		throw AttestorError.badRequest(
+			`proxySessionId "${proxySessionId}" is invalid. Must be a lowercase alphanumeric string of length 8-14 characters. eg. "mystring12345", "something1234".`,
+			{ proxySessionId }
+		)
+	}
♻️ Duplicate comments (3)
src/tests/tcp-tunnel.test.ts (1)

58-85: await the assert.rejects calls so failures are actually asserted

Both rejection assertions are still not awaited, so the async test may complete before the assertions run, and failures can be missed.

Apply this change:

-	it('should gracefully fail an invalid geoLocation or ip session id', async() => {
-		assert.rejects(
+	it('should gracefully fail an invalid geoLocation or ip session id', async() => {
+		await assert.rejects(
 			async() => makeTcpTunnel({
 				host: 'lumtest.com',
 				port: 80,
 				geoLocation: 'xz',
 				proxySessionId: '',
 				logger,
 			}),
 			(err: AttestorError) => {
 				assert.match(err.message, /failed with status code: 400/)
 				return true
 			}
 		)
 
-		assert.rejects(
+		await assert.rejects(
 			async() => makeTcpTunnel({
 				host: 'lumtest.com',
 				port: 80,
 				geoLocation: '',
 				proxySessionId: 'xz',
 				logger,
 			}),
 			(err: AttestorError) => {
 				assert.match(err.message, /failed with status code: 400/)
 				return true
 			}
 		)
src/server/tunnels/make-tcp-tunnel.ts (1)

202-236: Minor: non-null assertion on HTTPS_PROXY_URL is unnecessary

Given HTTPS_PROXY_URL is already a concrete string (from getEnvVariable) and guarded above when missing, the ! non-null assertion is redundant and was previously flagged by static analysis.

You can simplify:

-	const agentUrl = HTTPS_PROXY_URL!.replace(
+	const agentUrl = HTTPS_PROXY_URL.replace(
 		'{{geoLocation}}',
 		geoLocation?.toLowerCase() || ''
-	).replace(
+	).replace(
 		'{{proxySessionId}}',
 		proxySessionId ? `-session-${proxySessionId}` : ''
 	)
src/providers/http/index.ts (1)

699-703: Bug: params.getProxySessionId should be params.proxySessionId

This block operates on params.getProxySessionId, but the rest of the file (and the new getProxySessionId helper) consistently use proxySessionId as the parameter name. As previously noted, this will at best be a no-op and at worst a type/lint error, and it means template substitution for proxySessionId never actually runs.

Suggested fix:

-	const proxySessionIdParams = extractAndReplaceTemplateValues(params.getProxySessionId)
-	if(proxySessionIdParams) {
-		params.getProxySessionId = proxySessionIdParams.newParam
-		extractedValues = { ...extractedValues, ...proxySessionIdParams.extractedValues }
-	}
+	const proxySessionIdParams = extractAndReplaceTemplateValues(params.proxySessionId)
+	if(proxySessionIdParams) {
+		params.proxySessionId = proxySessionIdParams.newParam
+		extractedValues = { ...extractedValues, ...proxySessionIdParams.extractedValues }
+	}
🧹 Nitpick comments (1)
src/tests/tcp-tunnel.test.ts (1)

100-153: External IP check is useful but fragile; consider isolating it

The new “same IP using a proxySessionId” test is a good behavioral check for sticky proxy sessions, but it depends on api.ipify.org and real network access, which can make it flaky or slow if this suite is ever un-skipped. Consider either keeping this permanently skipped or moving it to an integration/e2e suite with appropriate guards or mocking.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4cce1d and d283227.

📒 Files selected for processing (6)
  • src/providers/http/index.ts (4 hunks)
  • src/server/tunnels/make-tcp-tunnel.ts (7 hunks)
  • src/server/utils/proxy-session.ts (1 hunks)
  • src/tests/rpc-tunnel.test.ts (3 hunks)
  • src/tests/tcp-tunnel.test.ts (3 hunks)
  • src/types/providers.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/server/utils/proxy-session.ts
  • src/types/providers.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/providers/http/index.ts (2)
src/types/providers.ts (1)
  • ProviderSecretParams (29-29)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-6)
src/server/tunnels/make-tcp-tunnel.ts (3)
src/providers/http/index.ts (2)
  • proxySessionId (57-61)
  • geoLocation (52-56)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-6)
src/utils/error.ts (1)
  • AttestorError (10-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (7)
src/tests/rpc-tunnel.test.ts (2)

33-38: Explicitly passing empty geoLocation/proxySessionId looks fine

Adding geoLocation: '' and proxySessionId: '' to the RPC createTunnel payload keeps the new fields explicit without changing behavior (they’re effectively “unset” values). No issues here.


180-237: Good split of validation coverage between geoLocation and proxySessionId

The two assert.rejects blocks clearly distinguish invalid geoLocation from invalid proxySessionId and correctly await the promises, so TLS tunnel creation failures are now well-covered.

src/tests/tcp-tunnel.test.ts (2)

19-25: Adding proxySessionId to existing geoLocation tests is consistent

Passing proxySessionId: '' alongside existing geoLocation values keeps tests aligned with the new API surface and continues to exercise pure geo-based routing. Once server-side validation treats empty proxy session IDs as “absent”, these tests will remain valid.


88-95: Explicit proxySessionId in restricted-server test is fine

Including proxySessionId: '' here keeps this test aligned with the new tunnel API while preserving the original behavior (no sticky proxy session). No further changes needed.

src/server/tunnels/make-tcp-tunnel.ts (1)

202-209: Good: proxy warning now includes proxySessionId context

Including both geoLocation and proxySessionId in the warning when HTTPS_PROXY_URL is missing will make debugging misconfigured environments much easier, and clearing both fields before falling back to direct connect is a sensible default.

src/providers/http/index.ts (2)

57-61: HTTP provider proxySessionId entry point looks correct

Exposing proxySessionId(params, secretParams) and delegating to getProxySessionId mirrors the existing geoLocation pattern and cleanly plugs into the Provider API. No issues here.


818-847: Proxy session ID resolution and validation are reasonable

getProxySessionId correctly:

  • Resolves {{param}} placeholders from paramValues / secret paramValues.
  • Throws if any referenced template value is missing.
  • Validates the final string via isValidProxySessionId before returning it.

This matches the intended constraints from isValidProxySessionId and aligns with geoLocation handling.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/server/tunnels/make-tcp-tunnel.ts (1)

192-261: Bug: geoLocation validation breaks “proxySessionId-only” usage

Right now, proxy usage requires a valid geoLocation even when only proxySessionId is provided:

  • The guard if(!geoLocation && !proxySessionId) correctly allows proxy when either is present.
  • But immediately after, if(!isValidCountryCode(geoLocation)) runs unconditionally; when geoLocation is empty/undefined and proxySessionId is set, this throws a bad request instead of using the proxy with session-based routing.

This effectively prevents using the proxy with only proxySessionId, which contradicts the intended “either geoLocation or proxySessionId (or both)” behavior.

You can fix this by only validating geoLocation when it’s provided:

-	if(!isValidCountryCode(geoLocation)) {
-		throw AttestorError.badRequest(
-			`Geolocation "${geoLocation}" is invalid. Must be 2 letter ISO country code`,
-			{ geoLocation }
-		)
-	}
+	if(geoLocation && !isValidCountryCode(geoLocation)) {
+		throw AttestorError.badRequest(
+			`Geolocation "${geoLocation}" is invalid. Must be 2 letter ISO country code`,
+			{ geoLocation }
+		)
+	}

This keeps strict validation when geoLocation is supplied, while allowing session-only proxying with a validated proxySessionId.

♻️ Duplicate comments (1)
src/providers/http/index.ts (1)

693-703: Bug (regression): using params.getProxySessionId instead of params.proxySessionId

This block is still operating on a non-existent getProxySessionId field:

const proxySessionIdParams = extractAndReplaceTemplateValues(params.getProxySessionId)
if(proxySessionIdParams) {
	params.getProxySessionId = proxySessionIdParams.newParam
	// ...
}

Issues:

  • HTTPProviderParams exposes proxySessionId, not getProxySessionId, so this is a type error and will never actually update the real proxySessionId value.
  • It also contradicts the usage in getProxySessionId(...), which correctly reads v2Params.proxySessionId.

This was already called out in a previous review; it still needs to be fixed.

Apply this diff to wire template substitution to the correct field:

-	const proxySessionIdParams = extractAndReplaceTemplateValues(params.getProxySessionId)
+	const proxySessionIdParams = extractAndReplaceTemplateValues(params.proxySessionId)
 	if(proxySessionIdParams) {
-		params.getProxySessionId = proxySessionIdParams.newParam
+		params.proxySessionId = proxySessionIdParams.newParam
 		extractedValues = { ...extractedValues, ...proxySessionIdParams.extractedValues }
 	}
🧹 Nitpick comments (1)
src/providers/http/index.ts (1)

818-847: getProxySessionId implementation is correct; consider minor reuse with getGeoLocation

The new getProxySessionId:

  • Resolves {{param}} placeholders against v2Params.paramValues and secretParams.paramValues, with clear erroring on missing values.
  • Validates the final string via isValidProxySessionId before returning.
  • Mirrors the existing getGeoLocation pattern, so behavior is predictable for callers.

If you want to reduce duplication, you could later factor the shared “template resolution” loop used here and in getGeoLocation into a small helper, but that’s non-blocking.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d283227 and cd39003.

📒 Files selected for processing (6)
  • src/providers/http/index.ts (4 hunks)
  • src/server/tunnels/make-tcp-tunnel.ts (7 hunks)
  • src/server/utils/proxy-session.ts (1 hunks)
  • src/tests/rpc-tunnel.test.ts (3 hunks)
  • src/tests/tcp-tunnel.test.ts (3 hunks)
  • src/types/providers.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/server/utils/proxy-session.ts
  • src/types/providers.ts
  • src/tests/tcp-tunnel.test.ts
  • src/tests/rpc-tunnel.test.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/server/tunnels/make-tcp-tunnel.ts (3)
src/utils/logger.ts (1)
  • logger (10-10)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-6)
src/utils/error.ts (1)
  • AttestorError (10-66)
src/providers/http/index.ts (2)
src/types/providers.ts (1)
  • ProviderSecretParams (29-29)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-6)
🔇 Additional comments (3)
src/server/tunnels/make-tcp-tunnel.ts (2)

9-32: Import and documentation updates for proxySessionId look consistent

Using the absolute import #src/server/utils/proxy-session.ts and extending the doc comment to describe proxySessionId’s role in keeping a static proxy IP are both aligned with the rest of the module and the new feature intent; no issues here.


104-152: Plumbing proxySessionId through connectTcp/getSocket is correct

Passing proxySessionId from connectTcp into getSocket (and thus _getSocket) mirrors the existing geoLocation flow, keeps logging intact, and respects the existing timeout/error pattern; the control flow here looks sound.

src/providers/http/index.ts (1)

17-61: HTTP_PROVIDER.proxySessionId surface and validation hook look good

The new proxySessionId(params, secretParams) accessor cleanly mirrors geoLocation, delegating to getProxySessionId and returning undefined when the field is absent. Combined with the dedicated isValidProxySessionId import, this gives a clear, typed entry point for session-based proxy usage.

@predatorx7 predatorx7 changed the title [WIP] Add proxySessionId to provider params for forwarding requests to same… Add proxySessionId to provider params for forwarding requests to same… Dec 5, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/providers/http/index.ts (1)

818-847: getProxySessionId logic is sound; consider small refinements/DRY later.

Implementation correctly:

  • Resolves {{param}} placeholders from paramValues or secretParams.paramValues, and
  • Validates the final value via isValidProxySessionId, throwing on missing or invalid values.

Two optional follow‑ups you might consider (not blocking this PR):

  • Treat empty strings explicitly (either normalizing to undefined or treating them as invalid) rather than relying on the truthiness check in if(v2Params?.proxySessionId).
  • Factor out the shared “resolve template with paramValues + secretParams” pattern used here, in getGeoLocation, and in getURL into a small helper to reduce duplication and keep future changes to templating behavior in one place.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd39003 and 1ea68af.

📒 Files selected for processing (1)
  • src/providers/http/index.ts (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/providers/http/index.ts (2)
src/types/providers.ts (1)
  • ProviderSecretParams (29-29)
src/server/utils/proxy-session.ts (1)
  • isValidProxySessionId (1-6)
🔇 Additional comments (3)
src/providers/http/index.ts (3)

17-17: Import of isValidProxySessionId correctly wires centralized validation.

The import path and usage align with the shared proxy-session validator; no issues here.


57-61: HTTP_PROVIDER.proxySessionId hook is consistent with existing provider API.

The new method mirrors the geoLocation pattern and cleanly delegates to getProxySessionId, returning undefined when the parameter is not present. Looks correct and type-safe.


699-703: Template substitution for proxySessionId is correctly integrated.

Handling proxySessionId in substituteParamValues matches the existing patterns (URL, body, geoLocation): templates are resolved, the field is updated in-place, and extractedValues is merged. This should play well with downstream extraction/redaction logic.

@adiwajshing adiwajshing merged commit 93012f7 into main Dec 5, 2025
2 checks passed
@adiwajshing adiwajshing deleted the same-proxy-ip branch December 5, 2025 11:13
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