Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
WalkthroughThis pull request adds nine new image cache entries to Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryThis PR adds a new tutorial blog post titled "Build a notes app with user impersonation," along with nine supporting screenshots and the corresponding image cache entries. The post walks readers through setting up an Appwrite project, enabling the impersonator capability for a user, and building a React + TypeScript notes app that demonstrates the The content is well-written, logically structured, and consistent with the companion announcement post. Two minor issues were found:
Confidence Score: 5/5
Important Files Changed
|
| - **Each operator should have their own account.** Do not share a single impersonator login across a team. Individual accounts make audit trails meaningful. | ||
| - **Only grant the capability to users who need it.** The impersonator flag gives broad access. Treat it like an admin privilege. | ||
| - **A real user session is required.** An API key alone cannot trigger impersonation. The operator must authenticate first. | ||
| - **Always show the impersonation state in the UI.** Use the `impersonatorUserId` field from `account.get()` to detect active impersonation and display a clear banner. |
There was a problem hiding this comment.
Security guidance inconsistent with tutorial code
The security consideration advises readers to use the impersonatorUserId field from account.get() to detect active impersonation. However, the tutorial code tracks the impersonation state via a React component state variable (isImpersonating) set when impersonate() is called, not by reading impersonatorUserId from the response.
The two approaches serve slightly different purposes:
- The component state approach only works for the operator's own UI session.
- Checking
impersonatorUserIdon the result ofaccount.get()is the reliable, SDK-native way that also works in scenarios where the impersonation state might be initialised from an existing session on page load.
Consider updating the impersonate() function snippet to show reading impUser.impersonatorUserId for banner detection, which would both demonstrate the recommended pattern and keep the advice consistent with the shown code.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/routes/blog/post/user-impersonation-tutorial/+page.markdoc (1)
154-173: Consider adding error handling guidance.The session detection code has a try-catch block that silently swallows errors with a comment "No active session." While this works for the demo, consider briefly mentioning in the tutorial what errors might occur and how to handle them in production.
For example:
- Permission errors if impersonator capability is incorrectly configured
- Network errors during the listUsers call
- Invalid user ID errors during impersonation
This would help developers adapt the code for production use where error messaging and logging are important.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/routes/blog/post/user-impersonation-tutorial/`+page.markdoc around lines 154 - 173, Update the try-catch in the useEffect/checkSession flow to capture the caught error (catch (err)) and surface it instead of silently ignoring it: log the error via your logger or console, set a user-visible error state (e.g., setError) so the UI can display a friendly message, and handle specific failure cases from account.get, listUsers, and fetchNotes (inspect err.message or err.code to treat permission errors, network failures, and invalid user-id errors differently — show permission-denied text for impersonator misconfiguration, retry or prompt on network errors, and validate user IDs before calling impersonation). Also update the tutorial text around checkSession to briefly describe these production-handling strategies (permission, network, invalid ID) and recommend logging and user-facing messages..optimize-cache.json (1)
1059-1059: Remove unused image from cache.The
demo-login.pngcache entry is not referenced in the blog post markdown. All other images in this set are used within the tutorial content, but this one remains orphaned in the cache. Removing it will keep the cache lean and avoid storing hash values for unused resources.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.optimize-cache.json at line 1059, Remove the orphaned image cache entry "images/blog/user-impersonation-tutorial/demo-login.png" from .optimize-cache.json by deleting its key/value pair (the line containing that path and hash) and adjust the surrounding commas so the JSON remains valid; verify no references to that image exist in the blog post markdown and run any cache validation/lint step you use to ensure the file parses correctly after removal.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/routes/blog/post/user-impersonation-tutorial/`+page.markdoc:
- Line 182: Remove the non-existent client.setImpersonateUserId call and replace
the flow with the Server SDK Users service: use Users.createSession(userId, /*
credentials */) or Users.createJWT(userId) on the server to generate a session
ID or JWT, return that to the client, and then call client.setSession(sessionId)
or client.setJWT(jwt) on the Client instance; update the tutorial text and the
code examples that reference client.setImpersonateUserId (and the related line
at 189) to demonstrate users.createSession/users.createJWT on the server and
client.setSession/client.setJWT on the browser client instead.
---
Nitpick comments:
In @.optimize-cache.json:
- Line 1059: Remove the orphaned image cache entry
"images/blog/user-impersonation-tutorial/demo-login.png" from
.optimize-cache.json by deleting its key/value pair (the line containing that
path and hash) and adjust the surrounding commas so the JSON remains valid;
verify no references to that image exist in the blog post markdown and run any
cache validation/lint step you use to ensure the file parses correctly after
removal.
In `@src/routes/blog/post/user-impersonation-tutorial/`+page.markdoc:
- Around line 154-173: Update the try-catch in the useEffect/checkSession flow
to capture the caught error (catch (err)) and surface it instead of silently
ignoring it: log the error via your logger or console, set a user-visible error
state (e.g., setError) so the UI can display a friendly message, and handle
specific failure cases from account.get, listUsers, and fetchNotes (inspect
err.message or err.code to treat permission errors, network failures, and
invalid user-id errors differently — show permission-denied text for
impersonator misconfiguration, retry or prompt on network errors, and validate
user IDs before calling impersonation). Also update the tutorial text around
checkSession to briefly describe these production-handling strategies
(permission, network, invalid ID) and recommend logging and user-facing
messages.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5dd585da-90b8-44c0-9af5-3a6cac237b6b
⛔ Files ignored due to path filters (9)
static/images/blog/user-impersonation-tutorial/cover.pngis excluded by!**/*.pngstatic/images/blog/user-impersonation-tutorial/demo-dashboard.pngis excluded by!**/*.pngstatic/images/blog/user-impersonation-tutorial/demo-impersonating-note.pngis excluded by!**/*.pngstatic/images/blog/user-impersonation-tutorial/demo-impersonating.pngis excluded by!**/*.pngstatic/images/blog/user-impersonation-tutorial/demo-login.pngis excluded by!**/*.pngstatic/images/blog/user-impersonation-tutorial/demo-users.pngis excluded by!**/*.pngstatic/images/blog/user-impersonation-tutorial/impersonator-toggle.pngis excluded by!**/*.pngstatic/images/blog/user-impersonation-tutorial/project-overview.pngis excluded by!**/*.pngstatic/images/blog/user-impersonation-tutorial/table-permissions.pngis excluded by!**/*.png
📒 Files selected for processing (2)
.optimize-cache.jsonsrc/routes/blog/post/user-impersonation-tutorial/+page.markdoc
|
|
||
| ```tsx | ||
| const impersonate = async (userId: string) => { | ||
| client.setImpersonateUserId(userId); |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
What is the correct API for user impersonation in the Appwrite Client SDK? Does client.setImpersonateUserId() exist, and what are the correct parameters?
💡 Result:
The correct API for user impersonation in Appwrite is through the Server SDKs (not Client SDKs), using the Users service to generate a session or JWT for the target user, typically after enabling an "impersonator" capability on users via the Console or Users API. This allows admins/trusted operators to act as another user for debugging/support without sharing credentials. Recent feature (announced March 2026). client.setImpersonateUserId does not exist in Appwrite Client SDKs. Client SDKs use Account service for user authentication (createSession, createJWT), but impersonation requires Server SDK with API key. Correct flow (Server SDK example, Node.js): 1. Use Users service (with API key) to create a session for the target userId: users.createSession(userId) 2. Use the returned session ID with Client SDK: client.setSession(sessionId) to make calls as that user. Or generate JWT: users.createJWT(userId) then client.setJWT(jwt). Parameters: userId (string, required). Client SDKs cannot impersonate directly; use Server SDK to generate user-specific session/JWT, then set on Client instance. Respects user permissions unlike API keys. No direct client.setImpersonateUserId; method not found in docs/SDK references.
Citations:
- 1: https://appwrite.io/blog/post/announcing-user-impersonation
- 2: https://appwrite.io/changelog/entry/2026-03-14
- 3: https://appwrite.io/blog/post/appwrite-server-sdk-vs-client-sdk
- 4: https://appwrite.io/docs/server/users?sdk=nodejs
- 5: https://appwrite.io/docs/products/auth/users
- 6: https://appwrite.io/threads/1100734700814872637
- 7: https://appwrite.io/docs/server/users
- 8: https://appwrite.io/docs/products/auth/jwt
Remove client.setImpersonateUserId() — this method does not exist in Appwrite Client SDKs.
User impersonation is only available in Server SDKs. The correct approach is to use the Server SDK's Users service to create a session or JWT for the target user, then use client.setSession(sessionId) or client.setJWT(jwt) on the Client instance. The tutorial should demonstrate the Server SDK flow: users.createSession(userId) to generate a session, then pass the returned session ID to the Client instance.
This affects lines 182 and 189 where the non-existent method is called.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/routes/blog/post/user-impersonation-tutorial/`+page.markdoc at line 182,
Remove the non-existent client.setImpersonateUserId call and replace the flow
with the Server SDK Users service: use Users.createSession(userId, /*
credentials */) or Users.createJWT(userId) on the server to generate a session
ID or JWT, return that to the client, and then call client.setSession(sessionId)
or client.setJWT(jwt) on the Client instance; update the tutorial text and the
code examples that reference client.setImpersonateUserId (and the related line
at 189) to demonstrate users.createSession/users.createJWT on the server and
client.setSession/client.setJWT on the browser client instead.
Summary by CodeRabbit