import {
Alert,
AlertDescription,
AlertIcon,
AlertTitle,
Badge,
Button,
FormControl,
FormHelperText,
FormLabel,
Heading,
HStack,
Input,
SimpleGrid,
VStack,
Text,
} from "@hope-ui/solid"
import { createSignal, For, JSXElement, onCleanup, Show } from "solid-js"
import { LinkWithBase, MaybeLoading } from "~/components"
import { useFetch, useManageTitle, useRouter, useT } from "~/hooks"
import { setMe, me, getSettingBool } from "~/store"
import { PEmptyResp, UserMethods, UserPermissions, PResp } from "~/types"
import { handleResp, handleRespWithoutNotify, notify, r } from "~/utils"
import { WebauthnItem } from "./Webauthnitems"
import {
RegistrationPublicKeyCredential,
create,
parseCreationOptionsFromJSON,
supported,
CredentialCreationOptionsJSON,
} from "@github/webauthn-json/browser-ponyfill"
import { PublicKeys } from "./PublicKeys"
const PermissionBadge = (props: { can: boolean; children: JSXElement }) => {
return (
{props.children}
)
}
const Profile = () => {
const t = useT()
useManageTitle("manage.sidemenu.profile")
const { searchParams, to } = useRouter()
const [username, setUsername] = createSignal(me().username)
const [password, setPassword] = createSignal("")
const [confirmPassword, setConfirmPassword] = createSignal("")
const usecompatibility = getSettingBool("sso_compatibility_mode")
const [loading, save] = useFetch(
(ssoID?: boolean): PEmptyResp =>
r.post("/me/update", {
username: ssoID ? me().username : username(),
password: ssoID ? "" : password(),
sso_id: me().sso_id,
}),
)
interface WebauthnItem {
fingerprint: string
id: string
}
interface Webauthntemp {
session: string
options: CredentialCreationOptionsJSON
}
const [getauthncredentialsloading, getauthncredentials] = useFetch(
(): PResp => r.get("/authn/getcredentials"),
)
const [, getauthntemp] = useFetch(
(): PResp => r.get("/authn/webauthn_begin_registration"),
)
const [postregistrationloading, postregistration] = useFetch(
(
session: string,
credentials: RegistrationPublicKeyCredential,
): PEmptyResp =>
r.post(
"/authn/webauthn_finish_registration",
JSON.stringify(credentials),
{
headers: {
session: session,
},
},
),
)
const saveMe = async (ssoID?: boolean) => {
if (password() && password() !== confirmPassword()) {
notify.warning(t("users.confirm_password_not_same"))
return
}
const resp = await save(ssoID)
handleResp(resp, () => {
setMe({ ...me(), username: username() })
if (!ssoID) {
notify.success(t("users.update_profile_success"))
to(`/@login?redirect=${encodeURIComponent(location.pathname)}`)
} else {
to("")
}
})
}
const ssoID = searchParams["sso_id"]
if (ssoID) {
setMe({ ...me(), sso_id: ssoID })
saveMe(true)
}
function messageEvent(event: MessageEvent) {
const data = event.data
if (data.sso_id) {
setMe({ ...me(), sso_id: data.sso_id })
saveMe(true)
}
}
window.addEventListener("message", messageEvent)
onCleanup(() => {
window.removeEventListener("message", messageEvent)
})
const [credentials, setcredentials] = createSignal([])
const initauthnEdit = async () => {
const resp = await getauthncredentials()
handleRespWithoutNotify(resp, setcredentials)
}
if (
supported() &&
!UserMethods.is_guest(me()) &&
getSettingBool("webauthn_login_enabled")
) {
initauthnEdit()
}
return (
{t("users.guest-tips")}
{t("users.modify_nothing")}
{t("global.have_account")}
{t("global.go_login")}
>
}
>
{t("users.update_profile")}
{t("users.change_username")}
{
setUsername(e.currentTarget.value)
}}
/>
{t("users.change_password")}
{
setPassword(e.currentTarget.value)
}}
/>
{t("users.change_password-tips")}
{t("users.confirm_password")}
{
setConfirmPassword(e.currentTarget.value)
}}
/>
{t("users.confirm_password-tips")}
{t("users.sso_login")}
{
const url = r.getUri() + "/auth/sso?method=get_sso_id"
if (usecompatibility) {
window.location.href = url
return
}
window.open(url, "authPopup", "width=500,height=600")
}}
>
{t("users.connect_sso")}
}
>
{t("users.webauthn")}
{(item) => (
)}
{(item, i) => (
{t(`users.permissions.${item}`)}
)}
)
}
export default Profile