Fix API-key login and research navigation

Validate submitted keys against the protected research endpoint instead of the nonexistent versioned health path. Replace server-only redirects in client code with SvelteKit navigation and route successful logins to the existing new-research screen.

Align frontend research history and creation calls with the backend response contract: list items are wrapped in items and new runs return research_id.
This commit is contained in:
faligam
2026-09-06 17:23:11 +02:00
parent c6f1889fe2
commit 8eb0383d48
3 changed files with 13 additions and 12 deletions

View File

@@ -16,7 +16,8 @@ export interface ResearchListItem extends ResearchSummary {
const HISTORY_LIMIT = 50; const HISTORY_LIMIT = 50;
export async function loadResearchHistory(apiKey: string): Promise<ResearchSummary[]> { export async function loadResearchHistory(apiKey: string): Promise<ResearchSummary[]> {
const list = await apiGet<ResearchSummary[]>('/v1/research', { apiKey }); const response = await apiGet<{ items: ResearchSummary[] }>('/v1/research', { apiKey });
const list = response.items;
// Sort descending by created_at (newest first), limit to HISTORY_LIMIT // Sort descending by created_at (newest first), limit to HISTORY_LIMIT
const sorted = list const sorted = list
.slice() .slice()
@@ -34,8 +35,8 @@ export async function createResearch(
query: string, query: string,
language: string, language: string,
depth: string depth: string
): Promise<{ id: string }> { ): Promise<{ research_id: string }> {
return await apiPost<{ id: string }>( return await apiPost<{ research_id: string }>(
'/v1/research', '/v1/research',
{ query, language, depth }, { query, language, depth },
{ apiKey } { apiKey }

View File

@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { redirect } from '@sveltejs/kit'; import { goto } from '$app/navigation';
import { user } from '$lib/stores'; import { user } from '$lib/stores';
import { theme, toggleTheme, applyTheme } from '$lib/theme'; import { theme, toggleTheme, applyTheme } from '$lib/theme';
import { isAuthenticated } from '$lib/auth'; import { isAuthenticated } from '$lib/auth';
@@ -14,7 +14,7 @@
onMount(() => { onMount(() => {
if (isAuthenticated()) { if (isAuthenticated()) {
redirect(302, '/research'); void goto('/research/new');
} }
applyTheme($theme); applyTheme($theme);
}); });
@@ -29,11 +29,12 @@
error = ''; error = '';
try { try {
// Validate the API key by fetching user info from the backend // Validate against a protected endpoint. `/health` is intentionally
const info = await apiGet<any>('/v1/health', { apiKey: apiKey.trim() }); // public and is not versioned; using `/v1/health` caused a 404.
await apiGet('/v1/research', { apiKey: apiKey.trim() });
user.set({ apiKey: apiKey.trim() }); user.set({ apiKey: apiKey.trim() });
localStorage.setItem('nsct-api-key', apiKey.trim()); localStorage.setItem('nsct-api-key', apiKey.trim());
redirect(302, '/research'); await goto('/research/new');
} catch (e) { } catch (e) {
// If the API key is invalid, the backend will return 401/403 // If the API key is invalid, the backend will return 401/403
// or an error response — accept it and show the error // or an error response — accept it and show the error

View File

@@ -1,5 +1,4 @@
<script lang="ts"> <script lang="ts">
import { redirect } from '@sveltejs/kit';
import { isAuthenticated } from '$lib/auth'; import { isAuthenticated } from '$lib/auth';
import { createResearch } from '$lib/sidebar'; import { createResearch } from '$lib/sidebar';
import { errorBanners } from '$lib/components/ErrorBannerStore'; import { errorBanners } from '$lib/components/ErrorBannerStore';
@@ -46,7 +45,7 @@
try { try {
const result = await createResearch(key, query.trim(), language, depth); const result = await createResearch(key, query.trim(), language, depth);
errorBanners.addErrorSuccess('Research wird erstellt…'); errorBanners.addErrorSuccess('Research wird erstellt…');
window.location.href = `/research/${result.id}`; window.location.href = `/research/${result.research_id}`;
} catch (e) { } catch (e) {
const msg = e instanceof Error ? e.message : 'Fehler beim Erstellen der Recherche.'; const msg = e instanceof Error ? e.message : 'Fehler beim Erstellen der Recherche.';
error = msg; error = msg;