From abe8ca90ee0b40ab6a5177f38fdfadf4194ffb05 Mon Sep 17 00:00:00 2001 From: Bradley Shellnut Date: Thu, 15 Aug 2024 16:46:58 -0700 Subject: [PATCH] Fixing infinite user get loop. --- src/hooks.server.ts | 80 +++++++++---------- .../server/api/controllers/iam.controller.ts | 22 ++++- src/routes/(app)/+layout.server.ts | 2 +- src/routes/(app)/+page.server.ts | 4 +- src/routes/(auth)/logout/+page.server.ts | 18 +---- 5 files changed, 67 insertions(+), 59 deletions(-) diff --git a/src/hooks.server.ts b/src/hooks.server.ts index fd1e06a..295a8f4 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -3,8 +3,6 @@ import 'reflect-metadata' import { hc } from 'hono/client'; import { sequence } from '@sveltejs/kit/hooks'; import { redirect, type Handle } from '@sveltejs/kit'; -import { dev } from '$app/environment'; -// import { lucia } from '$lib/server/auth'; import type { ApiRoutes } from '$lib/server/api'; import { parseApiResponse } from '$lib/utils/api'; import { StatusCodes } from '$lib/constants/status-codes'; @@ -50,45 +48,45 @@ const apiClient: Handle = async ({ event, resolve }) => { return response; }; -export const authentication: Handle = async function ({ event, resolve }) { - event.locals.startTimer = Date.now(); - - const ip = event.request.headers.get('x-forwarded-for') as string; - const country = event.request.headers.get('x-vercel-ip-country') as string; - event.locals.ip = dev ? '127.0.0.1' : ip; // || event.getClientAddress(); - event.locals.country = dev ? 'us' : country; - - const sessionId = event.cookies.get(lucia.sessionCookieName); - if (!sessionId) { - event.locals.user = null; - event.locals.session = null; - return resolve(event); - } - - const { session, user } = await lucia.validateSession(sessionId); - if (session && session.fresh) { - const sessionCookie = lucia.createSessionCookie(session.id); - console.log('sessionCookie', JSON.stringify(sessionCookie, null, 2)); - // sveltekit types deviates from the de-facto standard, you can use 'as any' too - event.cookies.set(sessionCookie.name, sessionCookie.value, { - path: '.', - ...sessionCookie.attributes, - }); - } - console.log('session from hooks', JSON.stringify(session, null, 2)); - if (!session) { - const sessionCookie = lucia.createBlankSessionCookie(); - console.log('blank sessionCookie', JSON.stringify(sessionCookie, null, 2)); - event.cookies.set(sessionCookie.name, sessionCookie.value, { - path: '.', - ...sessionCookie.attributes, - }); - } - event.locals.user = user; - event.locals.session = session; - - return resolve(event); -}; +// export const authentication: Handle = async function ({ event, resolve }) { +// event.locals.startTimer = Date.now(); +// +// const ip = event.request.headers.get('x-forwarded-for') as string; +// const country = event.request.headers.get('x-vercel-ip-country') as string; +// event.locals.ip = dev ? '127.0.0.1' : ip; // || event.getClientAddress(); +// event.locals.country = dev ? 'us' : country; +// +// const sessionId = event.cookies.get(lucia.sessionCookieName); +// if (!sessionId) { +// event.locals.user = null; +// event.locals.session = null; +// return resolve(event); +// } +// +// const { session, user } = await lucia.validateSession(sessionId); +// if (session && session.fresh) { +// const sessionCookie = lucia.createSessionCookie(session.id); +// console.log('sessionCookie', JSON.stringify(sessionCookie, null, 2)); +// // sveltekit types deviates from the de-facto standard, you can use 'as any' too +// event.cookies.set(sessionCookie.name, sessionCookie.value, { +// path: '.', +// ...sessionCookie.attributes, +// }); +// } +// console.log('session from hooks', JSON.stringify(session, null, 2)); +// if (!session) { +// const sessionCookie = lucia.createBlankSessionCookie(); +// console.log('blank sessionCookie', JSON.stringify(sessionCookie, null, 2)); +// event.cookies.set(sessionCookie.name, sessionCookie.value, { +// path: '.', +// ...sessionCookie.attributes, +// }); +// } +// event.locals.user = user; +// event.locals.session = session; +// +// return resolve(event); +// }; export const handle: Handle = sequence( // Sentry.sentryHandle(), diff --git a/src/lib/server/api/controllers/iam.controller.ts b/src/lib/server/api/controllers/iam.controller.ts index 35e6fc6..fdcc6d3 100644 --- a/src/lib/server/api/controllers/iam.controller.ts +++ b/src/lib/server/api/controllers/iam.controller.ts @@ -1,14 +1,19 @@ import { Hono } from 'hono'; -import { injectable } from 'tsyringe'; +import { inject, injectable } from 'tsyringe'; +import { setCookie } from 'hono/cookie'; import type { HonoTypes } from '../types'; import { requireAuth } from "../middleware/auth.middleware"; import type { Controller } from '../interfaces/controller.interface'; +import {IamService} from "$lib/server/api/services/iam.service"; +import {LuciaProvider} from "$lib/server/api/providers"; @injectable() export class IamController implements Controller { controller = new Hono(); constructor( + @inject(IamService) private readonly iamService: IamService, + @inject(LuciaProvider) private lucia: LuciaProvider ) { } routes() { @@ -16,6 +21,21 @@ export class IamController implements Controller { .get('/me', requireAuth, async (c) => { const user = c.var.user; return c.json({ user }); + }) + .post('/logout', requireAuth, async (c) => { + const sessionId = c.var.session.id; + await this.iamService.logout(sessionId); + const sessionCookie = this.lucia.createBlankSessionCookie(); + setCookie(c, sessionCookie.name, sessionCookie.value, { + path: sessionCookie.attributes.path, + maxAge: sessionCookie.attributes.maxAge, + domain: sessionCookie.attributes.domain, + sameSite: sessionCookie.attributes.sameSite as any, + secure: sessionCookie.attributes.secure, + httpOnly: sessionCookie.attributes.httpOnly, + expires: sessionCookie.attributes.expires + }); + return c.json({ status: 'success' }); }); } } diff --git a/src/routes/(app)/+layout.server.ts b/src/routes/(app)/+layout.server.ts index 58a037f..aa43781 100644 --- a/src/routes/(app)/+layout.server.ts +++ b/src/routes/(app)/+layout.server.ts @@ -5,7 +5,7 @@ import type { LayoutServerLoad } from '../$types'; export const load: LayoutServerLoad = loadFlash(async (event) => { const { url, locals, cookies } = event; - const authedUser = await locals.getAuthedUserOrThrow(); + const authedUser = await locals.getAuthedUser(); // if (userNotFullyAuthenticated(user, session)) { // await lucia.invalidateSession(locals.session!.id!); diff --git a/src/routes/(app)/+page.server.ts b/src/routes/(app)/+page.server.ts index 2985735..d554b67 100644 --- a/src/routes/(app)/+page.server.ts +++ b/src/routes/(app)/+page.server.ts @@ -42,7 +42,7 @@ export const load: PageServerLoad = async (event) => { }, }); - // if (userFullyAuthenticated(user, session)) { + if (authedUser) { const dbUser = await db.query.usersTable.findFirst({ where: eq(usersTable.id, authedUser!.id!), }); @@ -75,7 +75,7 @@ export const load: PageServerLoad = async (event) => { wishlists: userWishlists, collections: userCollection, }; - // } + } return { metaTagsChild: metaTags, user: null, wishlists: [], collections: [] }; }; diff --git a/src/routes/(auth)/logout/+page.server.ts b/src/routes/(auth)/logout/+page.server.ts index 78f9d98..b8fb2c5 100644 --- a/src/routes/(auth)/logout/+page.server.ts +++ b/src/routes/(auth)/logout/+page.server.ts @@ -1,22 +1,12 @@ -import { fail } from '@sveltejs/kit'; import { redirect } from 'sveltekit-flash-message/server'; -import { lucia } from '$lib/server/auth'; -import { signedOutMessage } from '$lib/flashMessages'; import type { Actions } from "./$types"; +import {StatusCodes} from "$lib/constants/status-codes"; export const actions: Actions = { default: async (event) => { - const { locals, cookies } = event; + const { locals } = event; console.log('Signing out user'); - if (!locals.session) { - return fail(401); - } - await lucia.invalidateSession(locals.session.id); - const sessionCookie = lucia.createBlankSessionCookie(); - cookies.set(sessionCookie.name, sessionCookie.value, { - path: '.', - ...sessionCookie.attributes - }); - return redirect(302, '/login', signedOutMessage, event); + await locals.api.me.logout.$post() + redirect(StatusCodes.SEE_OTHER, '/login') } };