docs: registrar fluxo do updater e atualizar chaves
This commit is contained in:
parent
206d00700e
commit
b5fd920efd
50 changed files with 980 additions and 93 deletions
|
|
@ -23,6 +23,13 @@ const registerSchema = z
|
|||
serialNumbers: z.array(z.string()).default([]),
|
||||
metadata: z.record(z.string(), z.unknown()).optional(),
|
||||
registeredBy: z.string().optional(),
|
||||
accessRole: z.enum(["collaborator", "manager"]).optional(),
|
||||
collaborator: z
|
||||
.object({
|
||||
email: z.string().email(),
|
||||
name: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.refine(
|
||||
(data) => (data.macAddresses && data.macAddresses.length > 0) || (data.serialNumbers && data.serialNumbers.length > 0),
|
||||
|
|
@ -61,15 +68,43 @@ export async function POST(request: Request) {
|
|||
const client = new ConvexHttpClient(convexUrl)
|
||||
|
||||
try {
|
||||
const tenantId = payload.tenantId ?? DEFAULT_TENANT_ID
|
||||
const persona = payload.accessRole ?? undefined
|
||||
const collaborator = payload.collaborator ?? null
|
||||
|
||||
if (persona && !collaborator) {
|
||||
return jsonWithCors(
|
||||
{ error: "Informe os dados do colaborador/gestor ao definir o perfil de acesso." },
|
||||
400,
|
||||
request.headers.get("origin"),
|
||||
CORS_METHODS
|
||||
)
|
||||
}
|
||||
|
||||
let metadataPayload: Record<string, unknown> | undefined = payload.metadata
|
||||
? { ...(payload.metadata as Record<string, unknown>) }
|
||||
: undefined
|
||||
if (collaborator) {
|
||||
const collaboratorMeta = {
|
||||
email: collaborator.email,
|
||||
name: collaborator.name ?? null,
|
||||
role: persona ?? "collaborator",
|
||||
}
|
||||
metadataPayload = {
|
||||
...(metadataPayload ?? {}),
|
||||
collaborator: collaboratorMeta,
|
||||
}
|
||||
}
|
||||
|
||||
const registration = await client.mutation(api.machines.register, {
|
||||
provisioningSecret: payload.provisioningSecret,
|
||||
tenantId: payload.tenantId ?? DEFAULT_TENANT_ID,
|
||||
tenantId,
|
||||
companySlug: payload.companySlug ?? undefined,
|
||||
hostname: payload.hostname,
|
||||
os: payload.os,
|
||||
macAddresses: payload.macAddresses,
|
||||
serialNumbers: payload.serialNumbers,
|
||||
metadata: payload.metadata,
|
||||
metadata: metadataPayload,
|
||||
registeredBy: payload.registeredBy,
|
||||
})
|
||||
|
||||
|
|
@ -78,6 +113,7 @@ export async function POST(request: Request) {
|
|||
tenantId: registration.tenantId ?? DEFAULT_TENANT_ID,
|
||||
hostname: payload.hostname,
|
||||
machineToken: registration.machineToken,
|
||||
persona,
|
||||
})
|
||||
|
||||
await client.mutation(api.machines.linkAuthAccount, {
|
||||
|
|
@ -86,6 +122,34 @@ export async function POST(request: Request) {
|
|||
authEmail: account.authEmail,
|
||||
})
|
||||
|
||||
let assignedUserId: Id<"users"> | undefined
|
||||
if (persona && collaborator) {
|
||||
const ensuredUser = (await client.mutation(api.users.ensureUser, {
|
||||
tenantId,
|
||||
email: collaborator.email,
|
||||
name: collaborator.name ?? collaborator.email,
|
||||
avatarUrl: undefined,
|
||||
role: persona.toUpperCase(),
|
||||
companyId: registration.companyId ? (registration.companyId as Id<"companies">) : undefined,
|
||||
})) as { _id?: Id<"users"> } | null
|
||||
|
||||
assignedUserId = ensuredUser?._id
|
||||
|
||||
await client.mutation(api.machines.updatePersona, {
|
||||
machineId: registration.machineId as Id<"machines">,
|
||||
persona,
|
||||
...(assignedUserId ? { assignedUserId } : {}),
|
||||
assignedUserEmail: collaborator.email,
|
||||
assignedUserName: collaborator.name ?? undefined,
|
||||
assignedUserRole: persona === "manager" ? "MANAGER" : "COLLABORATOR",
|
||||
})
|
||||
} else {
|
||||
await client.mutation(api.machines.updatePersona, {
|
||||
machineId: registration.machineId as Id<"machines">,
|
||||
persona: "",
|
||||
})
|
||||
}
|
||||
|
||||
return jsonWithCors(
|
||||
{
|
||||
machineId: registration.machineId,
|
||||
|
|
@ -95,6 +159,9 @@ export async function POST(request: Request) {
|
|||
machineToken: registration.machineToken,
|
||||
machineEmail: account.authEmail,
|
||||
expiresAt: registration.expiresAt,
|
||||
persona: persona ?? null,
|
||||
assignedUserId: assignedUserId ?? null,
|
||||
collaborator: collaborator ?? null,
|
||||
},
|
||||
{ status: 201 },
|
||||
request.headers.get("origin"),
|
||||
|
|
|
|||
77
src/app/api/machines/session/route.ts
Normal file
77
src/app/api/machines/session/route.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import { NextResponse } from "next/server"
|
||||
import { cookies } from "next/headers"
|
||||
import { ConvexHttpClient } from "convex/browser"
|
||||
|
||||
import { api } from "@/convex/_generated/api"
|
||||
import type { Id } from "@/convex/_generated/dataModel"
|
||||
import { env } from "@/lib/env"
|
||||
import { assertAuthenticatedSession } from "@/lib/auth-server"
|
||||
|
||||
const MACHINE_CTX_COOKIE = "machine_ctx"
|
||||
|
||||
function decodeMachineCookie(value: string) {
|
||||
try {
|
||||
const json = Buffer.from(value, "base64url").toString("utf8")
|
||||
return JSON.parse(json) as {
|
||||
machineId: string
|
||||
persona: string | null
|
||||
assignedUserId: string | null
|
||||
assignedUserEmail: string | null
|
||||
assignedUserName: string | null
|
||||
assignedUserRole: string | null
|
||||
}
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
const session = await assertAuthenticatedSession()
|
||||
if (!session || session.user?.role !== "machine") {
|
||||
return NextResponse.json({ error: "Sessão de máquina não encontrada." }, { status: 403 })
|
||||
}
|
||||
|
||||
const cookieStore = await cookies()
|
||||
const cookieValue = cookieStore.get(MACHINE_CTX_COOKIE)?.value
|
||||
if (!cookieValue) {
|
||||
return NextResponse.json({ error: "Contexto da máquina ausente." }, { status: 404 })
|
||||
}
|
||||
|
||||
const decoded = decodeMachineCookie(cookieValue)
|
||||
if (!decoded?.machineId) {
|
||||
return NextResponse.json({ error: "Contexto da máquina inválido." }, { status: 400 })
|
||||
}
|
||||
|
||||
const convexUrl = env.NEXT_PUBLIC_CONVEX_URL
|
||||
if (!convexUrl) {
|
||||
return NextResponse.json({ error: "Convex não configurado." }, { status: 500 })
|
||||
}
|
||||
|
||||
const client = new ConvexHttpClient(convexUrl)
|
||||
|
||||
try {
|
||||
const context = (await client.query(api.machines.getContext, {
|
||||
machineId: decoded.machineId as Id<"machines">,
|
||||
})) as {
|
||||
id: string
|
||||
tenantId: string
|
||||
companyId: string | null
|
||||
companySlug: string | null
|
||||
persona: string | null
|
||||
assignedUserId: string | null
|
||||
assignedUserEmail: string | null
|
||||
assignedUserName: string | null
|
||||
assignedUserRole: string | null
|
||||
metadata: Record<string, unknown> | null
|
||||
authEmail: string | null
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
machine: context,
|
||||
cookie: decoded,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("[machines.session] Falha ao obter contexto da máquina", error)
|
||||
return NextResponse.json({ error: "Falha ao obter contexto da máquina." }, { status: 500 })
|
||||
}
|
||||
}
|
||||
|
|
@ -47,6 +47,24 @@ export async function POST(request: Request) {
|
|||
response.headers.set(key, value)
|
||||
})
|
||||
|
||||
const machineCookiePayload = {
|
||||
machineId: session.machine.id,
|
||||
persona: session.machine.persona,
|
||||
assignedUserId: session.machine.assignedUserId,
|
||||
assignedUserEmail: session.machine.assignedUserEmail,
|
||||
assignedUserName: session.machine.assignedUserName,
|
||||
assignedUserRole: session.machine.assignedUserRole,
|
||||
}
|
||||
response.cookies.set({
|
||||
name: "machine_ctx",
|
||||
value: Buffer.from(JSON.stringify(machineCookiePayload)).toString("base64url"),
|
||||
httpOnly: true,
|
||||
sameSite: "lax",
|
||||
secure: true,
|
||||
path: "/",
|
||||
maxAge: 60 * 60 * 24 * 30,
|
||||
})
|
||||
|
||||
applyCorsHeaders(response, request.headers.get("origin"), CORS_METHODS)
|
||||
|
||||
return response
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue