ตรวจสอบการลงชื่อเข้าใช้
นี่คือขั้นตอนสำหรับ lead ไม่ใช่บันทึกว่า acceptance เสร็จแล้ว การตรวจ SQLite ในเครื่องและ response ของ frontend/Cypress ที่ใช้ stub ยืนยันได้เฉพาะพฤติกรรมในเครื่อง ไม่ยืนยันการส่งอีเมลจริง ความสำเร็จของ callback จาก provider หรือการตั้งค่า Cloudflare ห้ามทำขั้นตอนเหล่านี้โดยไม่มีสิทธิ์สำหรับ deployment และ test identity ที่เลือก
ก่อนเริ่ม
หัวข้อที่มีชื่อว่า “ก่อนเริ่ม”- ใช้ deployment สำหรับ acceptance และ test identity ที่ได้รับอนุญาต เก็บวิธีกู้คืน superadmin ที่ตรวจสอบแยกต่างหากไว้
- ยืนยันว่ามี Worker binding ที่ต้องใช้ผ่านกระบวนการตรวจการมีอยู่ของ secret ที่อนุมัติสำหรับ deployment บันทึกเฉพาะว่ามีหรือไม่มี ห้ามบันทึกค่า ตรวจวิธีที่เปิดใช้ที่หน้า การติดตั้ง ในส่วน วิธีเข้าสู่ระบบ
- ยืนยันว่า origin ของ frontend/backend และ callback registration ของ provider ตรงกับ deployment:
BACKEND_URL+/api/auth/callback/googleหรือ/api/auth/callback/github - ใช้ browser profile แยกสำหรับสอง session ของผู้ใช้เป้าหมาย, active superadmin คนที่สอง และ identity ที่ระบบไม่รู้จัก ลบ Access cookie จาก profile ที่ใช้ตรวจการเพิกถอนเฉพาะ session เพื่อไม่ให้ Access ยืนยันตัวตนให้ session ที่ถูกเพิกถอนได้เอง
- รัน
frontend/cypress/e2e/journey-account-security.cy.tsใน local rig ที่มีอยู่ Lead เป็นเจ้าของการรันและ live visual review ที่ 390×844 และ 1440×900: loading, empty, linked, error, email ยาว, confirmation, refusal, pending, success และ focus return assertion ที่ผ่านเพียงอย่างเดียวไม่ใช่ visual acceptance
Gate ของ provider จริง
หัวข้อที่มีชื่อว่า “Gate ของ provider จริง”| Gate | ขั้นตอน | ผลลัพธ์ที่ต้องได้ |
|---|---|---|
| การส่งจาก Resend | ขอ magic link สำหรับ identity ที่รู้จักและ active โดยเปิด magic link ไว้ รับอีเมลใน mailbox ที่ได้รับอนุญาตแล้วเปิดลิงก์ | อีเมลจริงมาถึง identity ของ CMS ที่คาดไว้เข้าสู่ระบบ และ protected request สำเร็จ HTTP acknowledgment จาก provider เพียงอย่างเดียวไม่ยืนยันการส่ง |
| การส่งคำเชิญและการพิสูจน์ที่อยู่ | ที่ การตั้งค่า → ผู้ใช้ เชิญ mailbox ที่ได้รับอนุญาต เปิดลิงก์จากอีเมล พิมพ์ที่อยู่นั้น และกรอกรหัสจากอีเมล แยกกัน ส่งต่อลิงก์ไปยัง mailbox ที่ได้รับอนุญาตอีกอันแล้วลองรับที่นั่น ลองลิงก์ที่ใช้แล้ว ที่ส่งใหม่ และที่ยกเลิกแล้วซ้ำ | อีเมลทั้งสองมาถึง การรับคำเชิญให้บทบาทที่เชิญบนไซต์นั้นเท่านั้น และรหัสผ่านใหม่เข้าสู่ระบบได้ ลิงก์ที่ส่งต่อรับไม่ได้หากไม่มีรหัสจาก mailbox ที่ได้รับเชิญ ลิงก์ที่ใช้แล้ว ถูกแทนที่ และถูกยกเลิกถูกปฏิเสธแบบเดียวกัน |
| การใช้ซ้ำและหมดอายุของ magic link | เปิดลิงก์ที่ใช้แล้วอีกครั้ง ขอสองลิงก์แล้วลองลิงก์เก่า แยกต่างหาก เก็บลิงก์ที่ยังไม่ใช้ให้นานเกินอายุ 15 นาทีแล้วลองใช้ | ลิงก์ที่ใช้แล้ว ถูกแทนที่ และหมดอายุสร้าง session ใหม่ไม่ได้ การขอด้วยที่อยู่ที่ไม่รู้จักให้ public response เหมือนกันและไม่สร้างบัญชี |
| Callback ของ Google | เข้าสู่ระบบด้วย Google identity จริงที่มี email ยืนยันแล้วตรงกับบัญชี CMS ที่เตรียมไว้ ลอง email อื่นที่ระบบไม่รู้จักและที่อยู่ที่ยังไม่ยืนยัน หาก provider อนุญาต fixture ที่ได้รับอนุญาต | เข้าสู่บัญชี CMS เดิมที่ตรงกัน ไม่สร้างบัญชีซ้ำหรือสมัครด้วย email ที่ไม่รู้จัก proof ที่ยังไม่ยืนยันถูกปฏิเสธ หากไม่มี fixture จริงที่ยังไม่ยืนยัน ให้ระบุ subcase ว่ายังไม่ตรวจ ห้ามใช้ stub แทนแล้วระบุว่าผ่าน acceptance |
| Callback ของ GitHub | ใช้ GitHub identity จริงที่มี primary email ยืนยันแล้วตรงกับบัญชี CMS ที่เตรียมไว้ ตรวจพฤติกรรมเมื่อซ่อน public email และเมื่อ primary email ไม่ตรงด้วย identity ที่ได้รับอนุญาต | ใช้ primary address ที่ยืนยันแล้วจาก GitHub การตรงกันเฉพาะ secondary address ไม่สามารถรับ identity ของ CMS ได้ identity ที่ไม่รู้จักหรือไม่ตรงถูกปฏิเสธ |
| OAuth replay/state ไม่ถูกต้อง | เปิด callback ที่ใช้แล้ว และ state ที่หมดอายุหรือไม่ถูกต้องซ้ำผ่าน browser โดยไม่เก็บ callback URL หรือ authorization code ในหลักฐาน | Proof ที่ใช้ซ้ำ ไม่ถูกต้อง หรือหมดอายุไม่สร้าง session หรือการเชื่อม provider |
| การเพิกถอนตอนเชื่อมและทิ้ง token | เข้าสู่ระบบผ่าน provider ที่เพิ่งเชื่อม ขณะที่มี CMS session เก่าในอีก profile ตรวจ session เก่ากับ protected API ทำการตรวจฐานข้อมูลที่ได้รับอนุญาตโดยดูเฉพาะ boolean ว่ามี provider token หรือไม่ | Session เก่าถูกปฏิเสธ คอลัมน์ access, refresh และ ID token ของ provider ยังเป็น null ห้าม export คอลัมน์หรือค่าของมัน |
| ยกเลิกการเชื่อมและเพิกถอน session | สร้างสอง CMS session สำหรับผู้ใช้คนเดียวกัน เปิดหน้า ความปลอดภัยของบัญชี ยกเลิกหนึ่งครั้ง แล้วจึงยืนยันยกเลิก Google ทำซ้ำแยกต่างหากสำหรับ GitHub ตรวจสอง session เก่าด้วย protected request | การยกเลิกไม่เปลี่ยนอะไร การยืนยันลบเฉพาะ connection ที่เลือกและเป็นของผู้เรียก ออกจากระบบ UI ที่เริ่มคำขอ และ session เก่าทั้งสองใช้ไม่ได้ Connection และ session ของผู้ใช้อื่นยังใช้ได้ เข้าสู่ระบบใหม่เพื่อตรวจ connection ที่เหลือ |
| ผู้ใช้ทั่วไปยกเลิก provider สุดท้าย | ใช้ผู้ใช้ทั่วไปที่มี OAuth connection เดียว ขณะที่ active superadmin แยกต่างหากยังมีวิธีที่ใช้ได้ | ยกเลิกสำเร็จและ session ของผู้ใช้เป้าหมายทั้งหมดสิ้นสุด การกู้คืนหรือการเข้าสู่ระบบภายหลังด้วย provider ที่มี email เดิมเป็นขั้นตอนแยก |
| Superadmin ที่ใช้ได้คนสุดท้าย | ใน deployment acceptance แบบ isolated ที่ได้รับอนุญาต ทำให้ provider เป้าหมายเป็นวิธีที่ใช้ได้เพียงวิธีเดียวใน active superadmin ทั้งหมด โดยเก็บทางกู้คืนของ operator ที่อนุมัติไว้ ลองยกเลิก จากนั้นสร้าง active superadmin อีกคนพร้อมวิธีที่ตรวจว่าใช้ได้แล้วลองซ้ำ | ครั้งแรกตอบ 409 would_lock_out_superadmins บัญชีและ session ยังอยู่ ครั้งที่สองสำเร็จได้แม้เป้าหมายไม่เหลือวิธีส่วนตัว วิธีอื่นที่ปิดใช้ ตั้งค่าไม่ครบ หรือยังไม่เชื่อมไม่นับ |
| พาสคีย์บนอุปกรณ์จริง | เมื่อเปิดพาสคีย์แล้ว เข้าสู่ระบบด้วยวิธีอื่นและเพิ่มพาสคีย์ที่หน้า ความปลอดภัยของบัญชี บนแล็ปท็อป (Touch ID หรือ Windows Hello) และบนโทรศัพท์ ออกจากระบบแล้วใช้ เข้าสู่ระบบด้วยพาสคีย์ บนแต่ละเครื่อง เปลี่ยนชื่อหนึ่งอันและลบอีกอัน ลองเพิ่มจาก session ที่เก่ากว่า 24 ชั่วโมง | แต่ละอุปกรณ์เข้าสู่ identity ของ CMS ที่คาดไว้โดยไม่ต้องพิมพ์ที่อยู่ พาสคีย์ที่ลบแล้วเข้าสู่ระบบไม่ได้ session เก่าถูกขอให้เข้าสู่ระบบใหม่ก่อนเพิ่ม |
| การกู้คืนเมื่ออุปกรณ์พาสคีย์หาย | ใช้บัญชีที่นอกจากพาสคีย์มีเพียงรหัสผ่าน ตัดการเข้าถึงอุปกรณ์ที่มีพาสคีย์ เข้าสู่ระบบด้วยรหัสผ่าน ลบพาสคีย์ที่หาย แล้วลองใช้อีกครั้ง เมื่อเปิดอีเมลและลิงก์เข้าสู่ระบบ ทำซ้ำกับบัญชีที่มีแต่พาสคีย์โดยใช้ลิงก์เข้าสู่ระบบทางอีเมลแทนรหัสผ่าน แยกกัน ปิดใช้งานบัญชีที่มีพาสคีย์แล้วลองเข้าสู่ระบบด้วยพาสคีย์นั้น | เข้าสู่ระบบด้วยรหัสผ่านได้ และพาสคีย์ที่ลบแล้วถูกปฏิเสธ วิธีสุดท้ายที่เหลือลบไม่ได้ บัญชีที่ถูกปิดใช้งานไม่ได้รับ session |
| Claim ผู้ดูแลคนแรกเมื่อรับการติดตั้งใหม่ | ใน instance ใหม่ที่ได้รับอนุญาตแยกกัน ใช้ claim ที่ผูกไว้กับแต่ละวิธีที่เลือก ลอง email ผิด claim ที่ใช้แล้วและหมดอายุ ห้าม reset deployment ที่มีอยู่เพื่อการตรวจนี้ | เฉพาะ email ที่ผูกไว้สร้าง superadmin คนแรกได้ การใช้ซ้ำ/หมดอายุล้มเหลว การเข้าสู่ระบบปกติไม่สร้างผู้ใช้ |
หลักฐานที่ปลอดภัย
หัวข้อที่มีชื่อว่า “หลักฐานที่ปลอดภัย”บันทึก label/version ของ deployment วันที่ วิธี scenario ผลที่คาดและสังเกต status/reason ของ response และ pass/fail/unverified Screenshot แสดง UI state ได้เมื่อปิดบัง personal address บันทึกเฉพาะ boolean/count comparison สำหรับ invariant ของบัญชี/session ผ่าน access ที่ได้รับอนุญาต
ห้ามเก็บ cookie, session token, password, claim link, ลิงก์ในอีเมล, OAuth code/state, provider identity id, provider token, ค่า secret, database dump เต็ม หรือ HAR/network export ที่ยังไม่ปิดบัง Browser profile ที่ถือ acceptance session เป็นสิ่งที่มี credential และควรปิดหรือออกจากระบบหลังตรวจ
Gate ที่ยังเปิดอยู่
หัวข้อที่มีชื่อว่า “Gate ที่ยังเปิดอยู่”- Focused Cypress ที่ lead รันและ live visual review ทั้งสอง viewport
- Acceptance จริงของ Resend (magic link และคำเชิญ), Google, GitHub และพาสคีย์บนอุปกรณ์จริง รวม negative/replay/expiry case ที่เกี่ยวข้องข้างต้น
- การยืนยันว่ามี secret ใน Cloudflare จริง
- Deployment ของเว็บไซต์เอกสารหลัง owner gate ตามปกติ
บันทึกผลแยกต่างหากเมื่อทำ ขั้นตอนนี้ไม่ได้อ้างว่า deployment หรือ provider สำเร็จ
ยังไม่เปิดตัว (pre-MVP) และยังไม่มีเวอร์ชันเสถียร
คอมมิตซอร์สโค้ด: fe23db481c422b40e317b92fc98116b4c0c26a87 (มีการแก้ไขที่ยังไม่คอมมิต)
วันที่สร้างเอกสาร (UTC): 2026-10-18T09:22:34.630Z
คอมมิตสำหรับอัปเกรด: ระบุไม่ได้: มีการแก้ไขที่ยังไม่คอมมิต. บันทึกการเปลี่ยนแปลง