refactor: require password verification
chore: styling work
This commit is contained in:
parent
7977fe9ea7
commit
86fa2b6d4b
16 changed files with 348 additions and 88 deletions
|
|
@ -41,13 +41,6 @@ export async function GET(request: Request, meta: Record<string, any>): Promise<
|
|||
event_id
|
||||
} = /^.*\/events\/.*\/(?<event_type>.*?)\:(?<event_id>[A-Za-z-]+)\.json$/.exec(entry.path)?.groups ?? {};
|
||||
|
||||
console.dir({
|
||||
entry,
|
||||
event_type,
|
||||
event_id,
|
||||
query: meta.query
|
||||
});
|
||||
|
||||
if (meta.query.after_id && event_id <= meta.query.after_id) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,22 @@ export async function POST(req: Request, meta: Record<string, any>): Promise<Res
|
|||
});
|
||||
}
|
||||
|
||||
const password_verification_hash: string = body.password_verification_hash ?? (typeof body.password_verification === 'string'
|
||||
? encodeBase64(
|
||||
await crypto.subtle.digest('SHA-256', new TextEncoder().encode(body.password_verification))
|
||||
)
|
||||
: '');
|
||||
if (password_verification_hash !== password_hash) {
|
||||
return Response.json({
|
||||
error: {
|
||||
cause: 'invalid password verification hash',
|
||||
message: 'Password and verification must be identical.'
|
||||
}
|
||||
}, {
|
||||
status: 400
|
||||
});
|
||||
}
|
||||
|
||||
const at_least_one_existing_user = (await USERS.all({
|
||||
limit: 1,
|
||||
offset: 0
|
||||
|
|
|
|||
|
|
@ -2,45 +2,61 @@
|
|||
:root {
|
||||
--base-color: #234;
|
||||
|
||||
--bg: hsl(from var(--base-color) h 20% 7.5%);
|
||||
--bg-darker: hsl(from var(--base-color) h 20% 5%);
|
||||
--bg-lighter: hsl(from var(--base-color) h 20% 10%);
|
||||
--bg: hsl(from var(--base-color) h 20% 10%);
|
||||
--bg-darker: hsl(from var(--base-color) h 20% 7.5%);
|
||||
--bg-lighter: hsl(from var(--base-color) h 20% 12.5%);
|
||||
--bg-card: hsl(from var(--base-color) h 20% 15%);
|
||||
--bg-card-hover: hsl(from var(--base-color) h 20% 16%);
|
||||
|
||||
--text-primary: hsl(from var(--base-color) h 5% 95%);
|
||||
--text-secondary: hsl(from var(--base-color) h 5% 85%);
|
||||
--text-muted: hsl(from var(--base-color) h 5% 75%);
|
||||
|
||||
--accent: hsl(from var(--base-color) h clamp(0, calc(s + 10), 100) clamp(0, calc(l + 20), 100));
|
||||
--accent-dark: hsl(from var(--base-color) h clamp(0, calc(s + 5), 100) clamp(0, calc(l - 5), 100));
|
||||
|
||||
--border-subtle: hsl(from var(--base-color) h 50% 90%);
|
||||
--border-normal: hsl(from var(--base-color) h 50% 80%);
|
||||
--border-highlight: hsl(from var(--base-color) h 50% 25%);
|
||||
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
|
||||
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.1);
|
||||
|
||||
--blur-radius: 8px;
|
||||
|
||||
--text: hsl(from var(--base-color) h 5% 100%);
|
||||
--accent: hsl(from var(--base-color) h clamp(0, calc(s + 10), 100) clamp(0, calc(l + 20), 100));
|
||||
|
||||
--border-subtle: hsl(from var(--base-color) h 50% 25%);
|
||||
--border-normal: hsl(from var(--base-color) h 50% 50%);
|
||||
--border-highlight: hsl(from var(--base-color) h 50% 75%);
|
||||
|
||||
--icon-scale: 1;
|
||||
--border-radius: 4px;
|
||||
--border-radius: 8px;
|
||||
--border-radius-lg: 12px;
|
||||
|
||||
--space-xxs: 0.25rem;
|
||||
--space-xs: 0.5rem;
|
||||
--space-sm: 0.75rem;
|
||||
--space-md: 1rem;
|
||||
--space-lg: 1.5rem;
|
||||
--space-xl: 2rem;
|
||||
--space-xxl: 3rem;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--bg: hsl(from var(--base-color) h 20% 93%);
|
||||
--bg-darker: hsl(from var(--base-color) h 20% 88%);
|
||||
--bg-lighter: hsl(from var(--base-color) h 20% 98%);
|
||||
--bg: hsl(from var(--base-color) h 20% 98%);
|
||||
--bg-darker: hsl(from var(--base-color) h 20% 96%);
|
||||
--bg-lighter: hsl(from var(--base-color) h 20% 99%);
|
||||
--bg-card: hsl(from var(--base-color) h 20% 100%);
|
||||
--bg-card-hover: hsl(from var(--base-color) h 20% 98%);
|
||||
|
||||
--text: hsl(from var(--base-color) h 5% 5%);
|
||||
--accent: hsl(from var(--base-color) h calc(s + 10) calc(l + 20));
|
||||
--text-primary: hsl(from var(--base-color) h 5% 5%);
|
||||
--text-secondary: hsl(from var(--base-color) h 5% 30%);
|
||||
--text-muted: hsl(from var(--base-color) h 5% 50%);
|
||||
|
||||
--border-subtle: hsl(from var(--base-color) h 50% 90%);
|
||||
--border-normal: hsl(from var(--base-color) h 50% 50%);
|
||||
--border-highlight: hsl(from var var(--base-color) h 50% 25%);
|
||||
--border-subtle: hsl(from var(--base-color) h 50% 85%);
|
||||
--border-normal: hsl(from var(--base-color) h 50% 70%);
|
||||
--border-highlight: hsl(from var(--base-color) h 50% 35%);
|
||||
}
|
||||
}
|
||||
|
||||
/* Box sizing rules */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Remove default margin in favour of better control in authored CSS */
|
||||
body,
|
||||
h1,
|
||||
|
|
@ -157,7 +173,7 @@ textarea:not([rows]) {
|
|||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
color: var(--text);
|
||||
color: var(--text-primary);
|
||||
background-color: var(--bg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -201,7 +217,7 @@ textarea:focus {
|
|||
|
||||
.avatar-container {
|
||||
display: block;
|
||||
margin: 0.5rem auto;
|
||||
margin: 0 auto 1rem;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
border-radius: var(--border-radius);
|
||||
|
|
@ -281,7 +297,7 @@ label:has(input[collapse-toggle]) {
|
|||
display: block;
|
||||
max-width: fit-content;
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--text);
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.5rem;
|
||||
margin-bottom: 2rem;
|
||||
|
|
@ -334,14 +350,15 @@ form input:focus {
|
|||
form button {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
border: 1px solid var(--text);
|
||||
border: 1px solid var(--border-subtle);
|
||||
font-size: 20px;
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
color: var(--text-primary);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
form button.primary {
|
||||
border-color: var(--border-highlight);
|
||||
background-color: var(--accent);
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +366,7 @@ button {
|
|||
background: inherit;
|
||||
color: inherit;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid var(--text);
|
||||
border: 1px solid var(--text-primary);
|
||||
border-radius: var(--border-radius);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -582,6 +582,49 @@
|
|||
left: -6px;
|
||||
}
|
||||
|
||||
/* ICON - MIC */
|
||||
.icon.mic {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: block;
|
||||
transform: scale(var(--icon-scale, 1));
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
border-bottom-left-radius: 120px;
|
||||
border-bottom-right-radius: 120px;
|
||||
border: 2px solid;
|
||||
border-top: 0;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.icon.mic::after,
|
||||
.icon.mic::before {
|
||||
content: "";
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.icon.mic::after {
|
||||
border: 2px solid;
|
||||
width: 8px;
|
||||
height: 18px;
|
||||
left: 2px;
|
||||
top: -10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.icon.mic::before {
|
||||
width: 10px;
|
||||
height: 4px;
|
||||
top: 12px;
|
||||
left: 1px;
|
||||
border-right: 4px solid transparent;
|
||||
box-shadow:
|
||||
0 2px 0,
|
||||
inset -2px 0 0;
|
||||
}
|
||||
|
||||
/* ICON - MINUS */
|
||||
.icon.minus {
|
||||
box-sizing: border-box;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function embed_vimeo(link_info) {
|
|||
<iframe
|
||||
src="https://player.vimeo.com/video/${video_id}"
|
||||
frameborder="0"
|
||||
allow="fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share"
|
||||
allow="fullscreen; picture-in-picture; clipboard-write; encrypted-media;"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
title="Star Trek: Legacy"
|
||||
loading="lazy"></iframe>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ function embed_youtube(link_info) {
|
|||
<iframe
|
||||
src="https://www.youtube.com/embed/${video_id}"
|
||||
title="YouTube video player"
|
||||
allow="clipboard-write; encrypted-media; picture-in-picture; web-share;"
|
||||
allow="clipboard-write; encrypted-media; picture-in-picture;"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen
|
||||
loading="lazy"
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@
|
|||
padding: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--text);
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0.5px;
|
||||
transition:
|
||||
background 0.25s,
|
||||
|
|
@ -257,7 +257,7 @@
|
|||
padding: 0.75rem;
|
||||
margin: 0 0.75rem 1rem 0;
|
||||
background: none;
|
||||
color: var(--text);
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--border-highlight);
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: none;
|
||||
|
|
@ -364,7 +364,7 @@
|
|||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
padding: 0.75rem;
|
||||
padding: 1rem;
|
||||
width: 6rem;
|
||||
border-right: 1px solid var(--border-subtle);
|
||||
overflow-y: auto;
|
||||
|
|
@ -421,7 +421,7 @@
|
|||
#server-info {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
padding: 0.75rem;
|
||||
padding: 1rem 2rem;
|
||||
}
|
||||
</style>
|
||||
<div id="server-info">
|
||||
|
|
|
|||
|
|
@ -98,6 +98,10 @@
|
|||
<input id="signup-password" type="password" name="password" required />
|
||||
<label class="placeholder" for="signup-password">password</label>
|
||||
</div>
|
||||
<div>
|
||||
<input id="signup-password-verification" type="password" name="password_verification" required />
|
||||
<label class="placeholder" for="signup-password-verification">verify password</label>
|
||||
</div>
|
||||
<div>
|
||||
<script>
|
||||
APP.on( 'load', () => {
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@
|
|||
font-weight: bold;
|
||||
font-size: x-large;
|
||||
content: "#";
|
||||
color: var(--text);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
#channel-list-container .channel-list > li.channel a {
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@
|
|||
position: absolute;
|
||||
top: 0.1rem;
|
||||
right: 0.1rem;
|
||||
color: rgb(from var(--text) r g b / 0.7);
|
||||
color: rgb(from var(--text-primary) r g b / 0.7);
|
||||
border: none;
|
||||
z-index: 10;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,8 @@
|
|||
method="POST"
|
||||
class="post-creation-form collapsible"
|
||||
style="
|
||||
margin-top: 1rem
|
||||
position: relative;
|
||||
margin-top: 1rem;
|
||||
width: 100%;
|
||||
transition: all 0.5s;
|
||||
"
|
||||
|
|
@ -221,6 +222,7 @@
|
|||
reset-on-submit
|
||||
focus-on-submit
|
||||
enter-key-submits
|
||||
accept-speech
|
||||
></textarea>
|
||||
|
||||
<button id="chat-send" class="primary" aria-label="Send a message">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue