#frontend#login#google#demo#select-database#workspace
หน้าเข้าสู่ระบบและเลือกฐานข้อมูล (Login & select database)
ผู้ใช้เข้าระบบสองขั้น: (1) /login ยืนยันตัวตน (2) /select-database เลือก/สร้าง "ฐานข้อมูล" (workspace) ที่จะทำงานด้วย แล้วจึงเข้า /home
ปุ่มที่หน้า /login มีแค่ 2 ทางคือ "ทดลองใช้งานทันที (Demo)" และ "ดำเนินการต่อด้วย Google" (ไม่มีช่องกรอกรหัสผ่านใน UI ที่อ่าน)
ทำงานอย่างไร
หน้า /login (src/app/login/page.tsx)
- Demo: ปุ่ม
handleDemoLogin(บรรทัด 90-105) เรียกapiPost("/api/auth/demo")แล้วrouter.replace(safeReturnTo)+router.refresh(). ใช้ฐานsmldemo(ข้อความบนปุ่ม บรรทัด 414). - Google: ปุ่ม
handleTriggerGoogleSignIn(บรรทัด 136-165) โหลดสคริปต์ Google Identity Services แล้วได้credential(idToken) ส่งให้handleGoogleCredential(บรรทัด 107-128) ->apiPost("/api/auth/google", {...}). สำเร็จแล้วไป/select-database?returnTo=...(บรรทัด 124) เพราะต้องเลือกฐานก่อน. ถ้ายังไม่ตั้ง Client ID จะแสดงข้อความ error (บรรทัด 139). มี route แบบ redirect (GET ?action=redirect+ cookiesml_google_oauth_state) ด้วย - ดู เซสชันและการยืนยันตัวตนฝั่ง frontend (Auth session & tokens). - สถานะ
demoBusy/googleBusyกันกดซ้ำและ disable ปุ่มอีกฝั่ง (บรรทัด 69-70, 401). - จุดสังเกต: โหมด admin ของ
/api/auth/login(รหัสผู้ใช้ + รหัสผ่าน) มีใน API แต่ไม่พบปุ่มเรียกในlogin/page.tsx(ยังไม่ยืนยันว่ามีทางเข้า UI อื่น).
returnTo และกัน open redirect
safeReturnPath(raw, fallback="/home")(src/lib/safe-return.ts:6-13) ยอมรับเฉพาะ path ภายในที่ขึ้นต้นด้วย/และไม่ใช่//,/\, ไม่มี\หรือ control char; ไม่ผ่านใช้/home.- login อ่าน
?returnTo=ก่อน แล้ว fallback เป็นsessionStorage["sml_return_to"](login/page.tsx:82-87); ค่านี้ถูกตั้งโดย host ตอน session หมดอายุ (โครงหน้าเว็บและการนำทาง (App shell & routing)) และถูกลบหลัง login สำเร็จ (บรรทัด 101).
หน้า /select-database (src/app/select-database/page.tsx)
| งาน | endpoint ที่เรียก | บรรทัด |
|---|---|---|
| โหลด session + รายการฐานข้อมูลของฉัน | GET /api/auth/session, GET /api/auth/databases |
141-142 |
| ตรวจชื่อฐานซ้ำแบบ real-time (debounce 220 ms) | GET /api/workspace/check-db-name?name= |
189-216 |
| เลือกฐาน | POST /api/workspace/select-db (สำรอง POST /api/auth/databases) |
224-231 |
| ลองใช้ Demo | POST /api/auth/demo |
261 |
สร้างฐานใหม่ (database_code, database_name, company_name) |
POST /api/workspace/databases |
286 |
| สมาชิกของฐาน (ดู/เชิญ/เปลี่ยนบทบาท/ลบ) | GET/POST/DELETE /api/workspace/members |
325, 362, 395, 417 |
| สิทธิ์จอรายผู้ใช้ | GET/POST /api/workspace/screen-rights |
433, 551 |
| ออกจากระบบ | POST /api/auth/logout |
570 |
- บทบาทต่อฐานมี 2 แบบ
ADMIN | MEMBER(บรรทัด 39, 122). ผู้ถูกเชิญเป็น MEMBER ต้องมีการผูกกับรหัสผู้ใช้ SML (mappedUserCode) และตั้งสิทธิ์จอ (บรรทัด 335-401). - เมื่อเลือกฐานเสร็จ ใช้
safeReturnPathเดิม แล้วrouter.replace+router.refresh()(บรรทัด 245-255). - พาธ
/api/workspace/*ทั้งหมดผ่าน catch-allsrc/app/api/workspace/[...path]/route.tsไปยัง backend (เส้นทาง API ฝั่ง Next.js ที่ส่งต่อไป Go backend (API proxy routes)).
ข้อควรระวัง
- ถ้า session ไม่มี
databaselayout ของ(app)จะ redirect กลับ/select-databaseทุกครั้ง (โครงหน้าเว็บและการนำทาง (App shell & routing)). - ชื่อฐานข้อมูลต้องเป็นอังกฤษตัวพิมพ์เล็ก/ตัวเลข (ข้อความ error บรรทัด ~276) และห้ามซ้ำ (ตรวจผ่าน
check-db-name).
ที่มาในโค้ด
frontend/src/app/login/page.tsx:90-128,136-165- demo/Google loginfrontend/src/lib/safe-return.ts:6-13- กัน open redirectfrontend/src/app/select-database/page.tsx:141-142,189-231,286,325-434- เลือก/สร้างฐาน/สมาชิก/สิทธิ์frontend/src/app/api/auth/demo/route.ts:11-15- mint session demo
ดูเพิ่ม
ภาพรวม Frontend ของ SML Ai Account (Frontend overview) · เซสชันและการยืนยันตัวตนฝั่ง frontend (Auth session & tokens) · โครงหน้าเว็บและการนำทาง (App shell & routing) · เส้นทาง API ฝั่ง Next.js ที่ส่งต่อไป Go backend (API proxy routes) · หน้าจอผู้ดูแลระบบส่วนกลาง (Admin Console)