-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
169 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,140 +1,192 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta | ||
name="viewport" | ||
content="width=device-width, initial-scale=1, maximum-scale=1" | ||
/> | ||
<link rel="icon" type="image/x-icon" href="/favicon.png" /> | ||
<title>Login to SilverBullet</title> | ||
<style> | ||
html, | ||
body { | ||
font-family: | ||
-apple-system, | ||
BlinkMacSystemFont, | ||
"Segoe UI", | ||
Roboto, | ||
"Helvetica Neue", | ||
Arial, | ||
"Noto Sans", | ||
sans-serif, | ||
"Apple Color Emoji", | ||
"Segoe UI Emoji", | ||
"Segoe UI Symbol", | ||
"Noto Color Emoji"; | ||
border: 0; | ||
margin: 0; | ||
} | ||
|
||
footer { | ||
margin-top: 10px; | ||
} | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /> | ||
<link rel="icon" type="image/x-icon" href="/favicon.png" /> | ||
<title>Login to SilverBullet</title> | ||
<style> | ||
*, | ||
*::before, | ||
*::after { | ||
box-sizing: border-box; | ||
} | ||
|
||
header { | ||
background-color: #e1e1e1; | ||
border-bottom: #cacaca 1px solid; | ||
} | ||
* { | ||
padding: 0; | ||
margin: 0; | ||
} | ||
|
||
h1 { | ||
margin: 0; | ||
margin: 0 auto; | ||
max-width: 800px; | ||
padding: 8px; | ||
font-size: 28px; | ||
font-weight: normal; | ||
} | ||
html { | ||
font-family: | ||
-apple-system, | ||
BlinkMacSystemFont, | ||
"Segoe UI", | ||
Roboto, | ||
"Helvetica Neue", | ||
Arial, | ||
"Noto Sans", | ||
sans-serif, | ||
"Apple Color Emoji", | ||
"Segoe UI Emoji", | ||
"Segoe UI Symbol", | ||
"Noto Color Emoji"; | ||
background-color: #fefefe; | ||
--primary-button-color: #eee; | ||
--primary-button-background-color: #464cfc; | ||
--primary-button-hover-background-color: color-mix(in srgb, | ||
var(--primary-button-background-color), | ||
black 35%); | ||
--primary-button-border-color: transparent; | ||
--modal-border-color: #6c6c6c; | ||
} | ||
|
||
header { | ||
position: absolute; | ||
padding: 1rem; | ||
font-size: 1.2rem; | ||
} | ||
|
||
footer { | ||
text-align: center; | ||
} | ||
|
||
h1 { | ||
font-size: 1.5rem; | ||
font-weight: normal; | ||
} | ||
|
||
input { | ||
font-family: inherit; | ||
font-size: inherit; | ||
padding: 0.5em; | ||
} | ||
|
||
form>div { | ||
display: flex; | ||
flex-direction: column; | ||
flex-grow: 1; | ||
} | ||
|
||
button { | ||
background: var(--primary-button-background-color); | ||
color: var(--primary-button-color); | ||
box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.05); | ||
border: 1px solid var(--border-color); | ||
padding: 0.7em; | ||
border-radius: 0.5em; | ||
|
||
form { | ||
max-width: 800px; | ||
margin: 0 auto; | ||
padding: 10px; | ||
&:hover { | ||
background-color: var(--primary-button-hover-background-color); | ||
} | ||
|
||
input { | ||
font-size: 18px; | ||
&:focus { | ||
outline: 2px solid var(--primary-button-color); | ||
outline-offset: -3px; | ||
} | ||
} | ||
|
||
form > div { | ||
margin-bottom: 5px; | ||
.error-message { | ||
color: red; | ||
} | ||
|
||
.center { | ||
height: 100vh; | ||
display: grid; | ||
place-items: center; | ||
} | ||
|
||
@media (min-width: 28em) { | ||
html { | ||
--top-color: #66A3BB; | ||
--bottom-color: #0B3A69; | ||
background: linear-gradient(var(--top-color), var(--bottom-color)); | ||
} | ||
|
||
.error-message { | ||
color: red; | ||
.floating-island { | ||
padding: 3em; | ||
border-radius: 8px; | ||
box-shadow: rgba(0, 0, 0, 0.35) 0px 20px 20px; | ||
background-color: white; | ||
border: var(--modal-border-color) 1px solid; | ||
} | ||
</style> | ||
</head> | ||
} | ||
} | ||
|
||
.flow { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-start; | ||
} | ||
|
||
.flow>* { | ||
margin-block: 0; | ||
} | ||
|
||
.flow>*+* { | ||
margin-block-start: var(--space, 1rem); | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<header> | ||
<body> | ||
<div class="center"> | ||
<div class="flow floating-island"> | ||
<h1> | ||
Login to <img src="/.client/logo.png" style="height: 1ch" /> | ||
SilverBullet | ||
</h1> | ||
</header> | ||
<form action="/.auth" method="POST" id="login"> | ||
<div class="error-message"></div> | ||
<div> | ||
<label for="username"> | ||
Username | ||
</label> | ||
<input | ||
type="text" | ||
name="username" | ||
id="username" | ||
autocomplete="off" | ||
autocorrect="off" | ||
autocapitalize="off" | ||
autofocus | ||
/> | ||
</div> | ||
<div> | ||
<label for="password"> | ||
Password | ||
</label> | ||
<input | ||
type="password" | ||
name="password" | ||
id="password" | ||
/> | ||
</div> | ||
<div> | ||
<input type="checkbox" name="rememberMe" id="rememberMe" /> | ||
<label for="rememberMe">Remember me</label> | ||
</div> | ||
<div> | ||
<input type="submit" value="Login" /> | ||
</div> | ||
<form action="/.auth" method="POST" id="login" class="flow"> | ||
<div class="error-message"></div> | ||
<div> | ||
<label for="username"> | ||
Username | ||
</label> | ||
<input type="text" name="username" id="username" autocomplete="off" autocorrect="off" autocapitalize="off" | ||
autofocus /> | ||
</div> | ||
<div> | ||
<label for="password"> | ||
Password | ||
</label> | ||
<input type="password" name="password" id="password" /> | ||
</div> | ||
<div style="--space: 1.8rem"> | ||
<button>Login</button> | ||
</div> | ||
</form> | ||
<footer> | ||
<a href="https://silverbullet.md">What is SilverBullet?</a> | ||
</footer> | ||
</form> | ||
|
||
<script> | ||
const params = new URLSearchParams(window.location.search); | ||
|
||
const error = params.get("error"); | ||
if (error === "0") { | ||
document.querySelector(".error-message").innerText = | ||
"The sent data was invalid"; | ||
} else if (error === "1") { | ||
document.querySelector(".error-message").innerText = | ||
"Invalid username or password"; | ||
} else if (error === "2") { | ||
document.querySelector(".error-message").innerText = | ||
"Too many invalid logins. Try again later"; | ||
} | ||
</div> | ||
</div> | ||
|
||
const from = params.get("from"); | ||
if (from) { | ||
var input = document.createElement("input"); | ||
input.setAttribute("type", "hidden"); | ||
input.setAttribute("name", "from"); | ||
input.setAttribute("value", from); | ||
<script> | ||
const params = new URLSearchParams(window.location.search); | ||
|
||
document.getElementById("login").appendChild(input); | ||
} | ||
</script> | ||
</body> | ||
</html> | ||
const error = params.get("error"); | ||
if (error === "0") { | ||
document.querySelector(".error-message").innerText = | ||
"The sent data was invalid"; | ||
} else if (error === "1") { | ||
document.querySelector(".error-message").innerText = | ||
"Invalid username or password"; | ||
} else if (error === "2") { | ||
document.querySelector(".error-message").innerText = | ||
"Too many invalid logins. Try again later"; | ||
} | ||
|
||
const from = params.get("from"); | ||
if (from) { | ||
var input = document.createElement("input"); | ||
input.setAttribute("type", "hidden"); | ||
input.setAttribute("name", "from"); | ||
input.setAttribute("value", from); | ||
|
||
document.getElementById("login").appendChild(input); | ||
} | ||
</script> | ||
</body> | ||
|
||
</html> |