Skip to content

Commit

Permalink
feat: implement conditional webauthn login (#254)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mmx233 authored Feb 16, 2025
1 parent 15b2865 commit df1e3f2
Showing 1 changed file with 61 additions and 33 deletions.
94 changes: 61 additions & 33 deletions src/pages/login/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
Checkbox,
Icon,
} from "@hope-ui/solid"
import { createMemo, createSignal, Show } from "solid-js"
import { createMemo, createSignal, Show, onMount } from "solid-js"
import { SwitchColorMode, SwitchLanguageWhite } from "~/components"
import { useFetch, useT, useTitle, useRouter } from "~/hooks"
import {
Expand Down Expand Up @@ -99,10 +99,65 @@ const Login = () => {
r.get("/authn/webauthn_begin_login?username=" + username),
)
const { searchParams, to } = useRouter()
const isAuthnConditionalAvailable = async (): Promise<boolean> => {
if (
PublicKeyCredential &&
"isConditionalMediationAvailable" in PublicKeyCredential
) {
// @ts-expect-error
return await PublicKeyCredential.isConditionalMediationAvailable()
} else {
return false
}
}
const AuthnSignEnabled = getSettingBool("webauthn_login_enabled")
const AuthnSwitch = async () => {
setuseauthn(!useauthn())
}
const AuthnLogin = async (conditional?: boolean) => {
if (!supported()) {
if (!conditional) {
notify.error(t("users.webauthn_not_supported"))
}
return
}
if (conditional && !(await isAuthnConditionalAvailable())) {
return
}
changeToken()
const username_login: string = conditional ? "" : username()
if (!conditional && remember() === "true") {
localStorage.setItem("username", username())
} else {
localStorage.removeItem("username")
}
const resp = await getauthntemp(username_login)
handleResp(resp, async (data) => {
try {
const options = parseRequestOptionsFromJSON(data.options)
if (conditional) {
// @ts-expect-error
options.mediation = "conditional"
}
const credentials = await get(options)
const resp = await postauthnlogin(
data.session,
credentials,
username_login,
)
handleRespWithoutNotify(resp, (data) => {
notify.success(t("login.success"))
changeToken(data.token)
to(
decodeURIComponent(searchParams.redirect || base_path || "/"),
true,
)
})
} catch (error: unknown) {
if (error instanceof Error) notify.error(error.message)
}
})
}
const Login = async () => {
if (!useauthn()) {
if (remember() === "true") {
Expand Down Expand Up @@ -132,38 +187,7 @@ const Login = () => {
},
)
} else {
if (!supported()) {
notify.error(t("users.webauthn_not_supported"))
return
}
changeToken()
if (remember() === "true") {
localStorage.setItem("username", username())
} else {
localStorage.removeItem("username")
}
const resp = await getauthntemp(username())
handleResp(resp, async (data) => {
try {
const options = parseRequestOptionsFromJSON(data.options)
const credentials = await get(options)
const resp = await postauthnlogin(
data.session,
credentials,
username(),
)
handleRespWithoutNotify(resp, (data) => {
notify.success(t("login.success"))
changeToken(data.token)
to(
decodeURIComponent(searchParams.redirect || base_path || "/"),
true,
)
})
} catch (error: unknown) {
if (error instanceof Error) notify.error(error.message)
}
})
await AuthnLogin()
}
}
const [needOpt, setNeedOpt] = createSignal(false)
Expand All @@ -173,6 +197,10 @@ const Login = () => {
setUseLdap(true)
}

onMount(() => {
AuthnLogin(true)
})

return (
<Center zIndex="1" w="$full" h="100vh">
<VStack
Expand Down

0 comments on commit df1e3f2

Please sign in to comment.