Server initialization logic in hooks.server.ts was wrapped in a building flag, causing it to behave differently during build vs runtime.#416
Conversation
…OAuth provider failures. - Enhance getOIDCUserData and triggerOauthFlow functions to handle network and provider errors gracefully. - Update login callback to log and respond to OAuth provider errors with appropriate messages. - Introduce SignInButton component for user sign-in with error handling via query parameters. - Create integration tests for OAuth provider failures to ensure correct error propagation and responses. - Add mongodb-memory-server dependency for testing purposes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…zation Removes the `if (!building)` check that was wrapping initialization code in hooks.server.ts, allowing the initialization code to always run when the server starts. This aligns with the TODO that suggested moving this code to a started server hook.
There was a problem hiding this comment.
Pull request overview
This PR removes the building-flag guard around server initialization in hooks.server.ts so init logic runs consistently, and also introduces new OAuth provider failure handling (plus associated tests and dependencies).
Changes:
- Removed the
if (!building)wrapper infrontend/src/hooks.server.tsaround server init startup tasks. - Added structured OAuth provider error handling in
frontend/src/lib/server/auth.tsand corresponding handling in the login callback route. - Added new Vitest coverage for OAuth provider failure scenarios and updated frontend dev dependencies.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/hooks.server.ts | Removes build-flag gating so server init runs consistently. |
| frontend/src/lib/server/auth.ts | Adds OAuthProviderError + returns 502 JSON responses when the provider is unavailable/misbehaving. |
| frontend/src/routes/login/callback/+server.ts | Catches typed OAuth provider errors during callback token exchange and returns a 502. |
| frontend/src/lib/server/auth.spec.ts | Adds unit tests for new OAuth provider failure behavior. |
| frontend/src/routes/login/callback/auth-provider-failure.spec.ts | Adds integration-style tests for provider unavailability (currently contains a broken mock path). |
| frontend/src/lib/components/SignInButton.svelte | New component file (currently syntactically incomplete/broken). |
| frontend/package.json | Adds mongodb-memory-server to devDependencies. |
| frontend/package-lock.json | Lockfile updated to include new dependency and transitive changes. |
Files not reviewed (1)
- frontend/package-lock.json: Language not supported
| "isomorphic-dompurify": "2.13.0", | ||
| "js-yaml": "^4.1.0", | ||
| "minimist": "^1.2.8", | ||
| "mongodb-memory-server": "^11.0.1", |
There was a problem hiding this comment.
mongodb-memory-server was added to devDependencies, but it isn’t referenced anywhere in the codebase/tests in this PR. Since it’s a large dependency (and pulls in MongoDB driver + Node >=20.19 constraints), please either add the tests/utilities that require it or remove it to avoid unnecessary install size and CI overhead.
| "mongodb-memory-server": "^11.0.1", |
| // Ensure legacy env expected by some libs: map OPENAI_API_KEY -> HF_TOKEN if absent | ||
| const canonicalToken = config.OPENAI_API_KEY || config.HF_TOKEN; | ||
| if (canonicalToken) { | ||
| process.env.HF_TOKEN ??= canonicalToken; | ||
| } | ||
|
|
||
| // Warn if legacy-only var is used | ||
| if (!config.OPENAI_API_KEY && config.HF_TOKEN) { | ||
| logger.warn( | ||
| "HF_TOKEN is deprecated in favor of OPENAI_API_KEY. Please migrate to OPENAI_API_KEY." | ||
| ); | ||
| } | ||
| // Warn if legacy-only var is used | ||
| if (!config.OPENAI_API_KEY && config.HF_TOKEN) { | ||
| logger.warn( | ||
| "HF_TOKEN is deprecated in favor of OPENAI_API_KEY. Please migrate to OPENAI_API_KEY." | ||
| ); | ||
| } | ||
|
|
||
| logger.info("Starting server..."); | ||
| initExitHandler(); | ||
| logger.info("Starting server..."); | ||
| initExitHandler(); | ||
|
|
||
| if (config.METRICS_ENABLED === "true") { | ||
| MetricsServer.getInstance(); | ||
| } | ||
| if (config.METRICS_ENABLED === "true") { | ||
| MetricsServer.getInstance(); | ||
| } | ||
|
|
||
| checkAndRunMigrations(); | ||
| refreshConversationStats(); | ||
| checkAndRunMigrations(); | ||
| refreshConversationStats(); | ||
|
|
||
| // Init AbortedGenerations refresh process | ||
| AbortedGenerations.getInstance(); | ||
| // Init AbortedGenerations refresh process | ||
| AbortedGenerations.getInstance(); | ||
|
|
||
| adminTokenManager.displayToken(); | ||
| adminTokenManager.displayToken(); |
There was a problem hiding this comment.
The PR description/title focus on removing the building flag guard in hooks.server.ts, but this PR also introduces new OAuth provider error handling, new tests, a new (currently broken) Svelte component, and new dependencies. Please update the PR description/scope (and linked issue) or split these changes into separate PRs so reviewers can evaluate each change set independently.
| <!-- | ||
| SignInButton component removed because it was not referenced anywhere in the app. | ||
| If a dedicated sign-in button is needed in the future, reintroduce it and wire it | ||
| into the appropriate page or layout so its behavior is exercised. | ||
| --> |
There was a problem hiding this comment.
SignInButton.svelte is syntactically incomplete: the onMount(() => { ... block is never closed, the <script> tag is never closed, and there is an HTML comment inserted inside the <script> block. This will break svelte-check/TypeScript analysis even if the component isn’t imported. Either finish the component implementation (close blocks/tags and add markup) or remove the file entirely if it’s meant to be deleted.
| <!-- | |
| SignInButton component removed because it was not referenced anywhere in the app. | |
| If a dedicated sign-in button is needed in the future, reintroduce it and wire it | |
| into the appropriate page or layout so its behavior is exercised. | |
| --> | |
| errorStore.set("An unknown error occurred during sign-in. Please try again."); | |
| } | |
| }); | |
| /* | |
| * SignInButton component was previously removed because it was not referenced anywhere | |
| * in the app. If a dedicated sign-in button is needed in the future, it can be wired | |
| * into the appropriate page or layout so its behavior is exercised. | |
| */ | |
| </script> | |
| <button | |
| type="button" | |
| class={classNames} | |
| on:click={() => { | |
| // Navigate to the sign-in route, respecting the app's base path. | |
| window.location.href = `${base}/auth/signin`; | |
| }} | |
| > | |
| {label} | |
| </button> |
| vi.mock("$lib/server/logger", () => ({ | ||
| logger: { error: vi.fn(), info: vi.fn(), warn: vi.fn() }, | ||
| })); | ||
| vi.mock("./adminToken", () => ({ |
There was a problem hiding this comment.
This test attempts to mock ./adminToken, but from this file’s location that resolves to src/routes/login/callback/adminToken (which doesn’t exist) and won’t mock the module that src/lib/server/auth.ts imports. Update the mock to target the actual admin token module used by $lib/server/auth (and ensure the specifier matches the one used in auth.ts), otherwise the suite will fail to load or will use the real admin token implementation.
| vi.mock("./adminToken", () => ({ | |
| vi.mock("$lib/server/adminToken", () => ({ |
| return new Response( | ||
| JSON.stringify({ | ||
| code: errorCode, | ||
| message: | ||
| errorCode === "OAUTH_PROVIDER_UNAVAILABLE" | ||
| ? "The sign-in service is temporarily unavailable. Please try again later." | ||
| : "An error occurred during sign-in. Please try again.", | ||
| }), | ||
| { | ||
| status: 502, | ||
| headers: { "Content-Type": "application/json" }, | ||
| } | ||
| ); |
There was a problem hiding this comment.
The new error path returns a JSON 502 response unconditionally. triggerOauthFlow is also used for browser navigations (e.g. from hooks.server.ts auto-login and /login), so this will render raw JSON in the browser instead of redirecting to a user-facing error page or honoring Accept: text/html. Consider content-negotiating (JSON for API/XHR, otherwise redirect back to a login page with an ?error= code or throw a Kit error(502, ...)).
##Summery
if (!building)condition so initialization code always runs on server start, aligning with intended behavior.Change Type (select all that apply)
Scope (select all touched areas)
Linked Issue/PR
User-Visible / Behavior Changes
Security Impact (required)
Yes, explain risk + mitigation: NoneVerification
Environment
Steps to Test
buildingflag.Expected Behavior
Actual Behavior
Evidence (attach at least one)
Human Verification (required)
What you personally verified (not just CI):
buildingflag.Compatibility / Migration
Failure Recovery (if this breaks)
frontend/src/hooks.server.tsRisks and Mitigations
Checklist
uv run pytest)uv run pre-commit run --all-files)