feat: adds basic auth system

This commit is contained in:
HerozDotExe 2024-11-02 19:20:14 +01:00
parent 2f6ffbf758
commit 5c1ee6850d
9 changed files with 190 additions and 0 deletions

View file

@ -21,5 +21,8 @@
"tslib": "^2.8.0", "tslib": "^2.8.0",
"typescript": "~5.6.2", "typescript": "~5.6.2",
"vite": "^5.4.10" "vite": "^5.4.10"
},
"dependencies": {
"pocketbase": "^0.21.5"
} }
} }

9
pnpm-lock.yaml generated
View file

@ -7,6 +7,10 @@ settings:
importers: importers:
.: .:
dependencies:
pocketbase:
specifier: ^0.21.5
version: 0.21.5
devDependencies: devDependencies:
'@sveltejs/vite-plugin-svelte': '@sveltejs/vite-plugin-svelte':
specifier: ^4.0.0 specifier: ^4.0.0
@ -677,6 +681,9 @@ packages:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
pocketbase@0.21.5:
resolution: {integrity: sha512-bnI/uinnQps+ElSlzxkc4yvwuSFfKcoszDtXH/4QT2FhGq2mJVUvDlxn+rjRXVntUjPfmMG5LEPZ1eGqV6ssog==}
postcss-import@15.1.0: postcss-import@15.1.0:
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@ -1400,6 +1407,8 @@ snapshots:
pirates@4.0.6: {} pirates@4.0.6: {}
pocketbase@0.21.5: {}
postcss-import@15.1.0(postcss@8.4.47): postcss-import@15.1.0(postcss@8.4.47):
dependencies: dependencies:
postcss: 8.4.47 postcss: 8.4.47

View file

@ -0,0 +1,39 @@
<script lang="ts">
import Auth from "./lib/components/Auth/Auth.svelte";
import Chat from "./lib/components/Chat/Chat.svelte";
import Login from "./lib/components/Auth/Login.svelte";
import Register from "./lib/components/Auth/Register.svelte";
import { getUser, pb } from "./lib/pocketbase.svelte";
let page = $state("");
function cancel() {
page = "auth";
}
function logout() {
pb.authStore.clear();
page = "auth";
}
$effect(() => {
const user = getUser();
$inspect(user);
if (!user) {
page = "auth";
} else {
page = "app";
}
});
</script>
{#if page == "auth"}
<Auth showLogin={() => (page = "login")} showRegister={() => (page = "register")}></Auth>
{:else if page == "login"}
<Login {cancel} />
{:else if page == "register"}
<Register {cancel} />
{:else if page == "app"}
<Chat />
{/if}

View file

@ -0,0 +1,13 @@
<script lang="ts">
import Link from "../utils/Link.svelte";
import Center from "../utils/Center.svelte";
let { showLogin, showRegister }: { showLogin: () => void; showRegister: () => void; } = $props();
</script>
<Center>
<p class="select-none text-2xl">
Welcome on minichat !
<br>
Please <Link onclick={showLogin}>login</Link> or <Link onclick={showRegister} >register</Link>.
</p>
</Center>

View file

@ -0,0 +1,40 @@
<script lang="ts">
import Center from "../utils/Center.svelte";
import Input from "../utils/Input.svelte";
import Button from "../utils/Button.svelte";
import { pb } from "../../pocketbase.svelte";
import { ClientResponseError } from "pocketbase";
let { cancel }: { cancel: () => void } = $props();
// svelte-ignore non_reactive_update
let username = "";
// svelte-ignore non_reactive_update
let password = "";
let authError = $state("")
async function login() {
if (password.length < 8) return;
try {
const authData = await pb.collection("users").authWithPassword(username, password);
console.log(authData);
} catch (error) {
if(error instanceof ClientResponseError) {
authError = error.response.message
}
}
}
</script>
<Center>
<form action="javascript:void(0);" class="select-none flex flex-col items-start gap-2">
<Input name="username" labelSize="larger" inputWidth="16rem" bind:value={username}>Username:</Input>
<Input name="password" type="password" labelSize="larger" inputWidth="16rem" bind:value={password}>Password:</Input>
<Button type="submit" width="16rem" onclick={login}>Login</Button>
<Button type="submit" width="16rem" onclick={cancel}>Cancel</Button>
<p class="text-center text-red-500 w-[100%]">{authError === "" ? "" : authError}</p>
</form>
</Center>

View file

@ -0,0 +1,64 @@
<script lang="ts">
import Center from "../utils/Center.svelte";
import Input from "../utils/Input.svelte";
import Button from "../utils/Button.svelte";
import { pb } from "../../pocketbase.svelte";
import { ClientResponseError } from "pocketbase";
// svelte-ignore non_reactive_update
let username = "";
// svelte-ignore non_reactive_update
let password = "";
// svelte-ignore non_reactive_update
let passwordConfirm = "";
let authError = $state("")
let { cancel }: { cancel: () => void } = $props();
async function register() {
if (password.length < 8 || password !== passwordConfirm) return;
const data = {
username,
password,
passwordConfirm,
};
try {
const record = await pb.collection("users").create(data);
const authData = await pb
.collection("users")
.authWithPassword(username, password);
console.log(record, authData)
} catch (error) {
if(error instanceof ClientResponseError) {
authError = error.response.message
}
}
}
</script>
<Center>
<form action="javascript:void(0);" class="select-none flex flex-col items-start gap-2">
<Input name="username" labelSize="larger" inputWidth="16rem" bind:value={username}
>Username:</Input>
<Input
name="password"
type="password"
labelSize="larger"
inputWidth="16rem"
bind:value={password}>Password:</Input>
<Input
name="password"
type="password"
labelSize="larger"
inputWidth="16rem"
bind:value={passwordConfirm}>Confirm password:</Input>
<Button type="submit" width="16rem" onclick={register}>Register</Button>
<Button type="submit" width="16rem" onclick={cancel}>Cancel</Button>
<p class="text-center text-red-500 w-[100%]">{authError === "" ? "" : authError}</p>
</form>
</Center>

View file

@ -0,0 +1,6 @@
<script lang="ts">
import { getUser, pb } from "../../pocketbase.svelte";
import Button from "../utils/Button.svelte";
</script>
<Button onclick={() => pb.authStore.clear()}>Logout</Button>

View file

@ -0,0 +1,5 @@
<script lang="ts">
let { open=false, children }: { open?: boolean, children: any } = $props();
</script>
<dialog {open}>{@render children?.()}</dialog>

View file

@ -0,0 +1,11 @@
import PocketBase from "pocketbase";
export const pb = new PocketBase("http://localhost:8090");
let user = $state(pb.authStore.model);
pb.authStore.onChange(() => {
user = pb.authStore.model;
});
export let getUser = () => user;