灵符lingfu
F

fu.ling-lang.org

↓ 0 downloads

ทะเบียนแพ็กเกจ fu.ling-lang.org — เขียนด้วยภาษา Ling (ไทย) ทั้งหมด

Keywords registry, packages, web, ling, thai
lingfu install fu.ling-lang.org
LicenseApache-2.0 OR MIT
Authorsลิงลิน
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (22)

controllers/auth.ling
// controllers/auth.ling — บัญชี, เข้าสู่ระบบ, 2FA (บังคับ), ออกจากระบบ

// ── ตัวช่วยเซสชัน: คืนแถวผู้ใช้ปัจจุบัน (id, username, stage, totp_secret) หรือ []
ฟังก์ชัน ผู้ใช้ปัจจุบัน(คำขอ) {
    ผูก โทเคน = cookie_get(คำขอ.cookie, "sid", "")
    คืน เซสชันผู้ใช้(โทเคน)
}

// คืน 1 ถ้าล็อกอินสมบูรณ์ (stage = active), ไม่งั้น 0
ฟังก์ชัน เข้าสู่ระบบแล้ว(คำขอ) {
    ผูก ส = ผู้ใช้ปัจจุบัน(คำขอ)
    ถ้า ส.len == 0 {
        คืน 0
    }
    ผูก ผ = รับรายการ(ส, 0)
    ถ้า ผ.stage == "active" {
        คืน 1
    }
    คืน 0
}

ฟังก์ชัน คุกกี้เซสชัน(โทเคน) {
    คืน "sid=" + โทเคน + "; HttpOnly; Path=/; SameSite=Lax; Max-Age=604800"
}

// ── GET /register ──
ฟังก์ชัน หน้าลงทะเบียน(คำขอ) {
    คืน เปลือก(คำขอ, "ลงทะเบียน",
        "<div class='auth-box'><h1>สร้างบัญชี</h1>" +
        "<form method='post' action='/register' class='form'>" +
        "<label>ชื่อผู้ใช้<input name='username' required></label>" +
        "<label>อีเมล<input name='email' type='email' required></label>" +
        "<label>รหัสผ่าน<input name='password' type='password' required></label>" +
        "<button type='submit'>ลงทะเบียนและตั้งค่า 2FA</button>" +
        "</form>" +
        "<p class='muted'>ทุกบัญชีต้องเปิดใช้ 2FA — ขั้นต่อไปจะแสดงกุญแจลับ</p>" +
        "<p><a href='/login'>มีบัญชีแล้ว? เข้าสู่ระบบ</a></p></div>")
}

// ── POST /register ──
ฟังก์ชัน ทำลงทะเบียน(คำขอ) {
    ผูก ชื่อ = query_param(คำขอ.body, "username", "")
    ผูก อีเมล = query_param(คำขอ.body, "email", "")
    ผูก รหัส = query_param(คำขอ.body, "password", "")
    ถ้า ชื่อ == "" {
        คืน ตอบผิด(คำขอ, "กรอกชื่อผู้ใช้")
    }
    ถ้า รหัส == "" {
        คืน ตอบผิด(คำขอ, "กรอกรหัสผ่าน")
    }
    ถ้า ผู้ใช้มีอยู่(ชื่อ) {
        คืน ตอบผิด(คำขอ, "ชื่อผู้ใช้หรืออีเมลนี้ถูกใช้แล้ว")
    }
    ผูก ความลับ = totp_secret()
    ผูก ไอดี = ผู้ใช้สร้าง(ชื่อ, อีเมล, รหัส, ความลับ)
    ถ้า ไอดี == 0 {
        คืน ตอบผิด(คำขอ, "สร้างบัญชีไม่สำเร็จ")
    }
    // สร้างเซสชันขั้น 'pending_2fa' แล้วพาไปหน้าตั้งค่า 2FA
    ผูก โทเคน = เซสชันสร้าง(ไอดี, "pending_2fa")
    คืน ตอบคุกกี้(302, "", "text/html", คุกกี้เซสชัน(โทเคน), "/2fa/setup")
}

// ── GET /2fa/setup — แสดงกุญแจลับ + otpauth URI ──
ฟังก์ชัน หน้าตั้ง2fa(คำขอ) {
    ผูก ส = ผู้ใช้ปัจจุบัน(คำขอ)
    ถ้า ส.len == 0 {
        คืน เปลี่ยนเส้นทาง("/login")
    }
    ผูก ผ = รับรายการ(ส, 0)
    ผูก ยูอาร์ไอ = totp_uri(ผ.totp_secret, ผ.username, "fu.ling-lang.org")
    คืน เปลือก(คำขอ, "ตั้งค่า 2FA",
        "<div class='auth-box'><h1>ตั้งค่า 2FA</h1>" +
        "<p>เพิ่มบัญชีนี้ในแอป Authenticator (Google Authenticator, Authy ฯลฯ)</p>" +
        "<div class='secret'>กุญแจลับ: <code>" + ผ.totp_secret + "</code></div>" +
        "<div class='muted otpauth'><code>" + ยูอาร์ไอ + "</code></div>" +
        "<form method='post' action='/2fa/setup' class='form'>" +
        "<label>รหัส 6 หลักจากแอป<input name='code' inputmode='numeric' pattern='[0-9]{6}' required></label>" +
        "<button type='submit'>ยืนยันและเปิดใช้งาน</button>" +
        "</form></div>")
}

// ── POST /2fa/setup — ยืนยันโค้ด, เปิดใช้บัญชี ──
ฟังก์ชัน ทำตั้ง2fa(คำขอ) {
    ผูก ส = ผู้ใช้ปัจจุบัน(คำขอ)
    ถ้า ส.len == 0 {
        คืน เปลี่ยนเส้นทาง("/login")
    }
    ผูก ผ = รับรายการ(ส, 0)
    ผูก โค้ด = query_param(คำขอ.body, "code", "")
    ถ้า totp_verify(ผ.totp_secret, โค้ด) {
        ผู้ใช้ยืนยัน2fa(ผ.id)
        ผูก โทเคน = cookie_get(คำขอ.cookie, "sid", "")
        เซสชันเลื่อนขั้น(โทเคน)
        คืน เปลี่ยนเส้นทาง("/me/packages")
    }
    คืน ตอบผิด(คำขอ, "รหัสไม่ถูกต้อง ลองใหม่")
}

// ── GET /login ──
ฟังก์ชัน หน้าเข้าสู่ระบบ(คำขอ) {
    คืน เปลือก(คำขอ, "เข้าสู่ระบบ",
        "<div class='auth-box'><h1>เข้าสู่ระบบ</h1>" +
        "<form method='post' action='/login' class='form'>" +
        "<label>ชื่อผู้ใช้<input name='username' required></label>" +
        "<label>รหัสผ่าน<input name='password' type='password' required></label>" +
        "<label>รหัส 2FA (6 หลัก)<input name='code' inputmode='numeric' pattern='[0-9]{6}' required></label>" +
        "<button type='submit'>เข้าสู่ระบบ</button>" +
        "</form>" +
        "<p><a href='/register'>ยังไม่มีบัญชี? ลงทะเบียน</a></p></div>")
}

// ── POST /login — ตรวจรหัสผ่าน + 2FA พร้อมกัน ──
ฟังก์ชัน ทำเข้าสู่ระบบ(คำขอ) {
    ผูก ชื่อ = query_param(คำขอ.body, "username", "")
    ผูก รหัส = query_param(คำขอ.body, "password", "")
    ผูก โค้ด = query_param(คำขอ.body, "code", "")
    ผูก ผลตรวจ = ผู้ใช้ตรวจรหัส(ชื่อ, รหัส)
    ถ้า ผลตรวจ.len == 0 {
        คืน ตอบผิด(คำขอ, "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง")
    }
    ผูก ผ = รับรายการ(ผลตรวจ, 0)
    ถ้า ผ.totp_confirmed == 0 {
        คืน ตอบผิด(คำขอ, "บัญชีนี้ยังไม่ได้ตั้งค่า 2FA")
    }
    ถ้า totp_verify(ผ.totp_secret, โค้ด) {
        ผูก โทเคน = เซสชันสร้าง(ผ.id, "active")
        คืน ตอบคุกกี้(302, "", "text/html", คุกกี้เซสชัน(โทเคน), "/me/packages")
    }
    คืน ตอบผิด(คำขอ, "รหัส 2FA ไม่ถูกต้อง")
}

// ── GET /logout ──
ฟังก์ชัน ทำออกจากระบบ(คำขอ) {
    ผูก โทเคน = cookie_get(คำขอ.cookie, "sid", "")
    เซสชันลบ(โทเคน)
    คืน ตอบคุกกี้(302, "", "text/html", "sid=; Path=/; Max-Age=0", "/")
}

// ── ตัวช่วยตอบกลับ ──
ฟังก์ชัน ตอบผิด(คำขอ, ข้อความ) {
    คืน ตอบ(400, เปลือก(คำขอ, "ผิดพลาด",
        "<div class='auth-box'><div class='error'>" + html_escape(ข้อความ) + "</div>" +
        "<p><a href='/register'>ลงทะเบียน</a> · <a href='/login'>เข้าสู่ระบบ</a></p></div>"),
        "text/html; charset=utf-8")
}

ฟังก์ชัน เปลี่ยนเส้นทาง(ที่อยู่) {
    คืน ตอบคุกกี้(302, "", "text/html", "", ที่อยู่)
}

← Back to index