Use Solid Relay for authenticated web workflows - #57
Draft
sij411 wants to merge 9 commits into
Draft
Conversation
- Move GraphQL transport into a SolidStart server function so Relay operations can use the HttpOnly session cookie. - Read the session cookie through SolidStart's H3-backed getCookie helper and forward it to GraphQL as a Bearer token. - Validate that Relay operations contain query text and report unsuccessful HTTP responses. - Build the GraphQL proxy URL from the server request URL rather than a browser location fallback. - Keep Relay environments and stores factory-created so SSR requests do not share cached data. AI provenance: Codex was asked to analyze DrFed's CORS, Nitro proxy, SolidStart server-action, session-cookie, and Solid Relay architecture, and later to help move authentication into the Relay network layer. Codex inspected the relevant frontend and GraphQL code and the Solid Relay mutation guidance, then generated the initial fetchGraphQL server-function split, H3-backed cookie lookup, Bearer authorization handling, and removal of browser credential forwarding. I applied guidance from the Solid Relay maintainer's onboarding example, added operation-text validation and HTTP failure handling, reviewed the Relay environment lifetime, and directed the work incrementally. Codex subsequently replaced the browser location fallback with SolidStart's getRequestURL helper, formatted the file, and ran the focused web TypeScript and formatting checks. I reviewed and understood the implementation and manually verified and wrote error handling, using the methods from the library I chose. Assisted-by: Codex:gpt-5.6-sol
The login-completion action returned the access token to browser JavaScript, which then posted it to the public /session API only to store it as an HttpOnly cookie. This exposed the token before the cookie protection applied and made a public endpoint responsible for accepting client-supplied session credentials. I decided to move the cookie logic from routes/session.ts into a server-only session helper and remove the public /session API. The login-completion action now sets the cookie before returning, so the browser receives only the success or error result. Server-side Relay requests now use the configured GraphQL backend URL instead of deriving it from the incoming public request. This prevents internal GraphQL requests from being routed back through the externally advertised application origin when DrFed runs behind a reverse proxy. AI provenance: I asked Codex to analyze DrFed's session flow and prevent the login access token from passing through browser JavaScript. Codex inspected the login, Relay, GraphQL, and cookie paths; generated the server-only cookie helper; integrated it into login completion; removed the public session route; and corrected Relay's backend URL handling behind a reverse proxy. I directed the work incrementally, decided to replace the public session API with an internal server-only helper, and reviewed the security and Relay environment decisions. I manually verified login, browser cookie creation, and an authenticated viewer query through a reverse-proxied frontend. Focused Oxfmt, Oxlint, and web TypeScript checks passed. Assisted-by: Codex:gpt-5.6-sol
Replace the instance creation server action and its separate Relay environment with Solid Relay createMutation. GraphQL requests continue through the server-only fetch helper, while the form now handles schema and transport errors, mutation progress, and client-side workspace navigation. Remove the unused name input. Add a store-and-network workspace query and an InstanceSummary fragment that render instance hosts after creation. Mark creator memberships as accepted immediately so Account.instances includes newly created instances, and assert the acceptance timestamp in the GraphQL test. Checks: - Ran mise run check. - Ran mise run test, including Relay generation, the production web build, and package tests. - Manually confirmed an unauthenticated mutation displays an authorization error. - Manually signed in over Tailscale, created instances, confirmed the redirect to /workspace/, and confirmed the new hosts appeared there. AI provenance: I asked Codex to review the server-action instance creation flow against the Solid Relay onboarding pattern, convert it to a client mutation, add the workspace refresh and fragment, and diagnose why created instances did not appear after redirecting. Codex implemented the frontend changes, identified that creator memberships remained unaccepted, added the acceptance fix and regression assertion, and ran the automated checks. I chose refetch-on-navigation, removed the unused name field, reviewed the changes step by step, and manually tested authenticated and unauthenticated workflows over Tailscale. Assisted-by: Codex:gpt-5.6-sol
Replace the sign-in server action and its separate Relay environment with Solid Relay createMutation. Submit the form in the browser, derive the verification URL from the public browser origin, and use reactive state for mutation progress and success or error notices. Keep login completion server-side so the bearer access token continues to be written directly to the HttpOnly session cookie without passing through browser JavaScript. Checks: - Regenerated Relay artifacts with relay-compiler. - Ran Oxfmt and Oxlint on the sign-in route. - Ran the @drfed/web TypeScript check. - Manually completed the sign-in workflow through the Tailscale hostname. AI provenance: I asked Codex to analyze which parts of sign-in should use Solid Relay, explain the generated mutation type and error-handling options, review my incremental implementation, and apply the remaining callback and UI state changes. Codex reviewed the implementation, completed the client-side mutation wiring, and ran the focused checks. I chose to keep operation-specific local result state rather than introduce a shared mutation wrapper, reviewed the changes, and manually verified sign-in over Tailscale. Assisted-by: Codex:gpt-5.6-sol
Normalize Relay GraphQL errors before deciding whether login completion failed, so an empty error list is not treated as an error. Simplify the confirmation result type and show a pending message while the server action completes. Keep login completion in a per-request server Relay environment so the returned bearer access token is written directly to the HttpOnly session cookie and is never returned to browser JavaScript. Checks: - Ran Oxfmt and Oxlint on the confirmation route. - Ran the @drfed/web TypeScript check. - Manually completed the sign-in workflow through the Tailscale hostname. AI provenance: I asked Codex to review whether login confirmation could follow the client-side Solid Relay mutation pattern, explain the server-boundary and cache considerations, inspect my cleanup, and add pending feedback. Codex identified the GraphQL error-list edge case, recommended retaining the per-request server action to protect the bearer token, applied the pending output, and ran the focused checks. I simplified the result type, reviewed and formatted the changes, and manually verified sign-in over Tailscale. Assisted-by: Codex:gpt-5.6-sol
Handle createInstance results using Relay’s generated type-name discriminant instead of checking whether individual fields exist. Alias __typename to satisfy lint, handle the future union member, and stop requesting the unused error type. AI provenance: I asked Codex to analyze the inconsistent instance creation error-handling style and explain how the Relay-generated mutation union should be narrowed. Codex identified the field-presence checks and missing future-type handling, suggested switching on an aliased __typename, explained the repository’s switch-case lint requirements, reviewed the final diff, regenerated Relay artifacts, and ran the focused checks. I applied the result-type switch and reviewed the cleanup. Assisted-by: Codex:gpt-5.6-sol
Remove the incomplete actor route because its GraphQL operations are not available yet and its placeholder implementation no longer reflects the current frontend pattern. AI provenance: Codex checked that the placeholder route had no references. I decided on and performed the removal. Assisted-by: Codex:gpt-5.6-sol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification
AI assistance
I used Codex with gpt-5.6-sol to analyze the CORS, proxy, session-cookie, SolidStart server-function, and Solid Relay architecture; review the sign-in, login-confirmation, and instance-creation flows; implement and refine parts of the Relay transport and UI mutations; diagnose creator membership visibility; review error handling; and run checks. I directed the work incrementally, made and revised design decisions, reviewed and modified the implementation, and manually verified the affected workflows in the target environment. The actor-route removal was my decision and implementation; Codex only checked that the placeholder route had no references.
All AI-assisted commits include the required Assisted-by trailers.