feat(auth): implement user authentication with JWT and NextAuth

- Added user registration and login functionality with JWT authentication.
- Created auth controller, service, and module in the backend.
- Implemented user model and user products management.
- Integrated NextAuth for session management on the frontend.
- Added middleware for protecting routes and handling public access.
- Updated frontend API routes to include authorization headers.
- Enhanced recipe and user product models to support ownership and visibility.
- Created registration and login pages in the frontend.
- Added necessary types for NextAuth session management.
This commit is contained in:
Nils-Johan Gynther
2026-04-17 19:57:08 +02:00
parent 4c0411a7f2
commit ce0cc6fbf0
55 changed files with 1006 additions and 137 deletions
+49 -106
View File
@@ -1,6 +1,20 @@
import Link from 'next/link';
import { auth, signOut } from '../auth';
const linkStyle: React.CSSProperties = {
padding: '0.5rem 0.75rem',
background: '#fff',
border: '1px solid #ddd',
borderRadius: '4px',
textDecoration: 'none',
color: '#0070f3',
fontSize: '0.9rem',
fontWeight: 500,
};
export default async function Navigation() {
const session = await auth();
export default function Navigation() {
return (
<nav
style={{
@@ -14,111 +28,40 @@ export default function Navigation() {
alignItems: 'center',
}}
>
<Link
href="/"
style={{
padding: '0.5rem 0.75rem',
background: '#fff',
border: '1px solid #ddd',
borderRadius: '4px',
textDecoration: 'none',
color: '#0070f3',
fontSize: '0.9rem',
fontWeight: 500,
}}
>
🏠 Hem
</Link>
<Link
href="/inventory"
style={{
padding: '0.5rem 0.75rem',
background: '#fff',
border: '1px solid #ddd',
borderRadius: '4px',
textDecoration: 'none',
color: '#0070f3',
fontSize: '0.9rem',
fontWeight: 500,
}}
>
🛒 Varor
</Link>
<Link
href="/recipes"
style={{
padding: '0.5rem 0.75rem',
background: '#fff',
border: '1px solid #ddd',
borderRadius: '4px',
textDecoration: 'none',
color: '#0070f3',
fontSize: '0.9rem',
fontWeight: 500,
}}
>
📖 Recept
</Link>
<Link
href="/baslager"
style={{
padding: '0.5rem 0.75rem',
background: '#fff',
border: '1px solid #ddd',
borderRadius: '4px',
textDecoration: 'none',
color: '#0070f3',
fontSize: '0.9rem',
fontWeight: 500,
}}
>
🏪 Baslager
</Link>
<Link
href="/admin/products"
style={{
padding: '0.5rem 0.75rem',
background: '#fff',
border: '1px solid #ddd',
borderRadius: '4px',
textDecoration: 'none',
color: '#0070f3',
fontSize: '0.9rem',
fontWeight: 500,
}}
>
Admin
</Link>
<Link
href="/import"
style={{
padding: '0.5rem 0.75rem',
background: '#fff',
border: '1px solid #ddd',
borderRadius: '4px',
textDecoration: 'none',
color: '#0070f3',
fontSize: '0.9rem',
fontWeight: 500,
}}
>
📥 Importera
</Link>
<Link
href="/matplan"
style={{
padding: '0.5rem 0.75rem',
background: '#fff',
border: '1px solid #ddd',
borderRadius: '4px',
textDecoration: 'none',
color: '#0070f3',
fontSize: '0.9rem',
fontWeight: 500,
}}
>
📅 Matplan
</Link>
<Link href="/" style={linkStyle}>🏠 Hem</Link>
<Link href="/inventory" style={linkStyle}>🛒 Varor</Link>
<Link href="/recipes" style={linkStyle}>📖 Recept</Link>
<Link href="/baslager" style={linkStyle}>🏪 Baslager</Link>
<Link href="/admin/products" style={linkStyle}> Admin</Link>
<Link href="/import" style={linkStyle}>📥 Importera</Link>
<Link href="/matplan" style={linkStyle}>📅 Matplan</Link>
<span style={{ flex: 1 }} />
{session?.user && (
<>
<span style={{ fontSize: '0.9rem', color: '#555' }}>
👤 {session.user.name}
</span>
<form
action={async () => {
'use server';
await signOut({ redirectTo: '/login' });
}}
>
<button
type="submit"
style={{
...linkStyle,
cursor: 'pointer',
color: '#dc2626',
borderColor: '#dc2626',
}}
>
Logga ut
</button>
</form>
</>
)}
</nav>
);
}