From a8abcbc540d36e8275c128d47fece41e6933e165 Mon Sep 17 00:00:00 2001 From: Bradley Shellnut Date: Fri, 3 Jan 2025 19:04:03 -0800 Subject: [PATCH] Adding auth page with layout, signup fixes, moving DTOs for reuse in front end and back end. --- .env.example | 1 + src/lib/components/logo.svelte | 879 ++++++++++++++++++ .../login}/create-login-request.dto.ts | 0 .../dtos => dtos/login}/login-request.dto.ts | 0 .../api/dtos => dtos/login}/login.dto.ts | 0 .../api/dtos => dtos/login}/signin.dto.ts | 0 .../login}/verify-login-request.dto.ts | 0 .../dtos => dtos/login}/verify-login.dto.ts | 0 src/lib/dtos/reset-password/index.ts | 2 + .../reset-password-email.dto.ts | 5 + .../reset-password-token.dto.ts | 5 + src/lib/dtos/signin.dto.ts | 12 - .../{ => signup}/signup-username-email.dto.ts | 2 +- .../{server/api => }/dtos/update-email.dto.ts | 0 .../{server/api => }/dtos/verify-email.dto.ts | 0 src/lib/server/api/iam/iam.controller.ts | 10 +- .../login-requests/login-requests.service.ts | 6 +- .../iam/login-requests/routes/login.routes.ts | 2 +- src/lib/utils/flashMessages.ts | 12 + src/lib/utils/pageCrossfade.ts | 12 +- src/lib/utils/page_loading_indicator.svelte | 43 + src/lib/utils/superforms.ts | 2 +- src/routes/(auth)/+layout.server.ts | 8 + src/routes/(auth)/+layout.svelte | 148 +++ .../(auth)/auth/callback/google/+server.ts | 26 + src/routes/(auth)/login/+page.server.ts | 29 +- src/routes/(auth)/login/+page.svelte | 51 +- src/routes/(auth)/login/github/+server.ts | 19 - src/routes/(auth)/login/spotify/+server.ts | 19 - src/routes/(auth)/login/tidal/+server.ts | 19 - .../(auth)/password/reset/+page.server.ts | 56 ++ src/routes/(auth)/password/reset/+page.svelte | 98 ++ src/routes/(auth)/signup/+page.server.ts | 26 +- src/routes/(auth)/signup/+page.svelte | 108 ++- src/routes/+layout.server.ts | 12 +- src/routes/+layout.svelte | 46 +- src/routes/api/[...slug]/+server.ts | 3 +- svelte.config.js | 1 + 38 files changed, 1467 insertions(+), 195 deletions(-) create mode 100644 src/lib/components/logo.svelte rename src/lib/{server/api/iam/login-requests/dtos => dtos/login}/create-login-request.dto.ts (100%) rename src/lib/{server/api/iam/login-requests/dtos => dtos/login}/login-request.dto.ts (100%) rename src/lib/{server/api/dtos => dtos/login}/login.dto.ts (100%) rename src/lib/{server/api/dtos => dtos/login}/signin.dto.ts (100%) rename src/lib/{server/api/iam/login-requests/dtos => dtos/login}/verify-login-request.dto.ts (100%) rename src/lib/{server/api/dtos => dtos/login}/verify-login.dto.ts (100%) create mode 100644 src/lib/dtos/reset-password/index.ts create mode 100644 src/lib/dtos/reset-password/reset-password-email.dto.ts create mode 100644 src/lib/dtos/reset-password/reset-password-token.dto.ts delete mode 100644 src/lib/dtos/signin.dto.ts rename src/lib/dtos/{ => signup}/signup-username-email.dto.ts (93%) rename src/lib/{server/api => }/dtos/update-email.dto.ts (100%) rename src/lib/{server/api => }/dtos/verify-email.dto.ts (100%) create mode 100644 src/lib/utils/flashMessages.ts create mode 100644 src/lib/utils/page_loading_indicator.svelte create mode 100644 src/routes/(auth)/+layout.server.ts create mode 100644 src/routes/(auth)/+layout.svelte create mode 100644 src/routes/(auth)/auth/callback/google/+server.ts delete mode 100644 src/routes/(auth)/login/github/+server.ts delete mode 100644 src/routes/(auth)/login/spotify/+server.ts delete mode 100644 src/routes/(auth)/login/tidal/+server.ts create mode 100644 src/routes/(auth)/password/reset/+page.server.ts create mode 100644 src/routes/(auth)/password/reset/+page.svelte diff --git a/.env.example b/.env.example index 25841b6..b00ed21 100644 --- a/.env.example +++ b/.env.example @@ -25,6 +25,7 @@ REDIS_URL=redis://localhost:6379 # Security - openssl rand -hex 32 SIGNING_SECRET= +SHOW_OAUTH_BUTTONS=false # Storage PUBLIC_IMAGE_URI=http://localhost:9000/dev diff --git a/src/lib/components/logo.svelte b/src/lib/components/logo.svelte new file mode 100644 index 0000000..2ed6f3d --- /dev/null +++ b/src/lib/components/logo.svelte @@ -0,0 +1,879 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lib/server/api/iam/login-requests/dtos/create-login-request.dto.ts b/src/lib/dtos/login/create-login-request.dto.ts similarity index 100% rename from src/lib/server/api/iam/login-requests/dtos/create-login-request.dto.ts rename to src/lib/dtos/login/create-login-request.dto.ts diff --git a/src/lib/server/api/iam/login-requests/dtos/login-request.dto.ts b/src/lib/dtos/login/login-request.dto.ts similarity index 100% rename from src/lib/server/api/iam/login-requests/dtos/login-request.dto.ts rename to src/lib/dtos/login/login-request.dto.ts diff --git a/src/lib/server/api/dtos/login.dto.ts b/src/lib/dtos/login/login.dto.ts similarity index 100% rename from src/lib/server/api/dtos/login.dto.ts rename to src/lib/dtos/login/login.dto.ts diff --git a/src/lib/server/api/dtos/signin.dto.ts b/src/lib/dtos/login/signin.dto.ts similarity index 100% rename from src/lib/server/api/dtos/signin.dto.ts rename to src/lib/dtos/login/signin.dto.ts diff --git a/src/lib/server/api/iam/login-requests/dtos/verify-login-request.dto.ts b/src/lib/dtos/login/verify-login-request.dto.ts similarity index 100% rename from src/lib/server/api/iam/login-requests/dtos/verify-login-request.dto.ts rename to src/lib/dtos/login/verify-login-request.dto.ts diff --git a/src/lib/server/api/dtos/verify-login.dto.ts b/src/lib/dtos/login/verify-login.dto.ts similarity index 100% rename from src/lib/server/api/dtos/verify-login.dto.ts rename to src/lib/dtos/login/verify-login.dto.ts diff --git a/src/lib/dtos/reset-password/index.ts b/src/lib/dtos/reset-password/index.ts new file mode 100644 index 0000000..f9198d7 --- /dev/null +++ b/src/lib/dtos/reset-password/index.ts @@ -0,0 +1,2 @@ +export * from './reset-password-email.dto'; +export * from './reset-password-token.dto'; \ No newline at end of file diff --git a/src/lib/dtos/reset-password/reset-password-email.dto.ts b/src/lib/dtos/reset-password/reset-password-email.dto.ts new file mode 100644 index 0000000..c32ba45 --- /dev/null +++ b/src/lib/dtos/reset-password/reset-password-email.dto.ts @@ -0,0 +1,5 @@ +import { z } from 'zod'; + +export const resetPasswordEmailDto = z.object({ + email: z.string().trim().email().max(64, { message: 'Email must be less than 64 characters' }), +}); diff --git a/src/lib/dtos/reset-password/reset-password-token.dto.ts b/src/lib/dtos/reset-password/reset-password-token.dto.ts new file mode 100644 index 0000000..9526c9f --- /dev/null +++ b/src/lib/dtos/reset-password/reset-password-token.dto.ts @@ -0,0 +1,5 @@ +import { z } from 'zod'; + +export const resetPasswordTokenDto = z.object({ + token: z.string().trim().min(6).max(6), +}); diff --git a/src/lib/dtos/signin.dto.ts b/src/lib/dtos/signin.dto.ts deleted file mode 100644 index 4b58701..0000000 --- a/src/lib/dtos/signin.dto.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {z} from "zod"; - -export const signinDto = z.object({ - identifier: z - .string() - .trim() - .min(3, { message: 'Must be at least 3 characters' }) - .max(50, { message: 'Must be less than 50 characters' }), - password: z.string({ required_error: 'Password is required' }).trim(), -}); - -export type signinDto = z.infer; \ No newline at end of file diff --git a/src/lib/dtos/signup-username-email.dto.ts b/src/lib/dtos/signup/signup-username-email.dto.ts similarity index 93% rename from src/lib/dtos/signup-username-email.dto.ts rename to src/lib/dtos/signup/signup-username-email.dto.ts index 42d3b58..bf79962 100644 --- a/src/lib/dtos/signup-username-email.dto.ts +++ b/src/lib/dtos/signup/signup-username-email.dto.ts @@ -1,4 +1,4 @@ -import { refinePasswords } from '../validations/account'; +import { refinePasswords } from '../../validations/account'; import { z } from 'zod'; export const signupUsernameEmailDto = z diff --git a/src/lib/server/api/dtos/update-email.dto.ts b/src/lib/dtos/update-email.dto.ts similarity index 100% rename from src/lib/server/api/dtos/update-email.dto.ts rename to src/lib/dtos/update-email.dto.ts diff --git a/src/lib/server/api/dtos/verify-email.dto.ts b/src/lib/dtos/verify-email.dto.ts similarity index 100% rename from src/lib/server/api/dtos/verify-email.dto.ts rename to src/lib/dtos/verify-email.dto.ts diff --git a/src/lib/server/api/iam/iam.controller.ts b/src/lib/server/api/iam/iam.controller.ts index 699bd14..8d23166 100644 --- a/src/lib/server/api/iam/iam.controller.ts +++ b/src/lib/server/api/iam/iam.controller.ts @@ -1,22 +1,22 @@ import { inject, injectable } from '@needle-di/core'; import { zValidator } from '@hono/zod-validator'; import { openApi } from 'hono-zod-openapi'; -import { createLoginRequestDto } from '../iam/login-requests/dtos/create-login-request.dto'; +import { createLoginRequestDto } from '../../../dtos/login/create-login-request.dto'; import { LoginRequestsService } from '../iam/login-requests/login-requests.service'; -import { verifyLoginRequestDto } from '../iam/login-requests/dtos/verify-login-request.dto'; +import { verifyLoginRequestDto } from '../../../dtos/login/verify-login-request.dto'; import { SessionsService } from '../iam/sessions/sessions.service'; import { authState } from '../common/middleware/auth.middleware'; import { Controller } from '../common/factories/controllers.factory'; -import { loginRequestDto } from './login-requests/dtos/login-request.dto'; +import { loginRequestDto } from '../../../dtos/login/login-request.dto'; import { signInEmail } from './login-requests/routes/login.routes'; import { rateLimit } from '../common/middleware/rate-limit.middleware'; import { LoggerService } from '../common/services/logger.service'; -import { signinDto } from '../dtos/signin.dto'; +import { signinDto } from '../../../dtos/login/signin.dto'; @injectable() export class IamController extends Controller { constructor( - private loggerService = inject(LoggerService), + private loggerService = inject(LoggerService), private loginRequestsService = inject(LoginRequestsService), private sessionsService = inject(SessionsService), ) { diff --git a/src/lib/server/api/iam/login-requests/login-requests.service.ts b/src/lib/server/api/iam/login-requests/login-requests.service.ts index 6068517..dd0e7a8 100644 --- a/src/lib/server/api/iam/login-requests/login-requests.service.ts +++ b/src/lib/server/api/iam/login-requests/login-requests.service.ts @@ -9,9 +9,9 @@ import { CredentialsRepository } from '../../users/credentials.repository'; import { UsersRepository } from '../../users/users.repository'; import { UsersService } from '../../users/users.service'; import { SessionsService } from '../sessions/sessions.service'; -import type { CreateLoginRequestDto } from './dtos/create-login-request.dto'; -import type { SignInDto } from '../../dtos/signin.dto'; -import type { VerifyLoginRequestDto } from './dtos/verify-login-request.dto'; +import type { CreateLoginRequestDto } from '../../../../dtos/login/create-login-request.dto'; +import type { SignInDto } from '../../../../dtos/login/signin.dto'; +import type { VerifyLoginRequestDto } from '../../../../dtos/login/verify-login-request.dto'; import { LoginRequestsRepository } from './login-requests.repository'; import { LoggerService } from '../../common/services/logger.service'; diff --git a/src/lib/server/api/iam/login-requests/routes/login.routes.ts b/src/lib/server/api/iam/login-requests/routes/login.routes.ts index f5cbe11..214519d 100644 --- a/src/lib/server/api/iam/login-requests/routes/login.routes.ts +++ b/src/lib/server/api/iam/login-requests/routes/login.routes.ts @@ -1,7 +1,7 @@ import { StatusCodes } from '$lib/utils/status-codes'; import { defineOpenApiOperation } from 'hono-zod-openapi'; import { createErrorSchema } from 'stoker/openapi/schemas'; -import { loginRequestDto } from '../dtos/login-request.dto'; +import { loginRequestDto } from '../../../../../dtos/login/login-request.dto'; export const signInEmail = defineOpenApiOperation({ tags: ['Login'], diff --git a/src/lib/utils/flashMessages.ts b/src/lib/utils/flashMessages.ts new file mode 100644 index 0000000..b96f045 --- /dev/null +++ b/src/lib/utils/flashMessages.ts @@ -0,0 +1,12 @@ +export const notSignedInMessage = { + type: 'error', + message: 'You are not signed in', +} as const; +export const forbiddenMessage = { + type: 'error', + message: 'You are not allowed to access this', +} as const; +export const signedOutMessage = { + type: 'success', + message: 'Successfully signed out', +} \ No newline at end of file diff --git a/src/lib/utils/pageCrossfade.ts b/src/lib/utils/pageCrossfade.ts index 71b63be..a83468c 100644 --- a/src/lib/utils/pageCrossfade.ts +++ b/src/lib/utils/pageCrossfade.ts @@ -1,8 +1,8 @@ -import {crossfade} from 'svelte/transition'; +import { crossfade } from 'svelte/transition'; export const [send, receive] = crossfade({ - duration: d => Math.sqrt(d * 200), - fallback() { - return { duration: 600, easing: x => --x * x * x + 1 }; // Ease-out cubic - } -}); \ No newline at end of file + duration: (d) => Math.sqrt(d * 200), + fallback() { + return { duration: 600, easing: (x) => --x * x * x + 1 }; // Ease-out cubic + }, +}); diff --git a/src/lib/utils/page_loading_indicator.svelte b/src/lib/utils/page_loading_indicator.svelte new file mode 100644 index 0000000..c308dfb --- /dev/null +++ b/src/lib/utils/page_loading_indicator.svelte @@ -0,0 +1,43 @@ + + +{#if visible} +
+{/if} diff --git a/src/lib/utils/superforms.ts b/src/lib/utils/superforms.ts index f420765..c1b5676 100644 --- a/src/lib/utils/superforms.ts +++ b/src/lib/utils/superforms.ts @@ -2,7 +2,7 @@ import { toast } from "svelte-sonner"; import { message, type ErrorStatus, type SuperForm, type SuperValidated } from "sveltekit-superforms"; export type Message = { - type: 'error' | 'success', + type: 'error' | 'success' | 'info', text: string } diff --git a/src/routes/(auth)/+layout.server.ts b/src/routes/(auth)/+layout.server.ts new file mode 100644 index 0000000..717d68c --- /dev/null +++ b/src/routes/(auth)/+layout.server.ts @@ -0,0 +1,8 @@ +export async function load(event) { + const { parent } = event; + const { authedUser } = await parent(); + + return { + authedUser, + }; +} diff --git a/src/routes/(auth)/+layout.svelte b/src/routes/(auth)/+layout.svelte new file mode 100644 index 0000000..378e149 --- /dev/null +++ b/src/routes/(auth)/+layout.svelte @@ -0,0 +1,148 @@ + + +
+ +
+ {#if page.url.pathname !== "/login"} + + {/if} + {#if page.url.pathname !== "/signup"} + + {/if} +
+
+
+
+
+

+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." +

+
John Doe
+
+
+
+
+ {@render children()} +
+
+ + diff --git a/src/routes/(auth)/auth/callback/google/+server.ts b/src/routes/(auth)/auth/callback/google/+server.ts new file mode 100644 index 0000000..863a7d7 --- /dev/null +++ b/src/routes/(auth)/auth/callback/google/+server.ts @@ -0,0 +1,26 @@ +import { StatusCodes } from '$lib/utils/status-codes'; +import type { RequestEvent } from '@sveltejs/kit'; +import { redirect } from 'sveltekit-flash-message/server'; + +export async function GET(event: RequestEvent): Promise { + const { locals, url } = event; + const code = url.searchParams.get('code'); + const state = url.searchParams.get('state'); + console.log('code', code, 'state', state); + + const { data, error } = await locals.api.oauth.google.$get({ query: { code, state } }).then(locals.parseApiResponse); + + if (error) { + return new Response(JSON.stringify(error), { + status: 400, + }); + } + + if (!data) { + return new Response(JSON.stringify({ message: 'Invalid request' }), { + status: 400, + }); + } + + redirect(StatusCodes.TEMPORARY_REDIRECT, '/'); +} diff --git a/src/routes/(auth)/login/+page.server.ts b/src/routes/(auth)/login/+page.server.ts index 29b86fe..2d90367 100644 --- a/src/routes/(auth)/login/+page.server.ts +++ b/src/routes/(auth)/login/+page.server.ts @@ -4,7 +4,8 @@ import { redirect } from 'sveltekit-flash-message/server'; import { zod } from 'sveltekit-superforms/adapters'; import { setError, superValidate } from 'sveltekit-superforms/server'; import type { PageServerLoad } from './$types'; -import { signinDto } from '@/server/api/dtos/signin.dto'; +import { signinDto } from '@/dtos/login/signin.dto'; +import { SHOW_OAUTH_BUTTONS } from '$env/static/private'; export const load: PageServerLoad = async (event) => { const { parent } = event; @@ -16,10 +17,11 @@ export const load: PageServerLoad = async (event) => { throw redirect('/', message, event); // redirect(302, '/', message, event) } - const form = await superValidate(event, zod(signinDto)); + const loginForm = await superValidate(event, zod(signinDto)); return { - form, + loginForm, + showOAuthButtons: SHOW_OAUTH_BUTTONS === 'true', }; }; @@ -34,25 +36,28 @@ export const actions: Actions = { throw redirect('/', message, event); } - const form = await superValidate(event, zod(signinDto)); + const loginForm = await superValidate(event, zod(signinDto)); - const { error } = await locals.api.iam.login.$post({ json: form.data }).then(locals.parseApiResponse); + const { error } = await locals.api.iam.login.$post({ json: loginForm.data }).then(locals.parseApiResponse); console.log('Login error', error); if (error) { + loginForm.data.password = ''; console.log('Setting error'); - return setError(form, 'identifier', 'An error occurred while logging in.'); + return setError(loginForm, 'identifier', 'An error occurred while logging in.'); } - if (!form.valid) { - form.data.password = ''; + if (!loginForm.valid) { + loginForm.data.password = ''; return fail(400, { - form, + loginForm, }); } - form.data.identifier = ''; - form.data.password = ''; + loginForm.data.identifier = ''; + loginForm.data.password = ''; + const message = { type: 'success', message: 'Signed In!' } as const; + redirect(302, '/', message, event); // const { error: totpCredentialError, data } = await locals.api.mfa.totp.$get().then(locals.parseApiResponse); // if (totpCredentialError || !data) { // return setError(form, 'identifier', totpCredentialError ?? 'Something went wrong. Please try again.'); @@ -70,7 +75,5 @@ export const actions: Actions = { // } else { // return setError(form, 'identifier', 'Something went wrong. Please try again.'); // } - - redirect(StatusCodes.TEMPORARY_REDIRECT, '/'); }, }; diff --git a/src/routes/(auth)/login/+page.svelte b/src/routes/(auth)/login/+page.svelte index 3fdd9d8..5ad7f94 100644 --- a/src/routes/(auth)/login/+page.svelte +++ b/src/routes/(auth)/login/+page.svelte @@ -1,18 +1,19 @@ + +
+ + + Reset Password + Enter your email to reset your password + + +
+ {#if showTokenVerification} + {@render tokenForm()} + {:else} + {@render emailForm()} + {/if} +
+
+
+
+ +{#snippet emailForm()} +
+ + + {#snippet children({ props })} + Email + + {/snippet} + + + + + +
+{/snippet} + +{#snippet tokenForm()} +
+ + + + {#snippet children({ props })} + Enter the token that was sent to your email + + {#snippet children({ cells })} + + {#each cells as cell} + + {/each} + + {/snippet} + + {/snippet} + + + + + +
+{/snippet} \ No newline at end of file diff --git a/src/routes/(auth)/signup/+page.server.ts b/src/routes/(auth)/signup/+page.server.ts index 73dcd81..061d441 100644 --- a/src/routes/(auth)/signup/+page.server.ts +++ b/src/routes/(auth)/signup/+page.server.ts @@ -15,11 +15,10 @@ const signUpDefaults = { }; export const load = async (event) => { - const { locals } = event; + const { parent } = event; + const { authedUser } = await parent(); - const user = await locals.getAuthedUser(); - - if (user) { + if (authedUser) { const message = { type: 'success', message: 'You are already signed in' } as const; throw redirect('/', message, event); } @@ -32,25 +31,24 @@ export const load = async (event) => { }; export const actions: Actions = { - default: async (event) => { + default: async (event) => { const { locals } = event; + const authedUser = await locals.getAuthedUser(); - const user = await locals.getAuthedUser(); - - if (user) { + if (authedUser) { const message = { type: 'success', message: 'You are already signed in' } as const; throw redirect('/', message, event); } - const form = await superValidate(event, zod(signupUsernameEmailDto)); + const form = await superValidate(event, zod(signupUsernameEmailDto)); - console.log('form data', form.data); + console.log('form data', form.data); const { error } = await locals.api.signup.$post({ json: form.data }).then(locals.parseApiResponse); - if (error) { - console.log('error', error); - form.data.password = ''; - form.data.confirm_password = ''; + if (error) { + console.log('error', error); + form.data.password = ''; + form.data.confirm_password = ''; return setError(form, 'username', 'Unable to sign up.'); } diff --git a/src/routes/(auth)/signup/+page.svelte b/src/routes/(auth)/signup/+page.svelte index 6bcf178..91ce1d7 100644 --- a/src/routes/(auth)/signup/+page.svelte +++ b/src/routes/(auth)/signup/+page.svelte @@ -4,70 +4,88 @@ import * as Card from '$lib/components/ui/card/index.js'; import { Label } from '$lib/components/ui/label/index.js'; import { Input } from '$lib/components/ui/input/index.js'; + import { receive, send } from "$lib/utils/pageCrossfade"; import { superForm } from 'sveltekit-superforms'; import * as Form from '$lib/components/ui/form'; import { zodClient } from 'sveltekit-superforms/adapters'; - import { signupUsernameEmailDto } from '@/dtos/signup-username-email.dto'; + import { signupUsernameEmailDto } from '$lib/dtos/signup/signup-username-email.dto.js'; const { data } = $props(); - const signupForm = superForm(data.signupForm, { + const sf_signup = superForm(data.signupForm, { validators: zodClient(signupUsernameEmailDto), resetForm: false, }); -const { form: signupFormData, errors: signupErrors, enhance: signupEnhance } = signupForm; +const { form: signupForm, errors: signupErrors, enhance: signupEnhance } = sf_signup; - - - Signup for an account - - -
- {@render signUpForm()} -
-
- By registering, you agree to our Terms of Service -
-
-
+ + Acme | Sign Up + + +
+ + + Signup for an account + + +
+ {@render signUpForm()} +
+
+ By registering, you agree to our Terms of Service +
+
+
+
{#snippet signUpForm()}
- - - {#if $signupErrors.username} -

{$signupErrors.username}

- {/if} - - - {#if $signupErrors.password} -

{$signupErrors.password}

- {/if} - - - {#if $signupErrors.confirm_password} -

{$signupErrors.confirm_password}

- {/if} - - - {#if $signupErrors.email} -

{$signupErrors.email}

- {/if} + + + {#snippet children({ props })} + + + {/snippet} + + + + + + {#snippet children({ props })} + + + {/snippet} + + + + + + {#snippet children({ props })} + + + {/snippet} + + + + + + {#snippet children({ props })} + + + {/snippet} + + +
- + Signup
- {#if !$signupFormData.email} + {#if !$signupForm.email} - Heads up! + Heads up! Without an email address, you won't be able to reset your password. Submit only if you are sure. You can always add this later. diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index b9528b9..f5c8937 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1,7 +1,9 @@ -export const load = async ({ locals }) => { +import { loadFlash } from "sveltekit-flash-message/server"; + +export const load = loadFlash(async ({ locals }) => { const authedUser = await locals.getAuthedUser(); - console.log('authedUser', authedUser) + return { - authedUser - } -} \ No newline at end of file + authedUser, + }; +}); \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index d905ccf..b8793a6 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,13 +1,51 @@ + -
- {@render children?.()} -
+ + +
+ {@render children?.()} +
+
diff --git a/src/routes/api/[...slug]/+server.ts b/src/routes/api/[...slug]/+server.ts index bdb38cf..abe9033 100644 --- a/src/routes/api/[...slug]/+server.ts +++ b/src/routes/api/[...slug]/+server.ts @@ -1,5 +1,4 @@ -// import { app } from '$lib/server/api'; -import {app} from '../../../hooks.server'; +import { app } from '../../../hooks.server'; import type { RequestHandler } from '@sveltejs/kit'; export const GET: RequestHandler = ({ request }) => app.request(request); diff --git a/svelte.config.js b/svelte.config.js index 94c0a99..0cfb331 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -13,6 +13,7 @@ const config = { // See https://svelte.dev/docs/kit/adapters for more information about adapters. adapter: adapter(), alias: { + $lib: "./src/lib", "@/*": "./src/lib/*" }, }