feat: adds basic auth system
This commit is contained in:
parent
2f6ffbf758
commit
5c1ee6850d
9 changed files with 190 additions and 0 deletions
|
|
@ -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
9
pnpm-lock.yaml
generated
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
13
src/lib/components/Auth/Auth.svelte
Normal file
13
src/lib/components/Auth/Auth.svelte
Normal 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>
|
||||||
40
src/lib/components/Auth/Login.svelte
Normal file
40
src/lib/components/Auth/Login.svelte
Normal 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>
|
||||||
64
src/lib/components/Auth/Register.svelte
Normal file
64
src/lib/components/Auth/Register.svelte
Normal 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>
|
||||||
6
src/lib/components/Chat/Chat.svelte
Normal file
6
src/lib/components/Chat/Chat.svelte
Normal 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>
|
||||||
5
src/lib/components/utils/Dialog.svelte
Normal file
5
src/lib/components/utils/Dialog.svelte
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<script lang="ts">
|
||||||
|
let { open=false, children }: { open?: boolean, children: any } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<dialog {open}>{@render children?.()}</dialog>
|
||||||
11
src/lib/pocketbase.svelte.ts
Normal file
11
src/lib/pocketbase.svelte.ts
Normal 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;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue