Skip to content

fix: keep optional impersonation in URL builder query strings - #1912

Merged
ChiragAgg5k merged 3 commits into
mainfrom
fix/location-impersonation
Sep 17, 2026
Merged

ChiragAgg5k merged 3 commits into
mainfrom
fix/location-impersonation

Conversation

@ChiragAgg5k

@ChiragAgg5k ChiragAgg5k commented Sep 17, 2026

Copy link
Copy Markdown
Member

Summary

After #1891, Console SDK URL builders (getFileDownload, getFilePreview, getFileView, every avatar method, deployment downloads, invoice view/download) stopped appending impersonateuserid. The browser then fetched those URLs as the impersonator and the server correctly answered 401.

The server-ce formatter now emits two security alternatives for a location method: the base auth, and the base auth plus the location keys. That makes ImpersonateUserId accepted but not required. #1891 taught getOperationAuthSchemes to skip accepted-minus-required schemes so that examples do not configure optional credentials. The same method backs the securitySchemes Twig filter that location and webAuth templates use to build their query string, and a URL builder has no request to carry headers, so the skip removed the credential rather than trimming an example.

Change

  • getOperationAuthSchemes takes an includeOptional flag. A new locationSchemes filter passes true; securitySchemes keeps the optional skip for examples.
  • The seven payload templates that build URL-builder or OAuth query strings (web, react-native, dart, flutter, swift, android, dotnet) switch to locationSchemes. The 17 docs example templates are untouched.
  • Fixture: the download route gains the second security alternative the real formatter emits, so the fixture reproduces the defect.

Tests

Web E2E (Node and Chromium). The scripts build the download URL twice, once without and once with setImpersonateUserId('impersonated'), and open each URL with fetch. The mock endpoint now accepts project and impersonateuserid from the query string, as the real API does for a browser navigation, and echoes the impersonated user. Expected output gains two lines:

GET:/v1/mock/tests/general/download:passed
GET:/v1/mock/tests/general/download:passed:as:impersonated

Against the pre-fix generator the second line comes back without :as:impersonated and the test fails. With the fix both variants pass.

Generation suite. testExampleCredentialsFollowPlatformAuth also checks the PHP client example for the same route still does not call setImpersonateUserId, so the optional skip for examples is pinned alongside the query-string behaviour.

Generated output, before vs after

Web SDK, client platform, from the test fixture. This is the only hunk in the whole tree:

--- before/src/services/general.ts
+++ after/src/services/general.ts
@@ -319,6 +319,7 @@
         const uri = new URL(this.client.config.endpoint + apiPath);

         payload['project'] = this.client.config.project;
+        payload['impersonateuserid'] = this.client.config.impersonateuserid;

         for (const [key, value] of Object.entries(Service.flatten(payload))) {
             uri.searchParams.append(key, value);

Node SDK, server platform, same fixture: no difference in any file. Node performs a real request for location methods and sends the header, so it was never affected, and its docs examples still omit the optional credential.

Verification

  • WebNodeTest and WebChromiumTest pass locally against the mock server; WebNodeTest fails when src/SDK/SDK.php and the templates are reset to main.
  • Generation suite: 87 tests, 1135 assertions, 4 pre-existing skips.
  • phpcs and Rector dry-run clean on the changed PHP files; djlint clean on the seven changed templates. The repo-wide composer lint and composer refactor:check failures are pre-existing on main and unchanged by this PR.

Rollout

Release the generator, then regenerate and publish the Console SDK and bump it in Console. No producer or Cloud change is needed; the spec is correct as published.

The optional-security migration made the securitySchemes filter drop any
scheme that is accepted but not required, so example snippets stop
configuring optional credentials. The same filter builds the query string
of location and webAuth methods, and a URL builder has no request to carry
headers, so dropping ImpersonateUserId there removed the credential rather
than trimming an example. Console download, preview and avatar URLs were
sent as the impersonator and returned 401.

Give payload templates their own locationSchemes filter that keeps every
scheme x-appwrite.auth lists; examples keep skipping the optional ones.
@greptile-apps

greptile-apps Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The functional change appears safe to merge, although the unresolved non-blocking generated-source assertion should still be replaced with an observable documentation-generation check.

Fix All in Claude CodeFindings

  1. P2 Test Mirrors Generated Source
Fix with agent prompt
### Issue 1
tests/generation/GenerationTest.php:undefined-310
The added `download.md` case checks exact generated setter strings such as `->setproject(` and `->setimpersonateuserid(`. This violates the repository directive to test observable behavior instead of mirroring source code: harmless formatting or API-expression changes can break the test without changing behavior, while the assertion does not show that the example actually configures only the intended credentials. This repository requirement must be satisfied before merging by replacing the string-matching case with an observable example-generation or execution check.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

The PR separates location-method credential selection from documentation-example credential selection so optional impersonation credentials remain in generated URL query strings while examples continue to omit them.

  • Adds a locationSchemes Twig filter that includes optional authentication schemes.
  • Updates URL-builder and OAuth templates across supported SDK targets.
  • Adds Web Node and Chromium behavioral coverage for URLs with and without impersonation.
  • Extends the fixture and mock endpoint to model query-string credentials.
  • The previously reported implementation-coupled documentation assertion remains unchanged and unresolved.

Reviews (3) · Last reviewed commit: "test: trim mock comments"

Comment thread tests/generation/GenerationTest.php Outdated
The generation suite asserted on the emitted TypeScript, which mirrors the
template rather than the behaviour. Open the built URL against the mock
instead: the mock now accepts credentials from the query string, as the
real API does for browser navigations, and echoes the impersonated user so
the Web E2E fails when the parameter is missing.
Comment thread tests/generation/GenerationTest.php
@ChiragAgg5k

Copy link
Copy Markdown
Member Author

@greptile review

@ChiragAgg5k
ChiragAgg5k merged commit 3aa71b6 into main Sep 17, 2026
59 checks passed
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