Initialize Nuxt.js project with Docker deployment setup

- Add core Nuxt.js application structure with TypeScript
- Include Docker configuration and deployment guide
- Set up project scaffolding with pages, composables, and middleware
- Add environment configuration and Git ignore rules
This commit is contained in:
2025-08-06 14:31:16 +02:00
parent 4ccccde3e4
commit 024d0da617
26 changed files with 1860 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
export default defineEventHandler(async (event) => {
const query = getQuery(event);
const { code, state } = query;
if (!code || !state) {
throw createError({
statusCode: 400,
statusMessage: 'Missing authorization code or state',
});
}
// Verify state
const storedState = getCookie(event, 'oauth-state');
if (state !== storedState) {
throw createError({
statusCode: 400,
statusMessage: 'Invalid state parameter',
});
}
try {
const keycloak = createKeycloakClient();
const sessionManager = createSessionManager();
// Exchange code for tokens
const tokens = await keycloak.exchangeCodeForTokens(code as string);
// Get user info
const userInfo = await keycloak.getUserInfo(tokens.access_token);
// Create session
const sessionData = {
user: {
id: userInfo.sub,
email: userInfo.email,
name: userInfo.name || `${userInfo.given_name} ${userInfo.family_name}`.trim(),
groups: userInfo.groups || [],
tier: userInfo.tier,
},
tokens: {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresAt: Date.now() + (tokens.expires_in * 1000),
},
createdAt: Date.now(),
lastActivity: Date.now(),
};
const sessionCookie = sessionManager.createSession(sessionData);
// Set session cookie
setHeader(event, 'Set-Cookie', sessionCookie);
// Clear state cookie
deleteCookie(event, 'oauth-state');
return sendRedirect(event, '/dashboard');
} catch (error) {
console.error('Auth callback error:', error);
throw createError({
statusCode: 500,
statusMessage: 'Authentication failed',
});
}
});

View File

@@ -0,0 +1,17 @@
import { randomBytes } from 'crypto';
export default defineEventHandler(async (event) => {
const keycloak = createKeycloakClient();
const state = randomBytes(32).toString('hex');
// Store state in session for verification
setCookie(event, 'oauth-state', state, {
httpOnly: true,
secure: true,
maxAge: 600, // 10 minutes
});
const authUrl = keycloak.getAuthUrl(state);
return sendRedirect(event, authUrl);
});

View File

@@ -0,0 +1,8 @@
export default defineEventHandler(async (event) => {
const sessionManager = createSessionManager();
const destroyCookie = sessionManager.destroySession();
setHeader(event, 'Set-Cookie', destroyCookie);
return { success: true };
});

View File

@@ -0,0 +1,19 @@
export default defineEventHandler(async (event) => {
const sessionManager = createSessionManager();
const cookieHeader = getHeader(event, 'cookie');
const session = sessionManager.getSession(cookieHeader);
if (!session) {
return {
authenticated: false,
user: null,
groups: [],
};
}
return {
authenticated: true,
user: session.user,
groups: session.user.groups || [],
};
});