fix(dataroom): use getSessionFromCookie() instead of middleware headers; fix auth page overflow
Build pitch-deck / build-push-deploy (push) Successful in 1m33s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 37s
CI / test-python-voice (push) Successful in 31s
CI / test-bqas (push) Successful in 27s
Build pitch-deck / build-push-deploy (push) Successful in 1m33s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 37s
CI / test-python-voice (push) Successful in 31s
CI / test-bqas (push) Successful in 27s
Dataroom routes were reading x-investor-id from request headers which the middleware sets as response headers — these don't reach route handlers when the admin fallback path runs (NextResponse.next() without header). Switch to getSessionFromCookie() consistent with all other investor routes. Auth page DSGVO footer switched from absolute bottom-0 to normal flow so the expanded Art. 13 notice doesn't overlap the login card. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,15 +1,16 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server'
|
import { NextRequest, NextResponse } from 'next/server'
|
||||||
import pool from '@/lib/db'
|
import pool from '@/lib/db'
|
||||||
import { streamFile } from '@/lib/dataroom-storage'
|
import { streamFile } from '@/lib/dataroom-storage'
|
||||||
import { logAudit } from '@/lib/auth'
|
import { logAudit, getSessionFromCookie } from '@/lib/auth'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
interface Ctx { params: Promise<{ id: string }> }
|
interface Ctx { params: Promise<{ id: string }> }
|
||||||
|
|
||||||
export async function GET(request: NextRequest, ctx: Ctx) {
|
export async function GET(request: NextRequest, ctx: Ctx) {
|
||||||
const investorId = request.headers.get('x-investor-id')
|
const session = await getSessionFromCookie()
|
||||||
const sessionId = request.headers.get('x-session-id')
|
if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||||
if (!investorId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
const investorId = session.sub
|
||||||
|
const sessionId = session.sessionId
|
||||||
|
|
||||||
const { id } = await ctx.params
|
const { id } = await ctx.params
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server'
|
import { NextRequest, NextResponse } from 'next/server'
|
||||||
import pool from '@/lib/db'
|
import pool from '@/lib/db'
|
||||||
|
import { getSessionFromCookie } from '@/lib/auth'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
|
|
||||||
export async function GET(request: NextRequest) {
|
export async function GET(request: NextRequest) {
|
||||||
const investorId = request.headers.get('x-investor-id')
|
const session = await getSessionFromCookie()
|
||||||
if (!investorId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||||
|
const investorId = session.sub
|
||||||
|
|
||||||
const { rows } = await pool.query(
|
const { rows } = await pool.query(
|
||||||
`SELECT d.id, d.filename, d.display_name, d.mime_type, d.file_size, r.released_at
|
`SELECT d.id, d.filename, d.display_name, d.mime_type, d.file_size, r.released_at
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server'
|
import { NextRequest, NextResponse } from 'next/server'
|
||||||
import pool from '@/lib/db'
|
import pool from '@/lib/db'
|
||||||
import { investorUploadDir, saveFile, safeName } from '@/lib/dataroom-storage'
|
import { investorUploadDir, saveFile, safeName } from '@/lib/dataroom-storage'
|
||||||
import { logAudit } from '@/lib/auth'
|
import { logAudit, getSessionFromCookie } from '@/lib/auth'
|
||||||
import { randomUUID } from 'crypto'
|
import { randomUUID } from 'crypto'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
|
|
||||||
const MAX_BYTES = parseInt(process.env.DATAROOM_MAX_UPLOAD_MB || '50') * 1024 * 1024
|
const MAX_BYTES = parseInt(process.env.DATAROOM_MAX_UPLOAD_MB || '50') * 1024 * 1024
|
||||||
|
|
||||||
export async function GET(request: NextRequest) {
|
export async function GET(_request: NextRequest) {
|
||||||
const investorId = request.headers.get('x-investor-id')
|
const session = await getSessionFromCookie()
|
||||||
if (!investorId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||||
|
const investorId = session.sub
|
||||||
|
|
||||||
const { rows } = await pool.query(
|
const { rows } = await pool.query(
|
||||||
`SELECT id, filename, display_name, mime_type, file_size, created_at
|
`SELECT id, filename, display_name, mime_type, file_size, created_at
|
||||||
@@ -23,9 +24,10 @@ export async function GET(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: NextRequest) {
|
||||||
const investorId = request.headers.get('x-investor-id')
|
const session = await getSessionFromCookie()
|
||||||
const sessionId = request.headers.get('x-session-id')
|
if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||||
if (!investorId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
const investorId = session.sub
|
||||||
|
const sessionId = session.sessionId
|
||||||
|
|
||||||
const formData = await request.formData()
|
const formData = await request.formData()
|
||||||
const file = formData.get('file') as File | null
|
const file = formData.get('file') as File | null
|
||||||
|
|||||||
@@ -39,15 +39,16 @@ export default function AuthPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-screen flex items-center justify-center bg-[#0a0a1a] relative overflow-hidden">
|
<div className="min-h-screen flex flex-col bg-[#0a0a1a] relative overflow-x-hidden">
|
||||||
{/* Background gradient */}
|
{/* Background gradient */}
|
||||||
<div className="absolute inset-0 bg-gradient-to-br from-indigo-950/30 via-transparent to-purple-950/20" />
|
<div className="absolute inset-0 bg-gradient-to-br from-indigo-950/30 via-transparent to-purple-950/20 pointer-events-none" />
|
||||||
|
|
||||||
|
<div className="flex-1 flex items-center justify-center py-12 px-6">
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 0.6 }}
|
transition={{ duration: 0.6 }}
|
||||||
className="relative z-10 text-center max-w-md mx-auto px-6"
|
className="relative z-10 text-center max-w-md w-full mx-auto"
|
||||||
>
|
>
|
||||||
<div className="mb-8">
|
<div className="mb-8">
|
||||||
<h1 className="text-3xl font-bold bg-gradient-to-r from-indigo-400 to-purple-400 bg-clip-text text-transparent mb-2">
|
<h1 className="text-3xl font-bold bg-gradient-to-r from-indigo-400 to-purple-400 bg-clip-text text-transparent mb-2">
|
||||||
@@ -122,9 +123,10 @@ export default function AuthPage() {
|
|||||||
We are an AI-first company. No PDFs. No slide decks. Just code.
|
We are an AI-first company. No PDFs. No slide decks. Just code.
|
||||||
</p>
|
</p>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Privacy Notice Footer */}
|
{/* Privacy Notice Footer */}
|
||||||
<div className="absolute bottom-0 left-0 right-0 px-8 py-4 border-t border-white/5">
|
<div className="relative z-10 px-8 py-5 border-t border-white/5">
|
||||||
<div className="max-w-2xl mx-auto">
|
<div className="max-w-2xl mx-auto">
|
||||||
<p className="text-[10px] text-white/20 leading-relaxed text-center">
|
<p className="text-[10px] text-white/20 leading-relaxed text-center">
|
||||||
<strong className="text-white/25">Datenschutzhinweis (Art. 13 DSGVO):</strong> Beim Zugriff werden technische Zugriffsdaten (IP-Adresse, Zeitpunkt, Browser) sowie – soweit eingeladen – personenbezogene Kontaktdaten (E-Mail, Name, Unternehmen) verarbeitet. Zweck: Zugangsverwaltung und Missbrauchsprävention. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse). Speicherdauer: max. 30 Tage nach letztem Zugriff; nicht aktivierte Zugänge nach 90 Tagen. Danach automatische Anonymisierung. Ihre Rechte gem. Art. 15–21 DSGVO (Auskunft, Berichtigung, Löschung, Einschränkung, Datenübertragbarkeit, Widerspruch): Anfragen an pitch@breakpilot.ai. Beschwerderecht bei der Aufsichtsbehörde: LfDI Baden-Württemberg (www.baden-wuerttemberg.datenschutz.de).</p>
|
<strong className="text-white/25">Datenschutzhinweis (Art. 13 DSGVO):</strong> Beim Zugriff werden technische Zugriffsdaten (IP-Adresse, Zeitpunkt, Browser) sowie – soweit eingeladen – personenbezogene Kontaktdaten (E-Mail, Name, Unternehmen) verarbeitet. Zweck: Zugangsverwaltung und Missbrauchsprävention. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse). Speicherdauer: max. 30 Tage nach letztem Zugriff; nicht aktivierte Zugänge nach 90 Tagen. Danach automatische Anonymisierung. Ihre Rechte gem. Art. 15–21 DSGVO (Auskunft, Berichtigung, Löschung, Einschränkung, Datenübertragbarkeit, Widerspruch): Anfragen an pitch@breakpilot.ai. Beschwerderecht bei der Aufsichtsbehörde: LfDI Baden-Württemberg (www.baden-wuerttemberg.datenschutz.de).</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user