feat(phase2): OAuth/Authentik integration + drag-and-drop reordering

- Add OIDC/OAuth2 login via openid-client with PKCE flow
- Auto-provision OAuth users with group mapping
- Conditional login page (OAuth/local/both based on auth mode)
- Admin OAuth test connection button
- Install svelte-dnd-action for board editor DnD
- Draggable sections and widgets with cross-section moves
- Reorder APIs with atomic Prisma transactions
- Visual drag handles and drop zone indicators
This commit is contained in:
2026-03-24 22:54:54 +03:00
parent ae114ab9ce
commit bf4e5089ee
22 changed files with 1273 additions and 257 deletions
+45 -2
View File
@@ -6,6 +6,32 @@
let { form: formData }: { form: SuperValidated<z.infer<typeof updateSystemSettingsSchema>> } = $props();
const { form, errors, enhance, delayed } = superForm(formData);
let oauthTesting = $state(false);
let oauthTestResult = $state('');
let oauthTestSuccess = $state(false);
async function testOAuthConnection() {
oauthTesting = true;
oauthTestResult = '';
oauthTestSuccess = false;
try {
const response = await fetch('/api/admin/oauth/test', { method: 'POST' });
const data = await response.json();
if (response.ok && data.success) {
oauthTestSuccess = true;
oauthTestResult = `Connected to issuer: ${data.issuer}`;
} else {
oauthTestResult = data.error || 'Connection test failed';
}
} catch {
oauthTestResult = 'Network error — could not reach the server';
} finally {
oauthTesting = false;
}
}
</script>
<form method="POST" action="?/update" use:enhance class="space-y-8">
@@ -42,10 +68,12 @@
</div>
</section>
<!-- OAuth (stored but non-functional in MVP) -->
<!-- OAuth Configuration -->
<section class="rounded-lg border border-border bg-card p-6">
<h2 class="mb-4 text-lg font-semibold text-card-foreground">OAuth Configuration</h2>
<p class="mb-4 text-xs text-muted-foreground">OAuth settings are stored but not active in this MVP version.</p>
<p class="mb-4 text-xs text-muted-foreground">
Configure your OIDC provider (e.g. Authentik, Keycloak). Set Auth Mode to "OAuth" or "Both" above to enable OAuth login.
</p>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div>
<label for="oauthClientId" class="mb-1 block text-sm font-medium text-foreground">Client ID</label>
@@ -81,6 +109,21 @@
/>
{#if $errors.oauthDiscoveryUrl}<span class="text-xs text-destructive">{$errors.oauthDiscoveryUrl}</span>{/if}
</div>
<div class="sm:col-span-2">
<button
type="button"
onclick={testOAuthConnection}
disabled={oauthTesting}
class="rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
>
{oauthTesting ? 'Testing...' : 'Test Connection'}
</button>
{#if oauthTestResult}
<span class="ml-3 text-sm {oauthTestSuccess ? 'text-green-600 dark:text-green-400' : 'text-destructive'}">
{oauthTestResult}
</span>
{/if}
</div>
</div>
</section>