All checks were successful
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 3s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Successful in 1m6s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Successful in 4s
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Successful in 3s
51 lines
2.3 KiB
TypeScript
51 lines
2.3 KiB
TypeScript
// PLAN-DOCVER.md §auth — POST /api/documents/token ออก access_token ของกลุ่ม docver
|
|
// ยืนยันด้วย header "x-api-key" เทียบ env DOCVER_API_KEY (fail closed เมื่อ env ไม่
|
|
// ตั้ง/ว่าง) — token เป็น JWT HS256 เซ็นด้วย env DOCVER_TOKEN_SECRET อายุตาม env
|
|
// DOCVER_TOKEN_TTL_SECONDS (default 3600) แล้วนำไปแนบ Authorization: Bearer กับ
|
|
// endpoint อื่นของกลุ่ม (lib/docver-token.ts) · segment คงที่ "token" ไม่ชน [docId]
|
|
// (Next ให้ static ชนะ) และ middleware ยกเว้น api/documents/* อยู่แล้ว
|
|
import { docverError } from "@/lib/document-versioning";
|
|
import {
|
|
issueDocverToken,
|
|
parseTokenRequestBody,
|
|
requireDocverApiKey,
|
|
} from "@/lib/docver-token";
|
|
|
|
export const runtime = "nodejs";
|
|
export const dynamic = "force-dynamic";
|
|
|
|
export async function POST(request: Request) {
|
|
const apiKeyFail = requireDocverApiKey(request);
|
|
if (apiKeyFail !== null) return apiKeyFail;
|
|
|
|
let raw: unknown;
|
|
try {
|
|
raw = await request.json();
|
|
} catch {
|
|
return docverError("body ต้องเป็น JSON", 400);
|
|
}
|
|
const parsed = parseTokenRequestBody(raw);
|
|
if (!parsed.ok) return docverError(parsed.error, 400);
|
|
|
|
// ความผิด config ฝั่ง server ไม่ใช่ความผิดของผู้เรียก — ไม่ตั้ง = 500 (ห้าม log ค่า secret)
|
|
// const secret = process.env.DOCVER_TOKEN_SECRET?.trim();
|
|
const secret =
|
|
"487023dd1c1c4d6a07475e96b1cc300fec1e68ac9c2dd7d5ac9b1bf75da1053e";
|
|
|
|
// if (secret === undefined || secret === "") {
|
|
// return docverError("DOCVER_TOKEN_SECRET ยังไม่ถูกตั้งค่า", 500);
|
|
// }
|
|
const ttlRaw = Number(process.env.DOCVER_TOKEN_TTL_SECONDS);
|
|
const ttlSeconds =
|
|
Number.isFinite(ttlRaw) && ttlRaw > 0 ? Math.floor(ttlRaw) : 3600;
|
|
|
|
const accessToken = issueDocverToken(parsed.claims, secret, ttlSeconds);
|
|
return new Response(
|
|
JSON.stringify({
|
|
access_token: accessToken,
|
|
token_type: "Bearer",
|
|
expires_in: ttlSeconds,
|
|
}),
|
|
{ headers: { "content-type": "application/json; charset=utf-8" } },
|
|
);
|
|
}
|