Fixes: 1. useFetch: add credentials:'same-origin' — cookie wasn't being sent with API calls, causing 401 → React error boundary → 'Etwas ist schiefgelaufen' 2. Instance detail Sheet now loads correctly (cookie sent with request) New instance actions (UI + API): - Redeploy: triggers Dokploy application.redeploy (rebuilds from latest commit) - Stop: triggers Dokploy application.stop (pauses container) - Start: triggers Dokploy application.start (resumes container) - Remove: existing delete (SlideCommit confirmation) Dokploy deploy fix: - deployApplication now calls markRunning before deploy - This ensures Dokploy creates a deployment job ActionsRow redesigned: - demo_active/active: [Redeploy] [Stop] [Demo +7d] [Remove] - grace: [Start] [Remove] - failed: [Retry] [Remove] - provisioning/deleting/deleted: no actions
65 lines
1.9 KiB
TypeScript
Executable File
65 lines
1.9 KiB
TypeScript
Executable File
import { NextResponse } from 'next/server'
|
|
import { z } from 'zod'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
const schema = z.object({
|
|
password: z.string().min(1),
|
|
redirect: z.string().optional(),
|
|
})
|
|
|
|
// POST /api/auth/login
|
|
// Simple password-based auth. Password is set via ADMIN_PASSWORD env var.
|
|
// Returns a session cookie (HMAC-signed, 7-day expiry).
|
|
export async function POST(req: Request) {
|
|
try {
|
|
const parsed = schema.safeParse(await req.json())
|
|
if (!parsed.success) {
|
|
return NextResponse.json({ error: 'invalid request' }, { status: 400 })
|
|
}
|
|
const { password, redirect } = parsed.data
|
|
|
|
const adminPassword = process.env.ADMIN_PASSWORD
|
|
if (!adminPassword) {
|
|
return NextResponse.json(
|
|
{ error: 'ADMIN_PASSWORD env not configured. Set it in Dokploy environment variables.' },
|
|
{ status: 503 }
|
|
)
|
|
}
|
|
|
|
if (password !== adminPassword) {
|
|
return NextResponse.json({ error: 'Falsches Passwort' }, { status: 401 })
|
|
}
|
|
|
|
// Create session token: base64(payload).hmac
|
|
const crypto = await import('crypto')
|
|
const payload = {
|
|
sub: 'admin',
|
|
iat: Date.now(),
|
|
exp: Date.now() + 7 * 24 * 3600 * 1000, // 7 days
|
|
}
|
|
const payloadB64 = Buffer.from(JSON.stringify(payload)).toString('base64url')
|
|
const key = process.env.AUTH_SECRET || adminPassword
|
|
const signature = crypto
|
|
.createHmac('sha256', key)
|
|
.update(payloadB64)
|
|
.digest('base64url')
|
|
const token = `${payloadB64}.${signature}`
|
|
|
|
const res = NextResponse.json({
|
|
ok: true,
|
|
redirect: redirect || '/',
|
|
})
|
|
res.cookies.set('aos-session', token, {
|
|
httpOnly: true,
|
|
secure: process.env.NODE_ENV === 'production',
|
|
sameSite: 'lax',
|
|
path: '/',
|
|
maxAge: 7 * 24 * 3600, // 7 days
|
|
})
|
|
return res
|
|
} catch {
|
|
return NextResponse.json({ error: 'login failed' }, { status: 500 })
|
|
}
|
|
}
|