fix(avatar): sincroniza avatar apos atualizar
All checks were successful
All checks were successful
- Propaga Set-Cookie do Better Auth no endpoint de avatar\n- Forca refresh da sessao apos upload/remocao\n- Adiciona teste de propagacao e defaults de env para testes
This commit is contained in:
parent
74c06ffa33
commit
8546a1feb1
6 changed files with 84 additions and 4 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
* DELETE - Remove a foto de perfil (volta ao padrão)
|
* DELETE - Remove a foto de perfil (volta ao padrão)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { NextRequest, NextResponse } from "next/server"
|
import { NextResponse } from "next/server"
|
||||||
|
|
||||||
import { getServerSession } from "@/lib/auth-server"
|
import { getServerSession } from "@/lib/auth-server"
|
||||||
import { auth } from "@/lib/auth"
|
import { auth } from "@/lib/auth"
|
||||||
|
|
@ -34,7 +34,7 @@ function extractSetCookies(headers: Headers) {
|
||||||
return setCookieHeaders
|
return setCookieHeaders
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: Request) {
|
||||||
try {
|
try {
|
||||||
const session = await getServerSession()
|
const session = await getServerSession()
|
||||||
|
|
||||||
|
|
@ -142,7 +142,7 @@ export async function POST(request: NextRequest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function DELETE(request: NextRequest) {
|
export async function DELETE(request: Request) {
|
||||||
try {
|
try {
|
||||||
const session = await getServerSession()
|
const session = await getServerSession()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }
|
||||||
import { Input } from "@/components/ui/input"
|
import { Input } from "@/components/ui/input"
|
||||||
import { Label } from "@/components/ui/label"
|
import { Label } from "@/components/ui/label"
|
||||||
import { Separator } from "@/components/ui/separator"
|
import { Separator } from "@/components/ui/separator"
|
||||||
import { useAuth, signOut } from "@/lib/auth-client"
|
import { refreshSession, signOut, useAuth } from "@/lib/auth-client"
|
||||||
|
|
||||||
const ShaderBackground = dynamic(
|
const ShaderBackground = dynamic(
|
||||||
() => import("@/components/background-paper-shaders-wrapper"),
|
() => import("@/components/background-paper-shaders-wrapper"),
|
||||||
|
|
@ -442,6 +442,7 @@ function ProfileEditCard({
|
||||||
|
|
||||||
const avatarData = await avatarRes.json()
|
const avatarData = await avatarRes.json()
|
||||||
setLocalAvatarUrl(avatarData.avatarUrl)
|
setLocalAvatarUrl(avatarData.avatarUrl)
|
||||||
|
await refreshSession()
|
||||||
|
|
||||||
// Limpa preview
|
// Limpa preview
|
||||||
if (pendingAvatarPreview) {
|
if (pendingAvatarPreview) {
|
||||||
|
|
@ -461,6 +462,7 @@ function ProfileEditCard({
|
||||||
|
|
||||||
setLocalAvatarUrl(null)
|
setLocalAvatarUrl(null)
|
||||||
setPendingRemoveAvatar(false)
|
setPendingRemoveAvatar(false)
|
||||||
|
await refreshSession()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Processa outros dados do perfil se houver
|
// Processa outros dados do perfil se houver
|
||||||
|
|
|
||||||
72
tests/profile-avatar-cookie-propagation.test.ts
Normal file
72
tests/profile-avatar-cookie-propagation.test.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { beforeEach, describe, expect, it, vi } from "vitest"
|
||||||
|
|
||||||
|
import { DELETE } from "@/app/api/profile/avatar/route"
|
||||||
|
import { getServerSession } from "@/lib/auth-server"
|
||||||
|
import { auth } from "@/lib/auth"
|
||||||
|
import { prisma } from "@/lib/prisma"
|
||||||
|
|
||||||
|
vi.mock("@/lib/auth-server", () => ({
|
||||||
|
getServerSession: vi.fn(),
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock("@/server/convex-client", () => ({
|
||||||
|
createConvexClient: vi.fn(() => ({ mutation: vi.fn() })),
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock("@/lib/prisma", () => ({
|
||||||
|
prisma: {
|
||||||
|
authUser: { update: vi.fn() },
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock("@/lib/auth", () => ({
|
||||||
|
auth: {
|
||||||
|
api: {
|
||||||
|
updateUser: vi.fn(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe("DELETE /api/profile/avatar", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.resetAllMocks()
|
||||||
|
vi.mocked(getServerSession).mockResolvedValue({
|
||||||
|
session: { id: "sess-1", expiresAt: Date.now() + 60_000 },
|
||||||
|
user: {
|
||||||
|
id: "user-1",
|
||||||
|
name: "Agente",
|
||||||
|
email: "agent@example.com",
|
||||||
|
role: "agent",
|
||||||
|
tenantId: null,
|
||||||
|
avatarUrl: "https://cdn.example.com/avatar.png",
|
||||||
|
machinePersona: null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("propaga Set-Cookie retornado pelo Better Auth (cookieCache)", async () => {
|
||||||
|
const upstreamHeaders = new Headers()
|
||||||
|
upstreamHeaders.append("set-cookie", "better-auth.session_data=abc; Path=/; HttpOnly")
|
||||||
|
upstreamHeaders.append("set-cookie", "better-auth.session_token=def; Path=/; HttpOnly")
|
||||||
|
|
||||||
|
vi.mocked(auth.api.updateUser).mockResolvedValue(
|
||||||
|
new Response(JSON.stringify({ status: true }), { status: 200, headers: upstreamHeaders })
|
||||||
|
)
|
||||||
|
|
||||||
|
const req = new Request("http://localhost/api/profile/avatar", { method: "DELETE" })
|
||||||
|
const res = await DELETE(req)
|
||||||
|
|
||||||
|
expect(res.status).toBe(200)
|
||||||
|
|
||||||
|
const headersAny = res.headers as Headers & { getSetCookie?: () => string[] | undefined }
|
||||||
|
const setCookies =
|
||||||
|
typeof headersAny.getSetCookie === "function"
|
||||||
|
? headersAny.getSetCookie() ?? []
|
||||||
|
: [res.headers.get("set-cookie")].filter(Boolean)
|
||||||
|
|
||||||
|
expect(setCookies.join("\n")).toContain("better-auth.session_data=abc")
|
||||||
|
expect(setCookies.join("\n")).toContain("better-auth.session_token=def")
|
||||||
|
|
||||||
|
expect(vi.mocked(prisma.authUser.update)).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -6,6 +6,7 @@ import { JSDOM } from "jsdom"
|
||||||
process.env.BETTER_AUTH_SECRET ??= "test-secret"
|
process.env.BETTER_AUTH_SECRET ??= "test-secret"
|
||||||
process.env.NEXT_PUBLIC_APP_URL ??= "http://localhost:3000"
|
process.env.NEXT_PUBLIC_APP_URL ??= "http://localhost:3000"
|
||||||
process.env.BETTER_AUTH_URL ??= process.env.NEXT_PUBLIC_APP_URL
|
process.env.BETTER_AUTH_URL ??= process.env.NEXT_PUBLIC_APP_URL
|
||||||
|
process.env.DATABASE_URL ??= "postgresql://postgres:postgres@localhost:5432/sistema_test?schema=public"
|
||||||
process.env.NODE_ENV ??= "test"
|
process.env.NODE_ENV ??= "test"
|
||||||
|
|
||||||
const OriginalDate = Date
|
const OriginalDate = Date
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ const convexDir = path.resolve(__dirname, "./convex")
|
||||||
const isCI = process.env.CI === "true"
|
const isCI = process.env.CI === "true"
|
||||||
const isBrowserRun = process.env.VITEST_BROWSER === "true"
|
const isBrowserRun = process.env.VITEST_BROWSER === "true"
|
||||||
|
|
||||||
|
process.env.DATABASE_URL =
|
||||||
|
process.env.DATABASE_URL ?? "postgresql://postgres:postgres@localhost:5432/sistema_test?schema=public"
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
root: __dirname,
|
root: __dirname,
|
||||||
plugins: [tsconfigPaths()],
|
plugins: [tsconfigPaths()],
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ if (typeof process !== "undefined" && process.versions?.node) {
|
||||||
process.env.BETTER_AUTH_SECRET = process.env.BETTER_AUTH_SECRET ?? "test-secret"
|
process.env.BETTER_AUTH_SECRET = process.env.BETTER_AUTH_SECRET ?? "test-secret"
|
||||||
process.env.NEXT_PUBLIC_APP_URL = process.env.NEXT_PUBLIC_APP_URL ?? "http://localhost:3000"
|
process.env.NEXT_PUBLIC_APP_URL = process.env.NEXT_PUBLIC_APP_URL ?? "http://localhost:3000"
|
||||||
process.env.BETTER_AUTH_URL = process.env.BETTER_AUTH_URL ?? process.env.NEXT_PUBLIC_APP_URL
|
process.env.BETTER_AUTH_URL = process.env.BETTER_AUTH_URL ?? process.env.NEXT_PUBLIC_APP_URL
|
||||||
|
process.env.DATABASE_URL =
|
||||||
|
process.env.DATABASE_URL ?? "postgresql://postgres:postgres@localhost:5432/sistema_test?schema=public"
|
||||||
}
|
}
|
||||||
|
|
||||||
export {}
|
export {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue