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:
@@ -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,10 +35,10 @@ 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 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -111,4 +112,4 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user