Spaces:
Sleeping
Sleeping
File size: 1,442 Bytes
b98da66 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
import type { VercelRequest, VercelResponse } from "@vercel/node";
import crypto from "crypto";
const SESSION_TTL_SECONDS = 10 * 60; // 10 minutes
const FORGE_SESSION_SECRET = process.env.FORGE_SESSION_SECRET!;
function signSession(payload: any): string {
const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
const sig = crypto
.createHmac("sha256", FORGE_SESSION_SECRET)
.update(body)
.digest("base64url");
return `${body}.${sig}`;
}
export default async function handler(req: VercelRequest, res: VercelResponse) {
if (req.method !== "POST") return res.status(405).end();
try {
const authResult = req.body;
// For now we trust authResult structure (replace with actual Pi verification):
const pi_uid = authResult.user?.uid;
const username = authResult.user?.username;
if (!pi_uid || !username) {
return res.status(400).json({ error: "Missing user info from Pi." });
}
// Mint short-lived Forge Session Token
const now = Math.floor(Date.now() / 1000);
const payload = {
pi_uid,
username,
iat: now,
exp: now + SESSION_TTL_SECONDS,
scope: "agent-session"
};
const session_token = signSession(payload);
return res.status(200).json({
status: "ok",
session_token
});
} catch (e: any) {
console.error(e);
return res.status(500).json({ error: "pi_auth_failed", message: e.message });
}
} |