Add: User Logging in
This commit is contained in:
parent
a34ed38800
commit
eea87823d9
45
src/comp/entry/entryfield.svelte
Normal file
45
src/comp/entry/entryfield.svelte
Normal file
@ -0,0 +1,45 @@
|
||||
<script>
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
export let name;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
export let labelName;
|
||||
|
||||
/**
|
||||
* @type {'text' | 'password'}
|
||||
*/
|
||||
export let type;
|
||||
|
||||
/**
|
||||
* @type {'username' | 'new-password' | 'current-password'}
|
||||
*/
|
||||
export let autocomplete;
|
||||
|
||||
/**
|
||||
* @type {string | null}
|
||||
*/
|
||||
export let value = null;
|
||||
|
||||
/** @type {import("svelte/elements").FormEventHandler<HTMLInputElement>} */
|
||||
function onInput(e) {
|
||||
value = e.target && 'value' in e.target && e.target?.value ? String(e.target?.value) : null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.pair {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
gap: 4px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="pair">
|
||||
<label class="noSelect" for="field-{name}">{labelName}</label>
|
||||
<input {type} {name} id="field-{name}" {autocomplete} required on:input={onInput}>
|
||||
</div>
|
||||
73
src/comp/entry/entryform.svelte
Normal file
73
src/comp/entry/entryform.svelte
Normal file
@ -0,0 +1,73 @@
|
||||
<script>
|
||||
import Glowfx from "$comp/fx/glowfx.svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
export let action;
|
||||
|
||||
/**
|
||||
* @type {'post'}
|
||||
*/
|
||||
export let method = 'post';
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
export let formName;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
export let submitText;
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.items {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
width: 100%;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 1.1rem;
|
||||
letter-spacing: 0em;
|
||||
|
||||
transition: letter-spacing 0.2s cubic-bezier(.18,.89,.32,1.28);
|
||||
|
||||
&:hover {
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<form class="entryForm" {action} {method} on:submit={(e) => {dispatch('submit', e);}} {...$$restProps}>
|
||||
<div class="name">
|
||||
<h1 class="typeHead noSelect">{formName}</h1>
|
||||
<slot name="belowName" />
|
||||
</div>
|
||||
|
||||
<div class="items">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<Glowfx borderRadius={4}>
|
||||
<button class="button typeTitle noSelect" type="submit">{submitText}</button>
|
||||
</Glowfx>
|
||||
</form>
|
||||
@ -131,7 +131,7 @@ export async function getPost(post_id, opts = {}) {
|
||||
}
|
||||
}();
|
||||
|
||||
const category_guess = await getCategoryCached(sql, post['category_id']);
|
||||
const category_guess = await getCategoryCached(post['category_id']);
|
||||
if (Object.hasOwn(category_guess, 'error')) {
|
||||
return {
|
||||
error: true,
|
||||
|
||||
@ -134,3 +134,47 @@ export async function createUser(username, password) {
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} username
|
||||
* @param {string} password
|
||||
* @returns {Promise<import('$types/status').Success | import('$types/status').Error>}
|
||||
*/
|
||||
export async function createUserSession(username, password) {
|
||||
const select = sql`
|
||||
SELECT password, id
|
||||
FROM doki8902.user
|
||||
WHERE username = ${ username };`;
|
||||
|
||||
const result = await select;
|
||||
|
||||
if (result.length == 0) {
|
||||
return {
|
||||
error: true,
|
||||
msg: 'Username or password is incorrect',
|
||||
};
|
||||
}
|
||||
|
||||
const hashedPassword = result[0]['password'];
|
||||
|
||||
const isMatch = await verify(hashedPassword, password);
|
||||
|
||||
if (!isMatch) {
|
||||
return {
|
||||
error: true,
|
||||
msg: 'Username or password is incorrect',
|
||||
};
|
||||
}
|
||||
|
||||
const insert = sql`
|
||||
INSERT INTO doki8902.user_session (user_id)
|
||||
VALUES (${ result[0]['id'] })
|
||||
RETURNING token;`;
|
||||
|
||||
const token = await insert;
|
||||
|
||||
return {
|
||||
success: true,
|
||||
result: token[0]['token'],
|
||||
};
|
||||
}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
import { createUserSession } from "$lib/server/db/user";
|
||||
|
||||
/** @type {import("@sveltejs/kit").Action} */
|
||||
async function POST({ request, cookies }) {
|
||||
if (request.method !== 'POST') {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await request.formData();
|
||||
const username = data.get('username')?.toString();
|
||||
const password = data.get('password')?.toString();
|
||||
|
||||
if (!username || !password) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await createUserSession(username, password);
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
|
||||
/** @type {import("@sveltejs/kit").Actions} */
|
||||
export let actions = {
|
||||
default: POST
|
||||
};
|
||||
@ -0,0 +1,11 @@
|
||||
<script>
|
||||
import Entryfield from "$comp/entry/entryfield.svelte";
|
||||
import Entryform from "$comp/entry/entryform.svelte";
|
||||
</script>
|
||||
|
||||
<Entryform action="/login" formName="Login" submitText="enter">
|
||||
<a href="/register" slot="belowName">New here?</a>
|
||||
|
||||
<Entryfield name="username" labelName="Username" type="text" autocomplete="username"></Entryfield>
|
||||
<Entryfield name="password" labelName="Password" type="password" autocomplete="current-password"></Entryfield>
|
||||
</Entryform>
|
||||
@ -11,6 +11,10 @@ export function load({ cookies }) {
|
||||
|
||||
/** @type {import('./$types').Action} */
|
||||
async function POST({ request }) {
|
||||
if (request.method !== 'POST') {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await request.formData();
|
||||
const username = data.get('username')?.toString();
|
||||
const password = data.get('password')?.toString();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import Glowfx from "$comp/fx/glowfx.svelte";
|
||||
import Entryfield from "$comp/entry/entryfield.svelte";
|
||||
import Entryform from "$comp/entry/entryform.svelte";
|
||||
|
||||
/** @type {string} */
|
||||
let password;
|
||||
@ -14,51 +15,10 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
<Entryform action="/register" formName="Register" submitText="go!" on:submit={(e) => {submitForm(e.detail);}}>
|
||||
<a href="/login" slot="belowName">Already a member?</a>
|
||||
|
||||
.items {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
width: 100%;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.pair {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
gap: 4px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 1.3rem;
|
||||
letter-spacing: 0.2em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<form class="entryForm" action="/register" method="post" on:submit={submitForm}>
|
||||
<h1 class="typeHead noSelect">Register</h1>
|
||||
<div class="items">
|
||||
<div class="pair">
|
||||
<label class="noSelect" for="username">Username</label>
|
||||
<input type="text" name="username" id="username" autocomplete="username" required>
|
||||
</div>
|
||||
|
||||
<div class="pair">
|
||||
<label class="noSelect" for="password">Password</label>
|
||||
<input type="password" name="password" id="password" autocomplete="new-password" required bind:value={password}>
|
||||
</div>
|
||||
|
||||
<div class="pair">
|
||||
<label class="noSelect" for="repeatPassword">Repeat Password</label>
|
||||
<input type="password" id="repeatPassword" autocomplete="new-password" required bind:value={repeatPassword}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Glowfx borderRadius={4}>
|
||||
<button class="button typeTitle noSelect" type="submit">GO!</button>
|
||||
</Glowfx>
|
||||
</form>
|
||||
<Entryfield name="username" labelName="Username" type="text" autocomplete="username"></Entryfield>
|
||||
<Entryfield name="password" labelName="Password" type="password" autocomplete="new-password" bind:value={password}></Entryfield>
|
||||
<Entryfield name="repeatPassword" labelName="Confirm Password" type="password" autocomplete="new-password" bind:value={repeatPassword}></Entryfield>
|
||||
</Entryform>
|
||||
|
||||
@ -5,4 +5,5 @@ export type Error = {
|
||||
|
||||
export type Success = {
|
||||
success: boolean,
|
||||
result?: object,
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user