From 514d89e7abcfb4ffff6e1143e448b869b0d66216 Mon Sep 17 00:00:00 2001 From: Mari Zhevagin Date: Tue, 20 Oct 2026 00:38:15 +0200 Subject: [PATCH 1/4] testbruker kan ikke forande passord eller brukernavn --- server/src/schema/resolvers/user.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/server/src/schema/resolvers/user.ts b/server/src/schema/resolvers/user.ts index b508a2c..f63fd03 100644 --- a/server/src/schema/resolvers/user.ts +++ b/server/src/schema/resolvers/user.ts @@ -70,6 +70,19 @@ async function findOwnRecipe(id: string, userId: string) { return recipe; } +// testbrukeren deles av alle som tester så den skal ikke kunne endres passord eller brukernavn +const TEST_USERNAME = 'test'; + +// stopper endringer på den delte testbrukeren +async function blockTestUser(userId: string) { + const user = await prisma.user.findUnique({ where: { id: userId } }); + if (user?.username === TEST_USERNAME) { + throw new GraphQLError('Testbrukeren kan ikke endres, lag en egen bruker hvis du ønsker å teste funksjonen.', { + extensions: { code: 'FORBIDDEN' }, + }); + } +} + // bytter ut alt innhold i en oppskrift async function replaceRecipe( id: string, @@ -304,6 +317,7 @@ export const userResolvers = { extensions: { code: 'UNAUTHENTICATED' }, }); } + await blockTestUser(context.userId); // fjerner mellomrom før og etter navnet const name = args.name.trim(); @@ -330,6 +344,7 @@ export const userResolvers = { extensions: { code: 'UNAUTHENTICATED' }, }); } + await blockTestUser(context.userId); const user = await prisma.user.findUnique({ where: { id: context.userId }, From 90800c40a91427573d495c5fb008be795c438a0b Mon Sep 17 00:00:00 2001 From: Mari Zhevagin Date: Tue, 20 Oct 2026 00:38:26 +0200 Subject: [PATCH 2/4] fikset cache problem --- client/src/lib/AuthProvider.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/src/lib/AuthProvider.tsx b/client/src/lib/AuthProvider.tsx index bf4d844..4f53c26 100644 --- a/client/src/lib/AuthProvider.tsx +++ b/client/src/lib/AuthProvider.tsx @@ -1,6 +1,6 @@ import { type ReactNode } from 'react'; import { CombinedGraphQLErrors } from '@apollo/client'; -import { useMutation, useQuery } from '@apollo/client/react'; +import { useMutation, useQuery, useApolloClient } from '@apollo/client/react'; import type { User } from '../types/user'; import { AuthContext } from './authContext'; import { @@ -23,7 +23,9 @@ type AuthProviderProps = { children: ReactNode }; export function AuthProvider({ children }: AuthProviderProps) { // spør serveren hvem som er logget inn - const { data, loading, refetch } = useQuery(ME); + const { data, loading, } = useQuery(ME); + // tømmer cachen når bruker byttes + const client = useApolloClient(); const [loginMutation] = useMutation(LOGIN); const [registerMutation] = useMutation(REGISTER); const [logoutMutation] = useMutation(LOGOUT); @@ -38,7 +40,7 @@ export function AuthProvider({ children }: AuthProviderProps) { const continueAsGuest = async () => { try { await guestMutation(); - await refetch(); + await client.resetStore(); return null; } catch (error) { return getErrorMessage(error); @@ -49,7 +51,7 @@ export function AuthProvider({ children }: AuthProviderProps) { const login = async (username: string, password: string) => { try { await loginMutation({ variables: { username, password } }); - await refetch(); + await client.resetStore(); return null; } catch (error) { return getErrorMessage(error); @@ -60,7 +62,7 @@ export function AuthProvider({ children }: AuthProviderProps) { const register = async (username: string, password: string) => { try { await registerMutation({ variables: { username, password } }); - await refetch(); + await client.resetStore(); return null; } catch (error) { return getErrorMessage(error); @@ -69,7 +71,7 @@ export function AuthProvider({ children }: AuthProviderProps) { const logout = async () => { await logoutMutation(); - await refetch(); + await client.resetStore(); }; return ( From 15a016618344c6d422d75acb6ad6118bd20dcbfa Mon Sep 17 00:00:00 2001 From: Mari Zhevagin Date: Tue, 20 Oct 2026 00:52:45 +0200 Subject: [PATCH 3/4] fikset min side bug med at siden hopper ved fanebytt --- client/src/components/layout/UserLink.tsx | 7 +++++++ client/src/lib/AuthProvider.tsx | 2 +- client/src/routes/ProfilePage.tsx | 3 ++- server/src/schema/resolvers/user.ts | 9 ++++++--- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/client/src/components/layout/UserLink.tsx b/client/src/components/layout/UserLink.tsx index fcc5f0e..ebcc1db 100644 --- a/client/src/components/layout/UserLink.tsx +++ b/client/src/components/layout/UserLink.tsx @@ -3,6 +3,12 @@ import PersonOutlinedIcon from '@mui/icons-material/PersonOutlined'; import PersonIcon from '@mui/icons-material/Person'; import { useCurrentUser } from '../../lib/useCurrentUser'; +// glir til toppen men hopper rett opp hvis animasjoner er skrudd av +function scrollToTop() { + const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + window.scrollTo({ top: 0, behavior: reduce ? 'auto' : 'smooth' }); +} + // brukerikonet går til min side eller til innlogging export function UserLink() { const { user } = useCurrentUser(); @@ -11,6 +17,7 @@ export function UserLink() { `flex text-4xl transition-colors focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-pink-light ${ isActive ? 'text-primary' : 'text-primary/80 hover:text-primary' diff --git a/client/src/lib/AuthProvider.tsx b/client/src/lib/AuthProvider.tsx index 4f53c26..4bf606e 100644 --- a/client/src/lib/AuthProvider.tsx +++ b/client/src/lib/AuthProvider.tsx @@ -23,7 +23,7 @@ type AuthProviderProps = { children: ReactNode }; export function AuthProvider({ children }: AuthProviderProps) { // spør serveren hvem som er logget inn - const { data, loading, } = useQuery(ME); + const { data, loading } = useQuery(ME); // tømmer cachen når bruker byttes const client = useApolloClient(); const [loginMutation] = useMutation(LOGIN); diff --git a/client/src/routes/ProfilePage.tsx b/client/src/routes/ProfilePage.tsx index 047d777..fdbbbe0 100644 --- a/client/src/routes/ProfilePage.tsx +++ b/client/src/routes/ProfilePage.tsx @@ -241,8 +241,9 @@ export default function ProfilePage() { {/* oppskriftsfanene */} + {/* minstehøyde så siden ikke krymper og kaster deg opp når fanen byttes */}
Date: Tue, 20 Oct 2026 01:00:39 +0200 Subject: [PATCH 4/4] =?UTF-8?q?bugfix:=20at=20man=20kommer=20=C3=B8verst?= =?UTF-8?q?=20p=C3=A5=20siden=20n=C3=A5r=20du=20bytter=20side?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/layout/Layout.tsx | 15 ++++++++++++++- server/src/schema/resolvers/user.ts | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/client/src/components/layout/Layout.tsx b/client/src/components/layout/Layout.tsx index 8cdf1fb..cd9ac96 100644 --- a/client/src/components/layout/Layout.tsx +++ b/client/src/components/layout/Layout.tsx @@ -1,13 +1,26 @@ -import { Outlet } from 'react-router'; +import { Outlet, useLocation } from 'react-router'; +import { useEffect } from 'react'; import Header from './Header'; import { BottomNav } from './BottomNav'; import { MotionConfig } from 'motion/react'; +// starter øverst på siden når man går til en ny side +function ScrollToTop() { + const { pathname } = useLocation(); + + useEffect(() => { + window.scrollTo(0, 0); + }, [pathname]); + + return null; +} + // felles ramme for alle sider export default function Layout() { return ( // gir mulighet for bruker å skru av animasjoner +
{/* ekstra plass nederst på mobil så bunnmenyen ikke dekker innholdet */} diff --git a/server/src/schema/resolvers/user.ts b/server/src/schema/resolvers/user.ts index 654ae01..203d9d1 100644 --- a/server/src/schema/resolvers/user.ts +++ b/server/src/schema/resolvers/user.ts @@ -70,7 +70,7 @@ async function findOwnRecipe(id: string, userId: string) { return recipe; } -// testbrukeren deles av alle som tester så den skal ikke kunne endres passord eller brukernavn +// testbrukeren deles av alle som tester så den skal ikke kunne endres passord eller navn const TEST_USERNAME = 'test'; // stopper endringer på den delte testbrukeren