feat: auto-start feishu login in client
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import type { FormEvent } from "react"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
import { useEffect, useMemo, useRef, useState } from "react"
|
||||
import {
|
||||
ArrowRight,
|
||||
Building2,
|
||||
@@ -21,8 +21,26 @@ type AuthConfig = {
|
||||
feishu_enabled?: boolean
|
||||
}
|
||||
|
||||
function normalizeNextPath(value: string | null | undefined) {
|
||||
const next = (value || "/").trim() || "/"
|
||||
if (!next.startsWith("/") || next.startsWith("//")) return "/"
|
||||
return next
|
||||
}
|
||||
|
||||
function loginNextPath() {
|
||||
if (typeof window === "undefined") return "/"
|
||||
return normalizeNextPath(new URLSearchParams(window.location.search).get("next"))
|
||||
}
|
||||
|
||||
function isFeishuClient() {
|
||||
if (typeof window === "undefined") return false
|
||||
const ua = window.navigator.userAgent.toLowerCase()
|
||||
return ua.includes("feishu") || ua.includes("lark")
|
||||
}
|
||||
|
||||
export default function LoginPage() {
|
||||
const [authConfig, setAuthConfig] = useState<AuthConfig | null>(null)
|
||||
const [nextPath] = useState(loginNextPath)
|
||||
const [username, setUsername] = useState("")
|
||||
const [password, setPassword] = useState("")
|
||||
const [remember, setRemember] = useState(true)
|
||||
@@ -31,6 +49,7 @@ export default function LoginPage() {
|
||||
const [hasError, setHasError] = useState(false)
|
||||
const [status, setStatus] = useState<LoginStatus>("idle")
|
||||
const [eyeOffset, setEyeOffset] = useState({ x: 0, y: 0 })
|
||||
const autoFeishuAttemptedRef = useRef(false)
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
@@ -63,6 +82,16 @@ export default function LoginPage() {
|
||||
const feishuEnabled = Boolean(authConfig?.feishu_enabled)
|
||||
const passwordEnabled = authConfig?.password_enabled ?? true
|
||||
|
||||
useEffect(() => {
|
||||
if (!feishuEnabled || status !== "idle" || autoFeishuAttemptedRef.current || !isFeishuClient()) return
|
||||
const attemptKey = `skg-feishu-auto-login:${nextPath}`
|
||||
if (window.sessionStorage.getItem(attemptKey) === "1") return
|
||||
window.sessionStorage.setItem(attemptKey, "1")
|
||||
autoFeishuAttemptedRef.current = true
|
||||
setStatus("loading")
|
||||
window.location.href = `/api/auth/feishu/start?next=${encodeURIComponent(nextPath)}`
|
||||
}, [feishuEnabled, nextPath, status])
|
||||
|
||||
const mood: LoginCharacterMood = useMemo(() => {
|
||||
if (status === "success") return "success"
|
||||
if (hasError) return "error"
|
||||
@@ -92,7 +121,7 @@ export default function LoginPage() {
|
||||
}
|
||||
setStatus("success")
|
||||
window.setTimeout(() => {
|
||||
window.location.href = "/"
|
||||
window.location.href = nextPath
|
||||
}, 420)
|
||||
} catch {
|
||||
setStatus("idle")
|
||||
@@ -102,7 +131,7 @@ export default function LoginPage() {
|
||||
|
||||
function onFeishuLogin() {
|
||||
setStatus("loading")
|
||||
window.location.href = "/api/auth/feishu/start?next=/"
|
||||
window.location.href = `/api/auth/feishu/start?next=${encodeURIComponent(nextPath)}`
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user