@axium/server 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/auth.d.ts +28 -0
- package/dist/auth.js +136 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +153 -234
- package/dist/config.d.ts +270 -0
- package/dist/config.js +122 -0
- package/dist/database.d.ts +80 -0
- package/dist/database.js +193 -34
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/io.d.ts +21 -0
- package/dist/io.js +63 -0
- package/package.json +22 -7
- package/web/app.html +15 -0
- package/web/auth.ts +12 -0
- package/web/hooks.server.ts +1 -0
- package/web/lib/Icon.svelte +42 -0
- package/web/routes/+page.server.ts +14 -0
- package/web/routes/+page.svelte +99 -0
- package/web/routes/edit/email/+page.server.ts +35 -0
- package/web/routes/edit/email/+page.svelte +25 -0
- package/web/routes/edit/name/+page.server.ts +35 -0
- package/web/routes/edit/name/+page.svelte +25 -0
- package/web/routes/signup/+page.server.ts +33 -0
- package/web/routes/signup/+page.svelte +27 -0
- package/web/static/axium.css +67 -0
- package/web/tsconfig.json +7 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Name } from '@axium/core/schemas';
|
|
2
|
+
import { fail, redirect, type Actions } from '@sveltejs/kit';
|
|
3
|
+
import { adapter } from '../../../../src/auth';
|
|
4
|
+
import type { PageServerLoadEvent } from './$types';
|
|
5
|
+
|
|
6
|
+
export async function load(event: PageServerLoadEvent) {
|
|
7
|
+
const session = await event.locals.auth();
|
|
8
|
+
if (!session) redirect(307, '/auth/signin');
|
|
9
|
+
return { session };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const actions = {
|
|
13
|
+
async default(event) {
|
|
14
|
+
const session = await event.locals.auth();
|
|
15
|
+
|
|
16
|
+
const rawName = (await event.request.formData()).get('name');
|
|
17
|
+
const { data: name, success, error } = Name.safeParse(rawName);
|
|
18
|
+
|
|
19
|
+
if (!success)
|
|
20
|
+
return fail(400, {
|
|
21
|
+
name,
|
|
22
|
+
error: error.flatten().formErrors[0] || Object.values(error.flatten().fieldErrors).flat()[0],
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const user = await adapter.getUserByEmail(session.user.email);
|
|
26
|
+
if (!user) return fail(500, { name, error: 'User does not exist' });
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
await adapter.updateUser({ id: user.id, name, image: user.image });
|
|
30
|
+
} catch (error: any) {
|
|
31
|
+
return fail(400, { name, error: typeof error === 'string' ? error : error.message });
|
|
32
|
+
}
|
|
33
|
+
redirect(303, '/');
|
|
34
|
+
},
|
|
35
|
+
} satisfies Actions;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { enhance } from '$app/forms';
|
|
3
|
+
import { page } from '$app/state';
|
|
4
|
+
const { user } = page.data.session;
|
|
5
|
+
let { form } = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<svelte:head>
|
|
9
|
+
<title>Edit Name</title>
|
|
10
|
+
</svelte:head>
|
|
11
|
+
|
|
12
|
+
<div>
|
|
13
|
+
<form method="POST" class="main" use:enhance>
|
|
14
|
+
{#if form?.error}
|
|
15
|
+
<div class="error">
|
|
16
|
+
{typeof form.error === 'string' ? form.error : JSON.stringify(form.error)}
|
|
17
|
+
</div>
|
|
18
|
+
{/if}
|
|
19
|
+
<div>
|
|
20
|
+
<label for="name">What do you want to be called?</label>
|
|
21
|
+
<input name="name" type="text" value={form?.name || user.name || ''} required />
|
|
22
|
+
</div>
|
|
23
|
+
<button type="submit">Continue</button>
|
|
24
|
+
</form>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Registration } from '@axium/core/schemas';
|
|
2
|
+
import { fail, redirect } from '@sveltejs/kit';
|
|
3
|
+
import * as auth from '../../../src/auth.js';
|
|
4
|
+
import * as config from '../../../src/config.js';
|
|
5
|
+
import type { Actions } from './$types';
|
|
6
|
+
|
|
7
|
+
export function load() {
|
|
8
|
+
if (!config.auth.credentials) return redirect(307, '/auth/signin');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const actions = {
|
|
12
|
+
async default(event) {
|
|
13
|
+
const { data, success, error } = Registration.safeParse(Object.fromEntries(await event.request.formData()));
|
|
14
|
+
|
|
15
|
+
if (!success)
|
|
16
|
+
return fail(400, {
|
|
17
|
+
...data,
|
|
18
|
+
error: error.flatten().formErrors[0] || Object.values(error.flatten().fieldErrors).flat()[0],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const { session } = await auth.register(data);
|
|
23
|
+
event.cookies.set('session', session.sessionToken, {
|
|
24
|
+
path: '/',
|
|
25
|
+
expires: session.expires,
|
|
26
|
+
httpOnly: true,
|
|
27
|
+
});
|
|
28
|
+
return { ...data, success: true, data: session.sessionToken };
|
|
29
|
+
} catch (error: any) {
|
|
30
|
+
return fail(400, { ...data, error: typeof error === 'string' ? error : error.message });
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
} satisfies Actions;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { enhance } from '$app/forms';
|
|
3
|
+
let { form } = $props();
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<div>
|
|
7
|
+
<form method="POST" class="main" use:enhance>
|
|
8
|
+
{#if form?.error}
|
|
9
|
+
<div class="error">
|
|
10
|
+
{typeof form.error === 'string' ? form.error : JSON.stringify(form.error)}
|
|
11
|
+
</div>
|
|
12
|
+
{/if}
|
|
13
|
+
<div>
|
|
14
|
+
<label for="name">Display Name</label>
|
|
15
|
+
<input name="name" type="text" value={form?.name || ''} required />
|
|
16
|
+
</div>
|
|
17
|
+
<div>
|
|
18
|
+
<label for="email">Email</label>
|
|
19
|
+
<input name="email" type="email" value={form?.email || ''} required />
|
|
20
|
+
</div>
|
|
21
|
+
<div>
|
|
22
|
+
<label for="password">Password</label>
|
|
23
|
+
<input name="password" type="password" />
|
|
24
|
+
</div>
|
|
25
|
+
<button type="submit">Register</button>
|
|
26
|
+
</form>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
body {
|
|
2
|
+
position: fixed;
|
|
3
|
+
inset: 0;
|
|
4
|
+
font-family: sans-serif;
|
|
5
|
+
font-size: 16px;
|
|
6
|
+
background-color: #222;
|
|
7
|
+
color: #bbb;
|
|
8
|
+
accent-color: #bbb;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.main {
|
|
12
|
+
padding: 2em;
|
|
13
|
+
border-radius: 1em;
|
|
14
|
+
background-color: #111;
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
gap: 1em;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
div:has(form.main) {
|
|
21
|
+
position: absolute;
|
|
22
|
+
inset: 0;
|
|
23
|
+
display: flex;
|
|
24
|
+
justify-content: center;
|
|
25
|
+
align-items: center;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
form.main {
|
|
29
|
+
width: max-content;
|
|
30
|
+
height: max-content;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
form {
|
|
34
|
+
div {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
gap: 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
input,
|
|
42
|
+
button {
|
|
43
|
+
border-radius: 0.5em;
|
|
44
|
+
border: 1px solid #aaa;
|
|
45
|
+
background-color: #222;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
input {
|
|
49
|
+
padding: 0.5em 1em;
|
|
50
|
+
outline: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
button {
|
|
54
|
+
padding: 0.5em 1em;
|
|
55
|
+
cursor: pointer;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
button:hover {
|
|
59
|
+
background-color: #334;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.error {
|
|
63
|
+
padding: 1em;
|
|
64
|
+
border-radius: 0.5em;
|
|
65
|
+
background-color: #733;
|
|
66
|
+
color: #ccc;
|
|
67
|
+
}
|