diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d8167c..fa22455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed +- Fixed TypeScript build error in `frontend/src/app/accounts/page.tsx`: replaced non-existent `account.username` with `account.email_address`, `account.last_checked_at` with `account.last_check_at`, and `account.last_error` with `account.last_error_message` (the backend intentionally excludes `username` from API responses for security) +- Fixed TypeScript error in `frontend/src/app/auth/callback/page.tsx`: `TokenResponse` doesn't include `user`; now fetches user via `userApi.getCurrentUser()` after OAuth token exchange +- Fixed TypeScript errors in `frontend/src/app/dashboard/page.tsx`: replaced non-existent `errors_count` with `emails_failed` on `ProcessingRun` +- Fixed TypeScript errors in `frontend/src/components/AddMailAccountModal.tsx`: removed invalid `account.username` access, added missing required fields to initial form state, and fixed autoDetect suggestions access +- Made `email_address`, `use_tls`, `forward_to` optional in the `MailAccountCreate` TypeScript interface to align with form usage +- Added typed suggestion fields to `autoDetect` return type in `api.ts` +- Excluded test files (`*.test.ts`, `*.spec.ts`) from TypeScript compilation in `tsconfig.json` - Upgraded Node.js base image in `frontend/Dockerfile` from `node:18-alpine` to `node:20-alpine` to satisfy the Node.js >= 20.9.0 requirement for Next.js and fix Docker build failures - Removed `actions/attest-build-provenance` step and associated `id-token: write` / `attestations: write` permissions from the CI `build` job — this action is not available for private user-owned repositories and caused every build to fail - Downgraded `eslint` from `^10` to `^9` in the frontend to resolve `TypeError: contextOrFilename.getFilename is not a function` caused by ESLint 10 removing the `getFilename()` API used by `eslint-plugin-react` bundled in `eslint-config-next` diff --git a/frontend/src/app/accounts/page.tsx b/frontend/src/app/accounts/page.tsx index 95dda97..0a69fe8 100644 --- a/frontend/src/app/accounts/page.tsx +++ b/frontend/src/app/accounts/page.tsx @@ -77,7 +77,7 @@ export default function AccountsPage() {

{account.name}

-

{account.username}

+

{account.email_address}

{account.is_enabled ? ( @@ -113,17 +113,17 @@ export default function AccountsPage() {
- {account.last_checked_at && ( + {account.last_check_at && (
- Last checked: {new Date(account.last_checked_at).toLocaleString()} + Last checked: {new Date(account.last_check_at).toLocaleString()}
)} - {account.last_error && ( + {account.last_error_message && (
-

{account.last_error}

+

{account.last_error_message}

)} diff --git a/frontend/src/app/auth/callback/page.tsx b/frontend/src/app/auth/callback/page.tsx index 165fb70..59aeb3c 100644 --- a/frontend/src/app/auth/callback/page.tsx +++ b/frontend/src/app/auth/callback/page.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; -import { authApi } from '@/lib/api'; +import { authApi, userApi } from '@/lib/api'; import { useAuthStore } from '@/store/authStore'; import { Loader2, CheckCircle, XCircle } from 'lucide-react'; @@ -37,8 +37,9 @@ export default function AuthCallbackPage() { const response = await authApi.googleAuth(code, redirectUri); localStorage.setItem('access_token', response.access_token); - localStorage.setItem('user', JSON.stringify(response.user)); - setUser(response.user); + const user = response.user ? response.user : await userApi.getCurrentUser(); + localStorage.setItem('user', JSON.stringify(user)); + setUser(user); setStatus('success'); setMessage('Authentication successful! Redirecting...'); diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx index 8eb9b11..31036c0 100644 --- a/frontend/src/app/dashboard/page.tsx +++ b/frontend/src/app/dashboard/page.tsx @@ -63,7 +63,7 @@ export default function DashboardPage() { return new Date(r.started_at).toDateString() === today; }) .reduce((sum, r) => sum + r.emails_forwarded, 0) || 0, - errors: runs?.filter((r) => r.errors_count > 0).length || 0, + errors: runs?.filter((r) => r.emails_failed > 0).length || 0, }; return ( @@ -166,8 +166,8 @@ export default function DashboardPage() { {run.emails_forwarded} - {run.errors_count > 0 ? ( - {run.errors_count} + {run.emails_failed > 0 ? ( + {run.emails_failed} ) : ( 0 )} diff --git a/frontend/src/components/AddMailAccountModal.tsx b/frontend/src/components/AddMailAccountModal.tsx index cea66d4..d73054f 100644 --- a/frontend/src/components/AddMailAccountModal.tsx +++ b/frontend/src/components/AddMailAccountModal.tsx @@ -25,7 +25,7 @@ export function AddMailAccountModal({ account, onClose }: AddMailAccountModalPro protocol: account?.protocol || 'pop3', host: account?.host || '', port: account?.port || 995, - username: account?.username || '', + username: '', password: '', use_ssl: account?.use_ssl ?? true, check_interval_minutes: account?.check_interval_minutes || 5, @@ -70,14 +70,17 @@ export function AddMailAccountModal({ account, onClose }: AddMailAccountModalPro setAutoDetecting(true); try { - const settings = await mailAccountsApi.autoDetect(formData.username); - setFormData((prev) => ({ - ...prev, - protocol: settings.protocol || prev.protocol, - host: settings.host || prev.host, - port: settings.port || prev.port, - use_ssl: settings.use_ssl ?? prev.use_ssl, - })); + const result = await mailAccountsApi.autoDetect(formData.username); + const suggestion = result.success && result.suggestions.length > 0 ? result.suggestions[0] : null; + if (suggestion) { + setFormData((prev) => ({ + ...prev, + protocol: suggestion.protocol || prev.protocol, + host: suggestion.host || prev.host, + port: suggestion.port || prev.port, + use_ssl: suggestion.use_ssl ?? prev.use_ssl, + })); + } alert('Settings auto-detected successfully!'); } catch { alert('Failed to auto-detect settings. Please enter manually.'); diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 41f5d8e..d115988 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -82,15 +82,15 @@ export interface MailAccount { export interface MailAccountCreate { name: string; - email_address: string; + email_address?: string; protocol: string; host: string; port: number; use_ssl: boolean; - use_tls: boolean; + use_tls?: boolean; username: string; password: string; - forward_to: string; + forward_to?: string; delivery_method?: string; is_enabled?: boolean; check_interval_minutes?: number; @@ -111,10 +111,19 @@ export interface ProcessingRun { error_message?: string | null; } +export interface AutoDetectSuggestion { + protocol?: string; + host?: string; + port?: number; + use_ssl?: boolean; + [key: string]: unknown; +} + interface TokenResponse { access_token: string; refresh_token: string; token_type: string; + user?: User; } // ── Auth API ──────────────────────────────────────────────────────────── @@ -215,10 +224,10 @@ export const mailAccountsApi = { async autoDetect( emailAddress: string - ): Promise<{ success: boolean; suggestions: Record[] }> { + ): Promise<{ success: boolean; suggestions: AutoDetectSuggestion[] }> { const response = await api.post<{ success: boolean; - suggestions: Record[]; + suggestions: AutoDetectSuggestion[]; }>("/mail-accounts/auto-detect", { email_address: emailAddress }); return response.data; }, diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index cf9c65d..39993f0 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -30,5 +30,5 @@ ".next/dev/types/**/*.ts", "**/*.mts" ], - "exclude": ["node_modules"] + "exclude": ["node_modules", "**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx"] }