Implementa o MVP do Adaptador de Planilhas no Elo Pro.
O módulo usa a identidade Supabase, isola cada workspace e registra storage, TTL, runner e biblioteca XLSX como decisões ainda abertas. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
commit
6e23f1533b
144 files changed
+19060
No files matched your search
@@ -0,0 +1,32 @@
|
||||
import { createHmac, timingSafeEqual } from "node:crypto";
|
||||
|
||||
export type DevSession = { userId: string; workspaceId: string; exp: number };
|
||||
|
||||
export function devAuthEnabled(): boolean {
|
||||
return process.env.NODE_ENV !== "production" && process.env.ADAPTER_DEV_AUTH === "1" && Boolean(process.env.ADAPTER_DEV_AUTH_SECRET);
|
||||
}
|
||||
|
||||
function secret(): string {
|
||||
const value = process.env.ADAPTER_DEV_AUTH_SECRET;
|
||||
if (!value) throw new Error("ADAPTER_DEV_AUTH_SECRET ausente.");
|
||||
return value;
|
||||
}
|
||||
|
||||
export function signDevSession(userId: string, workspaceId: string, ttlSeconds = 60 * 60 * 8): string {
|
||||
const body = Buffer.from(JSON.stringify({ userId, workspaceId, exp: Date.now() + ttlSeconds * 1000 })).toString("base64url");
|
||||
const sig = createHmac("sha256", secret()).update(body).digest("base64url");
|
||||
return `${body}.${sig}`;
|
||||
}
|
||||
|
||||
export function verifyDevSession(token: string): DevSession | null {
|
||||
if (!devAuthEnabled()) return null;
|
||||
const [body, sig] = token.split(".");
|
||||
if (!body || !sig) return null;
|
||||
const expected = createHmac("sha256", secret()).update(body).digest("base64url");
|
||||
const left = Buffer.from(sig);
|
||||
const right = Buffer.from(expected);
|
||||
if (left.length !== right.length || !timingSafeEqual(left, right)) return null;
|
||||
const parsed = JSON.parse(Buffer.from(body, "base64url").toString("utf8")) as DevSession;
|
||||
if (!parsed.exp || parsed.exp < Date.now()) return null;
|
||||
return parsed;
|
||||
}
|
||||
Reference in new issue
Block a user