Fix session cookie propagation; desktop creates session via POST before opening portal

This commit is contained in:
Esdras Renan 2025-10-14 20:33:40 -03:00
parent 69955ae80c
commit 6754af769b
3 changed files with 62 additions and 12 deletions

View file

@ -430,14 +430,36 @@ function App() {
} }
} }
const openSystem = useCallback(() => { const openSystem = useCallback(async () => {
if (!token) return if (!token) return
setIsLaunchingSystem(true) setIsLaunchingSystem(true)
try {
// Tenta criar a sessão via API (evita dependência de redirecionamento + cookies em 3xx)
const res = await fetch(`${apiBaseUrl}/api/machines/sessions`, {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ machineToken: token, rememberMe: true }),
})
if (!res.ok) {
// Fallback para o handshake por redirecionamento
const persona = (config?.accessRole ?? accessRole) === "manager" ? "manager" : "collaborator"
const redirectTarget = persona === "manager" ? "/dashboard" : "/portal"
const url = `${resolvedAppUrl}/machines/handshake?token=${encodeURIComponent(token)}&redirect=${encodeURIComponent(redirectTarget)}`
window.location.href = url
return
}
} catch {
const persona = (config?.accessRole ?? accessRole) === "manager" ? "manager" : "collaborator"
const redirectTarget = persona === "manager" ? "/dashboard" : "/portal"
const url = `${resolvedAppUrl}/machines/handshake?token=${encodeURIComponent(token)}&redirect=${encodeURIComponent(redirectTarget)}`
window.location.href = url
return
}
const persona = (config?.accessRole ?? accessRole) === "manager" ? "manager" : "collaborator" const persona = (config?.accessRole ?? accessRole) === "manager" ? "manager" : "collaborator"
const redirectTarget = persona === "manager" ? "/dashboard" : "/portal" const redirectTarget = persona === "manager" ? "/dashboard" : "/portal"
const url = `${resolvedAppUrl}/machines/handshake?token=${encodeURIComponent(token)}&redirect=${encodeURIComponent(redirectTarget)}` window.location.href = `${resolvedAppUrl}${redirectTarget}`
window.location.href = url }, [token, config?.accessRole, accessRole, resolvedAppUrl, apiBaseUrl])
}, [token, config?.accessRole, accessRole, resolvedAppUrl])
async function reprovision() { async function reprovision() {
if (!store) return if (!store) return

View file

@ -43,9 +43,26 @@ export async function POST(request: Request) {
{ status: 200 } { status: 200 }
) )
session.headers.forEach((value, key) => { // Propaga cookies de sessão do Better Auth com segurança.
response.headers.set(key, value) // Em alguns ambientes, múltiplos Set-Cookie são colapsados; tentamos cobrir ambos.
}) const headersAny = session.headers as unknown as { getSetCookie?: () => string[] }
const setCookies: string[] = []
try {
if (typeof headersAny?.getSetCookie === "function") {
setCookies.push(...(headersAny.getSetCookie() ?? []))
} else {
const single = session.headers.get("set-cookie")
if (single) setCookies.push(single)
}
} catch {
const single = session.headers.get("set-cookie")
if (single) setCookies.push(single)
}
for (const cookie of setCookies) {
// Usa append para não sobrescrever múltiplos cookies (authsession e assinatura, por exemplo)
response.headers.append("set-cookie", cookie)
}
const machineCookiePayload = { const machineCookiePayload = {
machineId: session.machine.id, machineId: session.machine.id,

View file

@ -50,13 +50,24 @@ export async function GET(request: NextRequest) {
const session = await createMachineSession(token, true) const session = await createMachineSession(token, true)
const response = NextResponse.redirect(redirectUrl) const response = NextResponse.redirect(redirectUrl)
session.headers.forEach((value, key) => { // Propaga os cookies de sessão do Better Auth (podem vir múltiplos)
if (key.toLowerCase() === "set-cookie") { const headersAny = session.headers as unknown as { getSetCookie?: () => string[] }
response.headers.append("set-cookie", value) let setCookies: string[] = []
try {
if (typeof headersAny?.getSetCookie === "function") {
setCookies = headersAny.getSetCookie() ?? []
} else { } else {
response.headers.set(key, value) const single = session.headers.get("set-cookie")
if (single) setCookies = [single]
} }
}) } catch {
const single = session.headers.get("set-cookie")
if (single) setCookies = [single]
}
for (const cookie of setCookies) {
response.headers.append("set-cookie", cookie)
}
const machineCookiePayload = { const machineCookiePayload = {
machineId: session.machine.id, machineId: session.machine.id,