eCourt-note/.env.example
Your Name 5121970f31
Some checks failed
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) Failing after 30s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Has been skipped
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Failing after 1s
refactor(auth): consolidate auth under /api/auth/* endpoints
- ยุบ route auth ที่เคย copy กันจน drift (flow N11 หายจาก /api/auth/session)
  เหลือโค้ด inline สองเส้นเดียว: POST /api/auth/token (ทางเข้า 3: x-api-key
  docver / x-api-key purpose:"login" mint ลิงก์ note / ticket ของ add-in)
  + POST /api/auth/session (แลก credential + register N8 + N11 fid-only)
- POST /api/documents/token คงไว้เป็น alias re-export (กลุ่ม docver/e-Court
  เดิม — contract เดิมเป๊ะ, มี test toBe กัน copy แยกชุดกลับมา)
- ถอดเส้นฝั่ง note ทั้งสอบ: /api/note/auth/token + /api/note/auth/session
  (e-Court ต้องย้ายมาทางเข้ารวม — แจ้งทีม e-Court ก่อน deploy)
- utils/auth-store.ts: primitives กลางฝั่ง client (jwtExp/isExpired/
  localStorage store + memory fallback) — lib/note-session ใช้ร่วม
  (expMs decode จาก JWT payload = นาฬิกา server) และวางไว้ให้ wordaddin
  ย้ายมาใช้รอบหน้าได้ (รอบนี้ไม่แต้ wordaddin ตามข้อตกลง)
- นโยบาย token หมดอายุกลาง session: PDFViewer reportActionError จับ
  auth-error ของ Server Action ทุกจุด → ล้าง session แล้วพาไป
  /note?sso=expired (จบที่ gate เดียวกับ bootstrap 401)
- openapi: ทางเข้า purpose:"login" + schema LoginTokenRequest + ลบ path
  เส้นที่ถอด + test กันเส้นตายหลุดค้างใน spec
- เอกสาร sync: PLAN-SSO §0.6, CLAUDE.md, PLAN-STAGED, .env.example, /note/dev
- tests: ย้าย/เพิ่มชุด auth (50 เคสกลุ่ม auth ผ่าน, ทั้งชุด 444 ผ่าน) +
  e2e ครบทั้ง API (mint/alias/ticket/404 เส้นเก่า/N11/D4) และ browser

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-09 14:30:29 +07:00

85 lines
6.9 KiB
Text

########### สำหรับ npm run dev และ แอปบน container
# Sign/Hash ที่ใช้ฝังในเอกสาร(docx)
SECRET="" # HmacSHA256
PRIVATE_KEY_HEX=""
PUBLIC_KEY_HEX=""
## ไม่ตั้ง/ว่าง = ปฏิเสธทุก request (fail closed) — ตั้งค่ายาวและสุ่ม เช่น 32+ ตัวอักษร
EXTERNAL_API_KEY=""
DOCVER_API_KEY=""
# secret เซ็น/ตรวจ JWT HS256 ของทุก endpoint /api/documents/* (Authorization: Bearer)
DOCVER_TOKEN_SECRET=
# ใช้ตอน migrate และ การใช้งาน ใน development
DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/ecourt-note
# Optional ไม่ใส่ก็ได้มีค่า default
TMPL_PATH='./public/tmpl'
TICKET_SEC=300 # อายุของ ticket ยิ่งน้อยยิ่งดี
DOCX_WORKERS=3 # cpu core หักออก 1
########### สำหรับโค้ดตัวอย่างให้ระบบนอกเรียกเข้ามาไม่ได้ใช้ในระบบนี้ ห้ามเอาไช้ในส่วนอื่น
DOCEDIT_BASE_URL=http://127.0.0.1:3000/docedit
########### สำหรับ แอป และ service ต่างๆใน container
APP_DOMAIN=docedit.example.com
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=note
# ใช้สำหรับ local dev ถ้า minio อยู่คนละเครื่องให้ดูค่าให้เหมาะสม
MINIO_ENDPOINT=127.0.0.1
MINIO_PORT=19000
MINIO_USE_SSL=false
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
# MINIO_BUCKET=docver
# DOCVER_LINK_TTL_SECONDS=900
# DOCVER_TOKEN_TTL_SECONDS=3600
# (ถอดแล้ว 2026-10-30) NOTE_SESSION_SECRET ของรอบ cookie oacCaseSig — แอป note
# เปลี่ยน session เป็น token แบบ add-in แล้ว (access_token purpose=login จาก
# POST /api/auth/session ทางเข้าเดียว 2026-11-09 — เส้นเดิม /api/note/auth/session
# ถอดแล้ว เก็บใน localStorage "note-auth") จึงใช้
# DOCVER_TOKEN_SECRET ตัวเดียวทั้งระบบ: เซ็น login-token ของลิงก์ + เซ็น/ตรวจ
# session token ฝั่ง Server Actions และ API ของแอป (lib/note-token.ts)
# dev-only (ทางเลือก): เปิดฟอร์ม "สร้างลิงก์ทดสอบ" บนหน้า /note + route
# POST /api/note/auth/dev-link — mint ลิงก์ SSO จากหน้าเว็บเพื่อทดสอบ flow จริง
# ⚠️ ตัวช่วยทดสอบเท่านั้น ไม่ใช่ทางเข้าจริง: ปิด = route ตอบ 404 + ฟอร์มหายจากหน้า
# และไม่ทำงานใน production build เด็ดขาด (NODE_ENV=production) — dev server ที่แชร์
# บน LAN เปิดไว้ = คนในวงแชร์เครือข่าย mint ลิงก์เข้าระบบได้ จึงควรเปิดเฉพาะตอนทดสอบ
# NOTE_SSO_DEV_MINT=1
# N11 RAM staging ของเอกสาร base64 จาก e-Court (2026-11-04, docs/PLAN-STAGED.md)
# POST /api/note/files/stage ใช้ DOCVER_API_KEY ด้านบน — env ด้านล่างเป็นตัวปรับล้วน
# ไม่ตั้งทั้งหมด = ใช้ default ทำงานได้เลย · ⚠️ staging อยู่ใน RAM ของ process เดียว
# (เหมือน SSE) — ห้ามรันหลาย instance/cluster · deploy หลัง IIS ต้องขยับ
# maxAllowedContentLength ≥ 140MB (ดู PLAN-STAGED.md D7)
# TTL sliding จากการเข้าใช้ล่าสุด (วินาที) — default 28800 = 8 ชม. เท่า session
# STAGED_DOC_TTL_SECONDS=28800
# โควตารวมทุกไฟล์ใน RAM (ไบต์) — เกิน = LRU evict รายการเก่าสุด
# STAGED_MAX_TOTAL_BYTES=268435456
# ขนาดเนื้อไฟล์ต่อไฟล์ (ไบต์) — เกิน = 413
# STAGED_MAX_FILE_BYTES=104857600
# จำนวน stage request พร้อมกันสูงสุด — เกิน = 429 Retry-After: 5
# STAGED_MAX_CONCURRENT=1
# hash fid ของ e-Court ก่อนเก็บลง files.external_id (2026-11-04, lib/ecourt-fid.ts)
# = HMAC-SHA256(pepper, fid) — ไม่มี fid ดิบใน DB
# ⚠️ ค่าคงที่ตลอดชีพ: ห้ามเปลี่ยนหลังมีข้อมูล (เปลี่ยน = แถวเก่าค้นไม่เจอ + เกิดแถว
# คู่เงียบ ๆ) · ตั้งค่ายาวและสุ่ม 32+ ตัวอักษร · ห้าม commit ค่าจริงลง repo
# · row เก่าที่เก็บ plaintext แปลงครั้งเดียวด้วย npm run migrate:ecourt-fid
# (ต้องใช้ pepper ค่าเดียวกัน — ระหว่างรันต้องหยุด process ของแอปก่อน)
FID_HASH_PEPPER=
# add-in ticket auth (2026-10-27, docs/PLAN-ADDIN-AUTH.md): add-in ใน Word ขอ token
# ที่ POST /api/documents/token ด้วย body {ticket_data, HmacSha256} ที่ e-Court stamp
# มากับไฟล์ — secret ต้องตรงกันสองฝั่ง: e-Court (ตัว stamp) กับ server นี้ (ตัว verify)
# ฝั่ง server ตรวจ HMAC ของ ticket: ADDIN_TICKET_SECRET (ไม่ตั้ง = ใช้ env SECRET
# ของกลุ่ม template → ยังไม่ตั้งอีก = "super_secret" ตาม requirement)
# ⚠️ production ต้องตั้งค่าจริง — ค่า default รู้กันหมด = ใครก็ปลอม ticket ได้
# (ใช้ร่วมกับทาง ticket ของ SSO POST /api/auth/session ด้วย — PLAN-SSO.md D12)
# 2026-10-30: ทาง ticket ของ SSO (POST /api/auth/session) ปฏิเสธค่า default
# นี้เฉพาะใน production — dev ใช้ default ทดสอบโหมด ticket ได้เลย (เครื่องมือ dev
# อย่าง make-login-link/make-ticket-docx ก็ default ค่าเดียวกัน)
# 2026-11-04: ฝั่ง add-in ไม่มี secret อีกต่อไป (ถอด NEXT_PUBLIC_ADDIN_TICKET_SECRET
# ตาม PLAN-SSO.md D13 — การตรวจ HMAC เป็นของ server อย่างเดียว)
# ADDIN_TICKET_SECRET=super_secret