add client-side login

This commit is contained in:
Henry Hiles 2025-06-19 16:44:08 -04:00
commit d1a6802852
No known key found for this signature in database
2 changed files with 70 additions and 18 deletions

View file

@ -6,12 +6,11 @@ import "../styles/login.css"
<StarlightPage
frontmatter={{ title: "Sign In to Federated Nexus", template: "splash" }}
>
<form method="post" action="http://auth.federated.nexus/login">
<input type="hidden" name="nonce" />
<input type="hidden" name="scope" />
<input type="hidden" name="state" />
<input type="hidden" name="client_id" />
<form method="post" action="https://auth.federated.nexus/login">
<input type="hidden" name="redirect_uri" />
<input type="hidden" name="state" />
<input type="hidden" name="user_id" />
<input type="hidden" name="access_token" />
<label>
Username
@ -22,9 +21,8 @@ import "../styles/login.css"
<input type="password" name="password" />
</label>
<button class="sl-link-button astro-e5owd36c primary" type="submit">
Submit
</button>
<span id="error"></span>
<button type="submit"><span>Submit</span></button>
<a href="/">Don't have an account? Apply at our home page.</a>
</form>
@ -32,18 +30,57 @@ import "../styles/login.css"
<script>
const params = new URLSearchParams(window.location.search)
for (const name of [
"client_id",
"nonce",
"scope",
"redirect_uri",
"state",
]) {
for (const name of ["redirect_uri", "state"]) {
const input = document.querySelector(
`input[name="${name}"]`
) as HTMLInputElement
if (input && params.has(name)) input.value = params.get(name)!
}
const form = document.querySelector("form")!
const error = document.querySelector("#error")! as HTMLSpanElement
form.addEventListener("submit", async (e) => {
e.preventDefault()
error.style.display = "none"
const username = form.username.value
const password = form.password.value
try {
const res = await fetch(
"https://matrix.federated.nexus/_matrix/client/v3/login",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
type: "m.login.password",
identifier: { type: "m.id.user", user: username },
password,
}),
}
)
if (!res.ok) {
throw new Error((await res.json())["error"])
}
const data = await res.json()
const id = form.querySelector(
'input[name="user_id"]'
) as HTMLInputElement
id.value = data.user_id
const token = form.querySelector(
'input[name="access_token"]'
) as HTMLInputElement
token.value = "data.access_token"
form.submit()
} catch (err: any) {
error.textContent = err.message || "Login failed"
error.style.display = "block"
}
})
</script>

View file

@ -19,8 +19,23 @@ body {
}
& button {
margin-top: 1.4rem;
margin: 1.4rem 0;
cursor: pointer;
border: none;
border-radius: 999rem;
gap: 0.5em;
line-height: 1.2;
background: var(--sl-color-text-accent);
color: var(--sl-color-black);
font-size: var(--sl-text-base);
padding: 1rem 1.25rem;
}
& #error {
margin-top: 1rem;
color: var(--sl-color-red);
}
}
}