Skip to content

Commit

Permalink
Add auth + build
Browse files Browse the repository at this point in the history
  • Loading branch information
YummYume committed Jan 5, 2024
1 parent e9c2375 commit 9f74df4
Show file tree
Hide file tree
Showing 19 changed files with 360 additions and 48 deletions.
Binary file modified bun.lockb
Binary file not shown.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
"prisma"
],
"devDependencies": {
"@sveltejs/adapter-auto": "^3.0.1",
"@sveltejs/adapter-node": "^2.0.1",
"@sveltejs/adapter-node": "^2.0.2",
"@sveltejs/enhanced-img": "^0.1.7",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tailwindcss/forms": "^0.5.7",
Expand Down
20 changes: 19 additions & 1 deletion src/app.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import type { Auth as AuthType } from '$lib/server/auth';
import type { PrismaClient } from '@prisma/client';
import type { AuthRequest, Session } from 'lucia';

// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
interface Locals {
db: PrismaClient;
auth: AuthRequest;
session: Session | null;
}
interface PageData {
seo?: {
title?: string;
Expand All @@ -16,6 +24,16 @@ declare global {
// interface PageState {}
// interface Platform {}
}

namespace Lucia {
type Auth = AuthType;
type DatabaseUserAttributes = {
username: string;
disallowedIngredients: string | null;
};
// eslint-disable-next-line @typescript-eslint/ban-types
type DatabaseSessionAttributes = {};
}
}

export {};
12 changes: 12 additions & 0 deletions src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { auth } from '$lib/server/auth';
import { db } from '$lib/server/db';

import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) => {
event.locals.db = db;
event.locals.auth = auth.handleRequest(event);
event.locals.session = await event.locals.auth.validate();

return resolve(event);
};
7 changes: 2 additions & 5 deletions src/routes/+layout.server.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import type { LayoutServerLoad } from './$types';

export const load = (async () => {
export const load = (async ({ locals }) => {
return {
user: {
username: 'Carlos',
disallowedIngredients: ['chocolat'],
},
user: locals.session?.user,
seo: {
title: 'CookConnect',
meta: {
Expand Down
15 changes: 9 additions & 6 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import type { LayoutData } from './$types';
import { enhance } from '$app/forms';
import { page } from '$app/stores';
export let data: LayoutData;
Expand Down Expand Up @@ -49,15 +50,17 @@
<nav class="flex items-center lg:order-2 sm:mx-0 mx-auto">
<ul class="contents">
<li>
<button
type="button"
class="
<form method="POST" action="/?/logout" use:enhance>
<button
type="submit"
class="
text-gray-800 hover:bg-gray-50 focus:ring-4 focus:ring-gray-300 font-medium
rounded-lg text-sm px-4 lg:px-5 py-2 lg:py-2.5 mr-2 focus:outline-none
"
>
Se déconnecter
</button>
>
Se déconnecter
</button>
</form>
</li>
<li>
<a
Expand Down
35 changes: 33 additions & 2 deletions src/routes/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import type { PageServerLoad } from './$types';
import { fail, redirect } from '@sveltejs/kit';

import { auth } from '$lib/server/auth';

import type { Actions, PageServerLoad } from './$types';

export const load = (async ({ locals }) => {
const { session } = locals;

if (!session) {
redirect(303, '/login');
}

export const load = (async () => {
return {
seo: {
title: 'CookConnect',
Expand All @@ -11,3 +21,24 @@ export const load = (async () => {
},
};
}) satisfies PageServerLoad;

export const actions = {
logout: async ({ locals, cookies }) => {
const { session } = locals;

if (!session) {
return fail(401, { error: "Vous n'êtes pas connecté." });
}

await auth.invalidateSession(session.sessionId);

const sessionCookie = auth.createSessionCookie(null);

cookies.set(sessionCookie.name, sessionCookie.value, {
...sessionCookie.attributes,
path: sessionCookie.attributes.path ?? '/',
});

redirect(303, '/');
},
} satisfies Actions;
83 changes: 77 additions & 6 deletions src/routes/account/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import type { PageServerLoad } from './$types';
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library';
import { fail, redirect } from '@sveltejs/kit';

import type { Actions, PageServerLoad } from './$types';

export const load = (async ({ locals }) => {
const { session } = locals;

if (!session) {
redirect(303, '/login');
}

export const load = (async () => {
return {
user: {
username: 'Carlos',
disallowedIngredients: 'chocolat',
},
user: session.user,
seo: {
title: 'Mon profil',
meta: {
Expand All @@ -14,3 +20,68 @@ export const load = (async () => {
},
};
}) satisfies PageServerLoad;

export const actions = {
default: async ({ locals, request }) => {
const { db, session } = locals;
const data = await request.formData();

if (!session) {
redirect(303, '/login');
}

const username = data.get('username') as string;
const disallowedIngredients = data.get('disallowedIngredients') as string;

if (!username) {
return fail(422, { error: "Le nom d'utilisateur ne peut pas être vide." });
}

if (!/^[A-Za-z]+$/g.test(username)) {
return fail(422, {
error: "Le nom d'utilisateur ne doit contenir que des lettres.",
});
}

if (username.length < 3 || username.length > 20) {
return fail(400, {
error: "Le nom d'utilisateur doit être compris entre 3 et 20 caractères.",
});
}

if (disallowedIngredients) {
if (!/[a-zA-Z,]/.test(disallowedIngredients)) {
return fail(422, {
error: 'Les ingrédients ne doivent contenir que des lettres et des virgules.',
});
}
}

if (disallowedIngredients.length > 255) {
return fail(400, {
error: 'La liste des ingrédients à éviter ne peut pas dépasser 255 caractères.',
});
}

try {
await db.user.update({
where: { id: session.user.userId },
data: {
username,
disallowedIngredients,
},
});
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === 'P2002') {
return fail(400, { error: "le nom d'utilisateur est déjà utilisé." });
}

// eslint-disable-next-line no-console
console.error('Error while updating user:', e);

return fail(500, {
error: "Oops... Quelque chose s'est mal passé. Veuillez réessayer plus tard.",
});
}
},
} satisfies Actions;
7 changes: 6 additions & 1 deletion src/routes/account/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
import { prefersReducedMotion } from '$lib/utils/preferences';
import { toasts } from '$lib/utils/toats';
import type { PageData } from './$types';
import type { ActionData, PageData } from './$types';
import { enhance } from '$app/forms';
export let data: PageData;
export let form: ActionData;
$: if (form?.error) {
toasts.error(form.error);
}
</script>

<h1 class="h1">Profil</h1>
Expand Down
31 changes: 27 additions & 4 deletions src/routes/account/favourites/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
import { redirect } from '@sveltejs/kit';

import type { PageServerLoad } from './$types';
import type { Favourite, Recipe } from '@prisma/client';

const ALLOWED_PER_PAGE = [10, 25, 50, 100];

export const load = (async () => {
export const load = (async ({ locals }) => {
const { session, db } = locals;

if (!session) {
redirect(303, '/login');
}

const [favourites, count] = await Promise.all([
db.favourite.findMany({
where: {
userId: session.user.userId,
},
include: {
recipe: true,
},
}),
db.favourite.count({
where: {
userId: session.user.userId,
},
}),
]);

return {
count: 0,
favourites: [] as (Favourite & { recipe: Recipe })[],
favourites,
count,
allowedPerPage: ALLOWED_PER_PAGE,
perPage: ALLOWED_PER_PAGE[0],
totalPages: 1,
Expand Down
16 changes: 14 additions & 2 deletions src/routes/login/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import { auth } from '$lib/server/auth';

import type { Actions, PageServerLoad } from './$types';

export const load = (async () => {
export const load = (async ({ locals }) => {
const { session } = locals;

if (session) {
redirect(303, '/');
}

return {
seo: {
title: 'Se connecter',
Expand All @@ -18,7 +24,13 @@ export const load = (async () => {
}) satisfies PageServerLoad;

export const actions = {
login: async ({ request, cookies }) => {
login: async ({ request, cookies, locals }) => {
const { session } = locals;

if (session) {
redirect(303, '/');
}

const data = await request.formData();
const username = (data.get('username') ?? '') as string;
const password = (data.get('password') ?? '') as string;
Expand Down
6 changes: 3 additions & 3 deletions src/routes/recipes/[slug]/+layout.server.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library';
import { error } from '@sveltejs/kit';

import { db } from '$lib/server/db';

import type { LayoutServerLoad } from './$types';

export const load = (async ({ params }) => {
export const load = (async ({ params, locals }) => {
const { db } = locals;

try {
const recipe = await db.recipe.findUniqueOrThrow({
where: {
Expand Down
Loading

0 comments on commit 9f74df4

Please sign in to comment.