Implement better auth flow with direct Authentik redirects

- Create custom /login and /logout endpoints that bypass Auth.js default pages
- Use auto-submitting forms to POST to Auth.js with proper form data
- Update UserHeader links to use new custom endpoints (/login, /logout)
- Remove old login/logout page server files that are no longer needed
- Login flow: /login → auto-submit form → /auth/signin/authentik → Authentik
- Logout flow: /logout → auto-submit form → /auth/signout → Authentik logout
- Provides seamless user experience with loading spinners during redirects
- Maintains all Auth.js security features and session management
- Eliminates intermediate Auth.js pages for cleaner auth flow

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-08-31 21:58:55 +02:00
parent 7f06717615
commit 9b77640977
5 changed files with 72 additions and 8 deletions

View File

@@ -139,10 +139,10 @@ h2 + p{
<p>({user.nickname})</p>
<ul>
<li><a href="https://sso.bocken.org/if/user/#/settings" >Einstellungen</a></li>
<li><a href="/auth/signout" >Log Out</a></li>
<li><a href="/logout" >Log Out</a></li>
</ul>
</div>
</button>
{:else}
<a class=entry href=/auth/signin>Log In</a>
<a class=entry href=/login>Log In</a>
{/if}

View File

@@ -1,3 +0,0 @@
import { signIn } from "../../../auth"
import type { Actions } from "./$types"
export const actions: Actions = { default: signIn }

View File

@@ -1,3 +0,0 @@
import { signIn } from "../../../auth"
import type { Actions } from "./$types"
export const actions: Actions = { default: signIn }

View File

@@ -0,0 +1,35 @@
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async ({ url }) => {
const callbackUrl = url.searchParams.get('callbackUrl') || '/';
// Create an auto-submitting form that POSTs to Auth.js signin
const html = `
<!DOCTYPE html>
<html>
<head>
<title>Redirecting to login...</title>
<style>
body { font-family: system-ui; text-align: center; padding: 2rem; }
.spinner { border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 20px auto; }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
</style>
</head>
<body>
<h2>Redirecting to login...</h2>
<div class="spinner"></div>
<form id="signin-form" method="POST" action="/auth/signin/authentik">
<input type="hidden" name="callbackUrl" value="${callbackUrl}" />
</form>
<script>
document.getElementById('signin-form').submit();
</script>
</body>
</html>`;
return new Response(html, {
headers: {
'Content-Type': 'text/html'
}
});
};

View File

@@ -0,0 +1,35 @@
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async ({ url }) => {
const callbackUrl = url.searchParams.get('callbackUrl') || '/';
// Create an auto-submitting form that POSTs to Auth.js signout
const html = `
<!DOCTYPE html>
<html>
<head>
<title>Signing out...</title>
<style>
body { font-family: system-ui; text-align: center; padding: 2rem; }
.spinner { border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 20px auto; }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
</style>
</head>
<body>
<h2>Signing out...</h2>
<div class="spinner"></div>
<form id="signout-form" method="POST" action="/auth/signout">
<input type="hidden" name="callbackUrl" value="${callbackUrl}" />
</form>
<script>
document.getElementById('signout-form').submit();
</script>
</body>
</html>`;
return new Response(html, {
headers: {
'Content-Type': 'text/html'
}
});
};