Initial commit

This commit is contained in:
Jarek Krochmalski
2025-12-28 21:16:03 +01:00
commit 62e3c6439e
552 changed files with 104858 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from '@sveltejs/kit';
import { authorize } from '$lib/server/authorize';
import {
getOidcConfig,
updateOidcConfig,
deleteOidcConfig
} from '$lib/server/db';
// GET /api/auth/oidc/[id] - Get specific OIDC configuration
export const GET: RequestHandler = async ({ params, cookies }) => {
const auth = await authorize(cookies);
// When auth is enabled, require authentication and settings:view permission
if (auth.authEnabled) {
if (!auth.isAuthenticated) {
return json({ error: 'Authentication required' }, { status: 401 });
}
if (!await auth.can('settings', 'view')) {
return json({ error: 'Permission denied' }, { status: 403 });
}
}
const id = parseInt(params.id || '');
if (isNaN(id)) {
return json({ error: 'Invalid configuration ID' }, { status: 400 });
}
try {
const config = await getOidcConfig(id);
if (!config) {
return json({ error: 'OIDC configuration not found' }, { status: 404 });
}
return json({
...config,
clientSecret: config.clientSecret ? '********' : ''
});
} catch (error) {
console.error('Failed to get OIDC config:', error);
return json({ error: 'Failed to get OIDC configuration' }, { status: 500 });
}
};
// PUT /api/auth/oidc/[id] - Update OIDC configuration
export const PUT: RequestHandler = async ({ params, request, cookies }) => {
const auth = await authorize(cookies);
// When auth is enabled, require authentication and settings:edit permission
if (auth.authEnabled) {
if (!auth.isAuthenticated) {
return json({ error: 'Authentication required' }, { status: 401 });
}
if (!await auth.can('settings', 'edit')) {
return json({ error: 'Permission denied' }, { status: 403 });
}
}
const id = parseInt(params.id || '');
if (isNaN(id)) {
return json({ error: 'Invalid configuration ID' }, { status: 400 });
}
try {
const existing = await getOidcConfig(id);
if (!existing) {
return json({ error: 'OIDC configuration not found' }, { status: 404 });
}
const data = await request.json();
// Don't update clientSecret if it's the masked value
const updateData: any = {};
if (data.name !== undefined) updateData.name = data.name;
if (data.enabled !== undefined) updateData.enabled = data.enabled;
if (data.issuerUrl !== undefined) updateData.issuerUrl = data.issuerUrl;
if (data.clientId !== undefined) updateData.clientId = data.clientId;
if (data.clientSecret !== undefined && data.clientSecret !== '********') {
updateData.clientSecret = data.clientSecret;
}
if (data.redirectUri !== undefined) updateData.redirectUri = data.redirectUri;
if (data.scopes !== undefined) updateData.scopes = data.scopes;
if (data.usernameClaim !== undefined) updateData.usernameClaim = data.usernameClaim;
if (data.emailClaim !== undefined) updateData.emailClaim = data.emailClaim;
if (data.displayNameClaim !== undefined) updateData.displayNameClaim = data.displayNameClaim;
if (data.adminClaim !== undefined) updateData.adminClaim = data.adminClaim;
if (data.adminValue !== undefined) updateData.adminValue = data.adminValue;
if (data.roleMappingsClaim !== undefined) updateData.roleMappingsClaim = data.roleMappingsClaim;
if (data.roleMappings !== undefined) updateData.roleMappings = data.roleMappings;
const config = await updateOidcConfig(id, updateData);
if (!config) {
return json({ error: 'Failed to update OIDC configuration' }, { status: 500 });
}
return json({
...config,
clientSecret: config.clientSecret ? '********' : ''
});
} catch (error: any) {
console.error('Failed to update OIDC config:', error);
return json({ error: error.message || 'Failed to update OIDC configuration' }, { status: 500 });
}
};
// DELETE /api/auth/oidc/[id] - Delete OIDC configuration
export const DELETE: RequestHandler = async ({ params, cookies }) => {
const auth = await authorize(cookies);
// When auth is enabled, require authentication and settings:edit permission
if (auth.authEnabled) {
if (!auth.isAuthenticated) {
return json({ error: 'Authentication required' }, { status: 401 });
}
if (!await auth.can('settings', 'edit')) {
return json({ error: 'Permission denied' }, { status: 403 });
}
}
const id = parseInt(params.id || '');
if (isNaN(id)) {
return json({ error: 'Invalid configuration ID' }, { status: 400 });
}
try {
const deleted = await deleteOidcConfig(id);
if (!deleted) {
return json({ error: 'OIDC configuration not found' }, { status: 404 });
}
return json({ success: true });
} catch (error) {
console.error('Failed to delete OIDC config:', error);
return json({ error: 'Failed to delete OIDC configuration' }, { status: 500 });
}
};

View File

@@ -0,0 +1,77 @@
import { json, redirect } from '@sveltejs/kit';
import type { RequestHandler } from '@sveltejs/kit';
import { buildOidcAuthorizationUrl, isAuthEnabled } from '$lib/server/auth';
import { getOidcConfig } from '$lib/server/db';
// GET /api/auth/oidc/[id]/initiate - Start OIDC authentication flow
export const GET: RequestHandler = async ({ params, url }) => {
// Check if auth is enabled
if (!isAuthEnabled()) {
return json({ error: 'Authentication is not enabled' }, { status: 400 });
}
const id = parseInt(params.id || '');
if (isNaN(id)) {
return json({ error: 'Invalid configuration ID' }, { status: 400 });
}
// Get redirect URL from query params
const redirectUrl = url.searchParams.get('redirect') || '/';
try {
const config = await getOidcConfig(id);
if (!config || !config.enabled) {
return json({ error: 'OIDC provider not found or disabled' }, { status: 404 });
}
const result = await buildOidcAuthorizationUrl(id, redirectUrl);
if ('error' in result) {
return json({ error: result.error }, { status: 500 });
}
// Redirect to the IdP
throw redirect(302, result.url);
} catch (error: any) {
// Re-throw redirect
if (error.status === 302) {
throw error;
}
console.error('Failed to initiate OIDC:', error);
return json({ error: error.message || 'Failed to initiate SSO' }, { status: 500 });
}
};
// POST /api/auth/oidc/[id]/initiate - Get authorization URL without redirect
export const POST: RequestHandler = async ({ params, request }) => {
// Check if auth is enabled
if (!isAuthEnabled()) {
return json({ error: 'Authentication is not enabled' }, { status: 400 });
}
const id = parseInt(params.id || '');
if (isNaN(id)) {
return json({ error: 'Invalid configuration ID' }, { status: 400 });
}
try {
const body = await request.json().catch(() => ({}));
const redirectUrl = body.redirect || '/';
const config = await getOidcConfig(id);
if (!config || !config.enabled) {
return json({ error: 'OIDC provider not found or disabled' }, { status: 404 });
}
const result = await buildOidcAuthorizationUrl(id, redirectUrl);
if ('error' in result) {
return json({ error: result.error }, { status: 500 });
}
return json({ url: result.url });
} catch (error: any) {
console.error('Failed to get OIDC authorization URL:', error);
return json({ error: error.message || 'Failed to initiate SSO' }, { status: 500 });
}
};

View File

@@ -0,0 +1,28 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from '@sveltejs/kit';
import { validateSession, testOidcConnection, isAuthEnabled } from '$lib/server/auth';
// POST /api/auth/oidc/[id]/test - Test OIDC connection
export const POST: RequestHandler = async ({ params, cookies }) => {
// When auth is disabled, allow access (for initial setup)
// When auth is enabled, require admin
if (isAuthEnabled()) {
const user = await validateSession(cookies);
if (!user || !user.isAdmin) {
return json({ error: 'Admin access required' }, { status: 403 });
}
}
const id = parseInt(params.id || '');
if (isNaN(id)) {
return json({ error: 'Invalid configuration ID' }, { status: 400 });
}
try {
const result = await testOidcConnection(id);
return json(result);
} catch (error: any) {
console.error('Failed to test OIDC connection:', error);
return json({ success: false, error: error.message || 'Test failed' }, { status: 500 });
}
};