From 90c2f9810f18393691820ee78b3261b4a6584649 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Thu, 10 Aug 2023 16:43:37 +0200 Subject: [PATCH 01/17] Update useGetUserQuery --- src/hooks/api/user.ts | 3 ++- src/layouts/Sidebar.tsx | 3 +-- src/pages/dashboard/index.page.tsx | 7 +------ .../steps/AdditionalInformationStep/OrganizerPicker.tsx | 1 - src/pages/steps/LocationStep.tsx | 1 - 5 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/hooks/api/user.ts b/src/hooks/api/user.ts index 0713382cf..efeb10d9e 100644 --- a/src/hooks/api/user.ts +++ b/src/hooks/api/user.ts @@ -8,6 +8,7 @@ import { ServerSideQueryOptions, useAuthenticatedQuery, } from './authenticated-query'; +import { useAuthenticatedQuery as useAuthenticatedQueryV2 } from './authenticated-query-v2'; type User = { sub: string; @@ -58,7 +59,7 @@ const getUser = async (cookies: Cookies) => { const useGetUserQuery = () => { const { cookies } = useCookiesWithOptions(['idToken']); - return useAuthenticatedQuery({ + return useAuthenticatedQueryV2({ queryKey: ['user'], queryFn: () => getUser(cookies), }); diff --git a/src/layouts/Sidebar.tsx b/src/layouts/Sidebar.tsx index be9861aaf..9df9ce26d 100644 --- a/src/layouts/Sidebar.tsx +++ b/src/layouts/Sidebar.tsx @@ -187,8 +187,7 @@ const ProfileMenu = ({ defaultProfileImageUrl }: ProfileMenuProps) => { const queryClient = useQueryClient(); const getUserQuery = useGetUserQuery(); - // @ts-expect-error - const user = getUserQuery.data as User; + const user = getUserQuery.data; const loginMenu = [ { diff --git a/src/pages/dashboard/index.page.tsx b/src/pages/dashboard/index.page.tsx index bd20003df..ccb237b02 100644 --- a/src/pages/dashboard/index.page.tsx +++ b/src/pages/dashboard/index.page.tsx @@ -241,9 +241,7 @@ const OfferRow = ({ item: offer, onDelete, ...props }: OfferRowProps) => { const { t, i18n } = useTranslation(); const getUserQuery = useGetUserQuery(); - // @ts-expect-error const userId = getUserQuery.data?.sub; - // @ts-expect-error const userIdv1 = getUserQuery.data?.['https://publiq.be/uitidv1id']; const isExternalCreator = ![userId, userIdv1].includes(offer.creator); @@ -361,9 +359,7 @@ const OrganizerRow = ({ const { t, i18n } = useTranslation(); const getUserQuery = useGetUserQuery(); - // @ts-expect-error const userId = getUserQuery.data?.sub; - // @ts-expect-error const userIdv1 = getUserQuery.data?.['https://publiq.be/uitidv1id']; const isExternalCreator = ![userId, userIdv1].includes(organizer.creator); @@ -550,8 +546,7 @@ const Dashboard = (): any => { ); const getUserQuery = useGetUserQuery(); - // @ts-expect-error - const user = getUserQuery.data as User; + const user = getUserQuery.data; const handleSelectSorting = (event) => { const sortValue = event.target.value; diff --git a/src/pages/steps/AdditionalInformationStep/OrganizerPicker.tsx b/src/pages/steps/AdditionalInformationStep/OrganizerPicker.tsx index 1baed1b33..04ed50993 100644 --- a/src/pages/steps/AdditionalInformationStep/OrganizerPicker.tsx +++ b/src/pages/steps/AdditionalInformationStep/OrganizerPicker.tsx @@ -136,7 +136,6 @@ const OrganizerPicker = ({ const queryClient = useQueryClient(); const getUserQuery = useGetUserQuery(); - // @ts-expect-error const user = getUserQuery.data; const [addButtonHasBeenPressed, setAddButtonHasBeenPressed] = useState(false); diff --git a/src/pages/steps/LocationStep.tsx b/src/pages/steps/LocationStep.tsx index 541897a91..3680945fb 100644 --- a/src/pages/steps/LocationStep.tsx +++ b/src/pages/steps/LocationStep.tsx @@ -524,7 +524,6 @@ const RecentLocations = ({ onFieldChange, ...props }) => { const getOffersQuery = useGetOffersByCreatorQuery( { advancedQuery: '_exists_:location.id AND NOT (audienceType:"education")', - // @ts-expect-error creator: getUserQuery?.data, sortOptions: { field: 'modified', From 65329749f24042d999744565a4b72f69a72a770b Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 11 Aug 2023 12:54:35 +0200 Subject: [PATCH 02/17] Add types to useHeaders --- src/hooks/api/{useHeaders.js => useHeaders.ts} | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) rename src/hooks/api/{useHeaders.js => useHeaders.ts} (83%) diff --git a/src/hooks/api/useHeaders.js b/src/hooks/api/useHeaders.ts similarity index 83% rename from src/hooks/api/useHeaders.js rename to src/hooks/api/useHeaders.ts index f5a18ab0c..a268b5926 100644 --- a/src/hooks/api/useHeaders.js +++ b/src/hooks/api/useHeaders.ts @@ -2,7 +2,10 @@ import getConfig from 'next/config'; import { useCookiesWithOptions } from '../useCookiesWithOptions'; -const createHeaders = (token, extraHeaders) => { +const createHeaders = ( + token: string, + extraHeaders: HeadersInit = {}, +): HeadersInit => { const { publicRuntimeConfig } = getConfig(); return { From ca3892dc049d00aebb965e9068a4e87d99d72e2f Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 11 Aug 2023 12:56:48 +0200 Subject: [PATCH 03/17] Update useGetPermissionsQuery --- src/hooks/api/authenticated-query-v2.ts | 21 +++++++-------------- src/hooks/api/user.ts | 12 +++++++----- src/layouts/Sidebar.tsx | 3 --- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/hooks/api/authenticated-query-v2.ts b/src/hooks/api/authenticated-query-v2.ts index e6413f992..6049df91e 100644 --- a/src/hooks/api/authenticated-query-v2.ts +++ b/src/hooks/api/authenticated-query-v2.ts @@ -26,9 +26,10 @@ type GenerateQueryKeyArguments = { type GeneratedQueryKey = readonly [QueryKey, QueryArguments]; -type AuthenticatedQueryFunctionContext = QueryFunctionContext & { - headers: Headers; -}; +type AuthenticatedQueryFunctionContext = + QueryFunctionContext & { + headers: Headers; + }; type ServerSideOptions = { req: NextApiRequest; @@ -60,7 +61,7 @@ const generateQueryKey = ({ type GetPreparedOptionsArguments = { options: UseAuthenticatedQueryOptions; isTokenPresent: boolean; - headers: Headers; + headers: HeadersInit; }; const getPreparedOptions = ({ @@ -79,19 +80,11 @@ const getPreparedOptions = ({ queryArguments, }); - const queryFunctionWithHeaders = async ( - context: QueryFunctionContext, - ) => { - return await queryFn( - context, - // @ts-expect-error - headers, - ); - }; return { ...restOptions, queryKey: generatedQueryKey, - queryFn: queryFunctionWithHeaders, + meta: { headers }, + queryFn: queryFn, ...('enabled' in restOptions && { enabled: isTokenPresent && !!restOptions.enabled, }), diff --git a/src/hooks/api/user.ts b/src/hooks/api/user.ts index efeb10d9e..2fbbc234d 100644 --- a/src/hooks/api/user.ts +++ b/src/hooks/api/user.ts @@ -1,5 +1,4 @@ import jwt_decode from 'jwt-decode'; -import getConfig from 'next/config'; import { FetchError, fetchFromApi, isErrorObject } from '@/utils/fetchFromApi'; @@ -80,22 +79,25 @@ const useGetUserQueryServerSide = ( }); }; -const getPermissions = async ({ headers }) => { +const getPermissions = async ({ meta }): Promise => { const res = await fetchFromApi({ path: '/user/permissions/', options: { - headers, + headers: meta.headers as Headers, }, }); + if (isErrorObject(res)) { // eslint-disable-next-line no-console - return console.error(res); + console.error(res); + return []; } + return await res.json(); }; const useGetPermissionsQuery = (configuration = {}) => - useAuthenticatedQuery({ + useAuthenticatedQueryV2({ queryKey: ['user', 'permissions'], queryFn: getPermissions, ...configuration, diff --git a/src/layouts/Sidebar.tsx b/src/layouts/Sidebar.tsx index 9df9ce26d..2893506da 100644 --- a/src/layouts/Sidebar.tsx +++ b/src/layouts/Sidebar.tsx @@ -464,7 +464,6 @@ const Sidebar = () => { ]; const filteredManageMenu = useMemo(() => { - // @ts-expect-error if (!getPermissionsQuery.data) { return []; } @@ -519,10 +518,8 @@ const Sidebar = () => { ]; return manageMenu.filter((menuItem) => { - // @ts-expect-error return getPermissionsQuery.data.includes(menuItem.permission); }); - // @ts-expect-error }, [countEventsToModerate, getPermissionsQuery.data, i18n.language, t]); return [ From 62579f29839e45c138cd10c3db2f78290fb8bb9b Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 11 Aug 2023 12:59:03 +0200 Subject: [PATCH 04/17] Update useGetRolesQuery --- src/hooks/api/user.ts | 6 +++--- src/layouts/Sidebar.tsx | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/hooks/api/user.ts b/src/hooks/api/user.ts index 2fbbc234d..c88b0c8dc 100644 --- a/src/hooks/api/user.ts +++ b/src/hooks/api/user.ts @@ -103,11 +103,11 @@ const useGetPermissionsQuery = (configuration = {}) => ...configuration, }); -const getRoles = async ({ headers }) => { +const getRoles = async ({ meta }) => { const res = await fetchFromApi({ path: '/user/roles/', options: { - headers, + headers: meta.headers as HeadersInit, }, }); if (isErrorObject(res)) { @@ -118,7 +118,7 @@ const getRoles = async ({ headers }) => { }; const useGetRolesQuery = (configuration = {}) => - useAuthenticatedQuery({ + useAuthenticatedQueryV2({ queryKey: ['user', 'roles'], queryFn: getRoles, ...configuration, diff --git a/src/layouts/Sidebar.tsx b/src/layouts/Sidebar.tsx index 2893506da..cb2669976 100644 --- a/src/layouts/Sidebar.tsx +++ b/src/layouts/Sidebar.tsx @@ -406,19 +406,16 @@ const Sidebar = () => { }, [rawAnnouncements]); useEffect(() => { - // @ts-expect-error if (!getRolesQuery.data) { return; } - // @ts-expect-error const validationQuery = getRolesQuery.data .map((role) => (role.constraints?.v3 ? role.constraints.v3 : null)) .filter((constraint) => constraint !== null) .join(' OR '); setSearchQuery(validationQuery); - // @ts-expect-error }, [getRolesQuery.data]); const announcements = useMemo( From 960564de7be98899770e35b9c7a0e5a17d8c6016 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 11 Aug 2023 14:23:19 +0200 Subject: [PATCH 05/17] Pass headers through context instead of meta --- src/hooks/api/authenticated-query-v2.ts | 15 +++++++++++---- src/hooks/api/user.ts | 21 +++++++++++---------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/hooks/api/authenticated-query-v2.ts b/src/hooks/api/authenticated-query-v2.ts index 6049df91e..6aa1f38ca 100644 --- a/src/hooks/api/authenticated-query-v2.ts +++ b/src/hooks/api/authenticated-query-v2.ts @@ -28,7 +28,7 @@ type GeneratedQueryKey = readonly [QueryKey, QueryArguments]; type AuthenticatedQueryFunctionContext = QueryFunctionContext & { - headers: Headers; + headers: HeadersInit; }; type ServerSideOptions = { @@ -43,7 +43,14 @@ type PrefetchAuthenticatedQueryOptions = { type UseAuthenticatedQueryOptions = { queryArguments?: QueryArguments; -} & UseQueryOptions; +} & Omit< + UseQueryOptions, + 'queryFn' +> & { + queryFn: ( + context: AuthenticatedQueryFunctionContext, + ) => TQueryFnData | Promise; + }; const isUnAuthorized = (status: number) => [401, 403].includes(status); @@ -83,8 +90,7 @@ const getPreparedOptions = ({ return { ...restOptions, queryKey: generatedQueryKey, - meta: { headers }, - queryFn: queryFn, + queryFn: (context) => queryFn({ ...context, headers }), ...('enabled' in restOptions && { enabled: isTokenPresent && !!restOptions.enabled, }), @@ -104,6 +110,7 @@ const prefetchAuthenticatedQuery = async ({ const headers = createHeaders(cookies.get('token')); const { queryKey, queryFn } = getPreparedOptions({ + // @ts-expect-error options, isTokenPresent: isTokenValid(cookies.get('token')), headers, diff --git a/src/hooks/api/user.ts b/src/hooks/api/user.ts index c88b0c8dc..2465476f0 100644 --- a/src/hooks/api/user.ts +++ b/src/hooks/api/user.ts @@ -79,21 +79,19 @@ const useGetUserQueryServerSide = ( }); }; -const getPermissions = async ({ meta }): Promise => { +const getPermissions = async ({ headers }) => { const res = await fetchFromApi({ path: '/user/permissions/', - options: { - headers: meta.headers as Headers, - }, + options: { headers }, }); if (isErrorObject(res)) { // eslint-disable-next-line no-console console.error(res); - return []; + return; } - return await res.json(); + return (await res.json()) as string[]; }; const useGetPermissionsQuery = (configuration = {}) => @@ -103,18 +101,21 @@ const useGetPermissionsQuery = (configuration = {}) => ...configuration, }); -const getRoles = async ({ meta }) => { +const getRoles = async ({ headers }) => { const res = await fetchFromApi({ path: '/user/roles/', options: { - headers: meta.headers as HeadersInit, + headers, }, }); + if (isErrorObject(res)) { // eslint-disable-next-line no-console - return console.error(res); + console.error(res); + return; } - return await res.json(); + + return (await res.json()) as any[]; }; const useGetRolesQuery = (configuration = {}) => From c01e417be64bb22820bafcd0fccf14c35a6b7ef9 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 11 Aug 2023 15:39:34 +0200 Subject: [PATCH 06/17] Update useGetUserQueryServerSide --- src/hooks/api/user.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hooks/api/user.ts b/src/hooks/api/user.ts index 2465476f0..4935e3d0e 100644 --- a/src/hooks/api/user.ts +++ b/src/hooks/api/user.ts @@ -3,11 +3,11 @@ import jwt_decode from 'jwt-decode'; import { FetchError, fetchFromApi, isErrorObject } from '@/utils/fetchFromApi'; import { Cookies, useCookiesWithOptions } from '../useCookiesWithOptions'; +import { ServerSideQueryOptions } from './authenticated-query'; import { - ServerSideQueryOptions, - useAuthenticatedQuery, -} from './authenticated-query'; -import { useAuthenticatedQuery as useAuthenticatedQueryV2 } from './authenticated-query-v2'; + prefetchAuthenticatedQuery, + useAuthenticatedQuery as useAuthenticatedQueryV2, +} from './authenticated-query-v2'; type User = { sub: string; @@ -70,7 +70,7 @@ const useGetUserQueryServerSide = ( ) => { const cookies = req.cookies; - return useAuthenticatedQuery({ + return prefetchAuthenticatedQuery({ req, queryClient, queryKey: ['user'], From b27f7bb4ba3670a6b67bdfaf710d917469328c88 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Thu, 24 Aug 2023 14:35:35 +0200 Subject: [PATCH 07/17] Work on failed authentication --- src/hooks/api/authenticated-query-v2.ts | 3 +- src/hooks/api/authenticated-query.ts | 3 +- src/hooks/api/user.ts | 2 +- src/layouts/{index.js => index.tsx} | 4 +- src/pages/dashboard/index.page.tsx | 4 +- ...ps.js => getApplicationServerSideProps.ts} | 52 +++++++++++++------ 6 files changed, 46 insertions(+), 22 deletions(-) rename src/layouts/{index.js => index.tsx} (98%) rename src/utils/{getApplicationServerSideProps.js => getApplicationServerSideProps.ts} (75%) diff --git a/src/hooks/api/authenticated-query-v2.ts b/src/hooks/api/authenticated-query-v2.ts index 6aa1f38ca..414eb440d 100644 --- a/src/hooks/api/authenticated-query-v2.ts +++ b/src/hooks/api/authenticated-query-v2.ts @@ -16,6 +16,7 @@ import { isTokenValid } from '@/utils/isTokenValid'; import { useCookiesWithOptions } from '../useCookiesWithOptions'; import { Headers } from './types/Headers'; import { createHeaders, useHeaders } from './useHeaders'; +import { GetServerSidePropsContext } from 'next/types'; type QueryArguments = Record; @@ -32,7 +33,7 @@ type AuthenticatedQueryFunctionContext = }; type ServerSideOptions = { - req: NextApiRequest; + req: GetServerSidePropsContext['req']; queryClient: QueryClient; }; diff --git a/src/hooks/api/authenticated-query.ts b/src/hooks/api/authenticated-query.ts index 66aeb6791..62ce18575 100644 --- a/src/hooks/api/authenticated-query.ts +++ b/src/hooks/api/authenticated-query.ts @@ -19,9 +19,10 @@ import { isErrorObject } from '@/utils/fetchFromApi'; import { isTokenValid } from '@/utils/isTokenValid'; import { createHeaders, useHeaders } from './useHeaders'; +import { GetServerSidePropsContext } from 'next/types'; type ServerSideQueryOptions = { - req?: NextApiRequest; + req?: GetServerSidePropsContext['req']; queryClient?: QueryClient; }; diff --git a/src/hooks/api/user.ts b/src/hooks/api/user.ts index 4935e3d0e..f8b7f968c 100644 --- a/src/hooks/api/user.ts +++ b/src/hooks/api/user.ts @@ -45,7 +45,7 @@ const getUser = async (cookies: Cookies) => { throw new FetchError(401, 'Unauthorized'); } - const userInfo = jwt_decode(cookies.idToken) as User; + const userInfo = jwt_decode(cookies.idToken); const decodedAccessToken = jwt_decode(cookies.token) as decodedAccessToken; if (Date.now() >= decodedAccessToken.exp * 1000) { diff --git a/src/layouts/index.js b/src/layouts/index.tsx similarity index 98% rename from src/layouts/index.js rename to src/layouts/index.tsx index 785b7fb50..53bf05b31 100644 --- a/src/layouts/index.js +++ b/src/layouts/index.tsx @@ -33,10 +33,10 @@ const useHandleAuthentication = () => { const getUserQuery = useGetUserQuery(); useEffect(() => { - if (!getUserQuery.data) return; + if (!getUserQuery?.data) return; Sentry.setUser({ id: getUserQuery.data.id }); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [getUserQuery.data]); + }, [getUserQuery?.data]); // redirect when there is no token or user cookie // manipulation from outside the application diff --git a/src/pages/dashboard/index.page.tsx b/src/pages/dashboard/index.page.tsx index ccb237b02..e09defce8 100644 --- a/src/pages/dashboard/index.page.tsx +++ b/src/pages/dashboard/index.page.tsx @@ -725,10 +725,10 @@ const Dashboard = (): any => { const getServerSideProps = getApplicationServerSideProps( async ({ req, query, cookies: rawCookies, queryClient }) => { - const user = (await useGetUserQueryServerSide({ + const user = await useGetUserQueryServerSide({ req, queryClient, - })) as User; + }); await Promise.all( Object.entries(UseGetItemsByCreatorMap).map(([key, hook]) => { diff --git a/src/utils/getApplicationServerSideProps.js b/src/utils/getApplicationServerSideProps.ts similarity index 75% rename from src/utils/getApplicationServerSideProps.js rename to src/utils/getApplicationServerSideProps.ts index 26e1be804..3de3b2cea 100644 --- a/src/utils/getApplicationServerSideProps.js +++ b/src/utils/getApplicationServerSideProps.ts @@ -1,17 +1,16 @@ import * as Sentry from '@sentry/nextjs'; import getConfig from 'next/config'; +import { GetServerSidePropsContext } from 'next/types'; import absoluteUrl from 'next-absolute-url'; import { QueryClient } from 'react-query'; import { generatePath, matchPath } from 'react-router'; import UniversalCookies from 'universal-cookie'; -import { useGetUserQuery, useGetUserQueryServerSide } from '@/hooks/api/user'; -import { defaultCookieOptions } from '@/hooks/useCookiesWithOptions'; +import { useGetUserQueryServerSide } from '@/hooks/api/user'; import { isFeatureFlagEnabledInCookies } from '@/hooks/useFeatureFlag'; import { getRedirects } from '../redirects'; import { FetchError } from './fetchFromApi'; -import { isTokenValid } from './isTokenValid'; class Cookies extends UniversalCookies { toString() { @@ -19,7 +18,7 @@ class Cookies extends UniversalCookies { return cookieEntries.reduce((previous, [key, value], currentIndex) => { const end = currentIndex !== cookieEntries.length - 1 ? '; ' : ''; - const pair = `${key}=${encodeURIComponent(value)}${end}`; + const pair = `${key}=${encodeURIComponent(value as string)}${end}`; return `${previous}${pair}`; }, ''); } @@ -61,7 +60,13 @@ const getRedirect = (originalPath, environment, cookies) => { .find((match) => !!match); }; -const redirectToLogin = (cookies, req, resolvedUrl) => { +const redirectToLogin = ({ + cookies, + req, + resolvedUrl, +}: Pick & { + cookies: Cookies; +}) => { Sentry.setUser(null); cookies.remove('token'); @@ -76,22 +81,31 @@ const redirectToLogin = (cookies, req, resolvedUrl) => { }; }; +type ExtendedGetServerSidePropsContext = GetServerSidePropsContext & { + cookies: string; + queryClient: QueryClient; +}; + const getApplicationServerSideProps = - (callbackFn) => - async ({ req, query, resolvedUrl }) => { + (callbackFn?: (context: ExtendedGetServerSidePropsContext) => any) => + async ({ + req, + query, + resolvedUrl, + ...context + }: GetServerSidePropsContext) => { const { publicRuntimeConfig } = getConfig(); if (publicRuntimeConfig.environment === 'development') { - process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; + process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; } - const rawCookies = req?.headers?.cookie ?? ''; - - const cookies = new Cookies(rawCookies, defaultCookieOptions); + const cookies = new Cookies(req.cookies); req.headers.cookie = cookies.toString(); - const isDynamicUrl = !!query.params; - const path = isDynamicUrl ? `/${query.params.join('/')}` : resolvedUrl; + const params = (query.params as string[]) ?? []; + const isDynamicUrl = Object.keys(params).length > 0; + const path = isDynamicUrl ? `/${params.join('/')}` : resolvedUrl; const redirect = getRedirect( path, @@ -102,7 +116,9 @@ const getApplicationServerSideProps = if (redirect) { // Don't include the `params` in the redirect URL's query. delete query.params; - const queryParameters = new URLSearchParams(query); + const queryParameters = new URLSearchParams( + query as Record, + ); // Return the redirect as-is if there are no additional query parameters // to append. @@ -124,7 +140,11 @@ const getApplicationServerSideProps = await useGetUserQueryServerSide({ req, queryClient }); } catch (error) { if (error instanceof FetchError) { - return redirectToLogin(cookies, req, resolvedUrl); + return redirectToLogin({ + cookies, + req, + resolvedUrl, + }); } } @@ -133,6 +153,8 @@ const getApplicationServerSideProps = if (!callbackFn) return { props: { cookies: cookies.toString() } }; return await callbackFn({ + ...context, + resolvedUrl, req, query, queryClient, From 5cbbdc5f26567fbfda67036b4757a1e7d110b5f7 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 25 Aug 2023 12:02:46 +0200 Subject: [PATCH 08/17] Fix Sidebar not returning valid JSX --- src/layouts/Sidebar.tsx | 200 ++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 99 deletions(-) diff --git a/src/layouts/Sidebar.tsx b/src/layouts/Sidebar.tsx index cb2669976..02aeef95e 100644 --- a/src/layouts/Sidebar.tsx +++ b/src/layouts/Sidebar.tsx @@ -519,119 +519,121 @@ const Sidebar = () => { }); }, [countEventsToModerate, getPermissionsQuery.data, i18n.language, t]); - return [ - { - if (!sidebarComponent?.current) return; - if (document.activeElement?.tagName?.toLowerCase() !== 'iframe') { - return; - } - // @ts-expect-error - document.activeElement.blur(); - }} - > - - - + return ( + <> :not(:first-child) { - border-top: 1px solid ${getValueForMenu('borderColor')}; - } + overflow: hidden; `} + width={{ default: '230px', s: '65px' }} + backgroundColor={getValueForSidebar('backgroundColor')} + color={getValueForSidebar('color')} + zIndex={getValueForSidebar('zIndex')} + padding={{ default: 2, s: 1 }} + spacing={3} + ref={sidebarComponent} + onMouseOver={() => { + if (!sidebarComponent?.current) return; + if (document.activeElement?.tagName?.toLowerCase() !== 'iframe') { + return; + } + // @ts-expect-error + document.activeElement.blur(); + }} > - + + + 0 ? 'space-between' : 'flex-end' - } + paddingTop={4} + spacing={4} flex={1} + css={` + > :not(:first-child) { + border-top: 1px solid ${getValueForMenu('borderColor')}; + } + `} > - {filteredManageMenu.length > 0 && ( - - )} - - + + 0 ? 'space-between' : 'flex-end' + } + flex={1} + > + {filteredManageMenu.length > 0 && ( + + )} + - - { - setIsNewCreateEnabled((prev) => !prev); - }} - /> - - {!isSmallView && ( - - - - )} - - - + + { + setIsNewCreateEnabled((prev) => !prev); + }} + /> + + {!isSmallView && ( + + + + )} + + + + - , - setIsJobLoggerVisible((oldState) => !oldState)} - onStatusChange={setJobLoggerState} - />, - , - ]; + setIsJobLoggerVisible((oldState) => !oldState)} + onStatusChange={setJobLoggerState} + /> + + + ); }; export { Sidebar }; From c04d9e83ad3b11760e568d5a0f3c7f282852f021 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 25 Aug 2023 13:27:40 +0200 Subject: [PATCH 09/17] Fix some TS errors --- src/pages/dashboard/index.page.tsx | 7 ++++--- src/pages/events/[eventId]/duplicate/index.page.tsx | 2 +- src/pages/events/[eventId]/edit/index.page.tsx | 6 +++--- src/pages/manage/movies/[eventId]/edit.page.tsx | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/pages/dashboard/index.page.tsx b/src/pages/dashboard/index.page.tsx index e09defce8..438d0db55 100644 --- a/src/pages/dashboard/index.page.tsx +++ b/src/pages/dashboard/index.page.tsx @@ -733,10 +733,11 @@ const getServerSideProps = getApplicationServerSideProps( await Promise.all( Object.entries(UseGetItemsByCreatorMap).map(([key, hook]) => { const page = - query.tab === key ? (query.page ? parseInt(query.page) : 1) : 1; + query.tab === key ? parseInt((query.page as string) ?? '1') : 1; - const sortingField = query?.sort?.split('_')[0] ?? SortingField.CREATED; - const sortingOrder = query?.sort?.split('_')[1] ?? SortingOrder.DESC; + const sort = (query?.sort ?? '') as string; + const sortingField = sort.split('_')[0] ?? SortingField.CREATED; + const sortingOrder = sort.split('_')[1] ?? SortingOrder.DESC; return hook({ req, diff --git a/src/pages/events/[eventId]/duplicate/index.page.tsx b/src/pages/events/[eventId]/duplicate/index.page.tsx index 4b57e5d2e..27924e3e1 100644 --- a/src/pages/events/[eventId]/duplicate/index.page.tsx +++ b/src/pages/events/[eventId]/duplicate/index.page.tsx @@ -10,7 +10,7 @@ export const getServerSideProps = getApplicationServerSideProps( const { eventId } = query; await useGetEventByIdQuery({ - id: eventId, + id: eventId as string, req, queryClient, }); diff --git a/src/pages/events/[eventId]/edit/index.page.tsx b/src/pages/events/[eventId]/edit/index.page.tsx index fbd82928f..34df25bec 100644 --- a/src/pages/events/[eventId]/edit/index.page.tsx +++ b/src/pages/events/[eventId]/edit/index.page.tsx @@ -10,11 +10,11 @@ export const getServerSideProps = getApplicationServerSideProps( async ({ req, query, queryClient, cookies }) => { const { eventId } = query; - const event = (await useGetEventByIdQuery({ - id: eventId, + await useGetEventByIdQuery({ + id: eventId as string, req, queryClient, - })) as Event; + }); return { props: { diff --git a/src/pages/manage/movies/[eventId]/edit.page.tsx b/src/pages/manage/movies/[eventId]/edit.page.tsx index fe1276cba..e6a8054d7 100644 --- a/src/pages/manage/movies/[eventId]/edit.page.tsx +++ b/src/pages/manage/movies/[eventId]/edit.page.tsx @@ -12,7 +12,7 @@ export const getServerSideProps = getApplicationServerSideProps( await useGetEventByIdQuery({ req, queryClient, - id: eventId, + id: eventId as string, }); return { From b2f3187cf9f1ffe3a74fb139346cedf71cfa01cb Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 25 Aug 2023 14:23:16 +0200 Subject: [PATCH 10/17] Return query state --- src/hooks/api/authenticated-query-v2.ts | 6 ++---- src/hooks/api/authenticated-query.ts | 7 ++++--- src/pages/dashboard/index.page.tsx | 2 +- src/pages/test.page.tsx | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/hooks/api/authenticated-query-v2.ts b/src/hooks/api/authenticated-query-v2.ts index 414eb440d..5f01921de 100644 --- a/src/hooks/api/authenticated-query-v2.ts +++ b/src/hooks/api/authenticated-query-v2.ts @@ -1,5 +1,5 @@ -import { NextApiRequest } from 'next'; import { useRouter } from 'next/router'; +import { GetServerSidePropsContext } from 'next/types'; import { Cookies } from 'react-cookie'; import { FetchQueryOptions, @@ -14,9 +14,7 @@ import { FetchError } from '@/utils/fetchFromApi'; import { isTokenValid } from '@/utils/isTokenValid'; import { useCookiesWithOptions } from '../useCookiesWithOptions'; -import { Headers } from './types/Headers'; import { createHeaders, useHeaders } from './useHeaders'; -import { GetServerSidePropsContext } from 'next/types'; type QueryArguments = Record; @@ -124,7 +122,7 @@ const prefetchAuthenticatedQuery = async ({ ); } catch {} - return await queryClient.getQueryData(queryKey); + return queryClient.getQueryState(queryKey); }; const useAuthenticatedQuery = ( diff --git a/src/hooks/api/authenticated-query.ts b/src/hooks/api/authenticated-query.ts index 62ce18575..f13851465 100644 --- a/src/hooks/api/authenticated-query.ts +++ b/src/hooks/api/authenticated-query.ts @@ -1,16 +1,18 @@ import { isEqual } from 'lodash'; import flatten from 'lodash/flatten'; -import type { NextApiRequest } from 'next'; import { useRouter } from 'next/router'; +import { GetServerSidePropsContext } from 'next/types'; import { useCallback } from 'react'; import { Cookies } from 'react-cookie'; import { MutationFunction, QueryClient, + useMutation, + useQueries, + useQuery, useQueryClient, UseQueryResult, } from 'react-query'; -import { useMutation, useQueries, useQuery } from 'react-query'; import { useCookiesWithOptions } from '@/hooks/useCookiesWithOptions'; import type { CalendarSummaryFormat } from '@/utils/createEmbededCalendarSummaries'; @@ -19,7 +21,6 @@ import { isErrorObject } from '@/utils/fetchFromApi'; import { isTokenValid } from '@/utils/isTokenValid'; import { createHeaders, useHeaders } from './useHeaders'; -import { GetServerSidePropsContext } from 'next/types'; type ServerSideQueryOptions = { req?: GetServerSidePropsContext['req']; diff --git a/src/pages/dashboard/index.page.tsx b/src/pages/dashboard/index.page.tsx index 438d0db55..85012b67a 100644 --- a/src/pages/dashboard/index.page.tsx +++ b/src/pages/dashboard/index.page.tsx @@ -725,7 +725,7 @@ const Dashboard = (): any => { const getServerSideProps = getApplicationServerSideProps( async ({ req, query, cookies: rawCookies, queryClient }) => { - const user = await useGetUserQueryServerSide({ + const { data: user } = await useGetUserQueryServerSide({ req, queryClient, }); diff --git a/src/pages/test.page.tsx b/src/pages/test.page.tsx index 6bb08aca3..5bb9f7989 100644 --- a/src/pages/test.page.tsx +++ b/src/pages/test.page.tsx @@ -47,7 +47,7 @@ const Test = () => { export const getServerSideProps = getApplicationServerSideProps( async ({ req, cookies, queryClient }) => { - const eventOnServer = await prefetchAuthenticatedQuery({ + const { data: eventOnServer } = await prefetchAuthenticatedQuery({ req, queryClient, queryKey: ['events'], From 38f474ae73095b7747339dfa76e7aa3534f80f45 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 25 Aug 2023 15:02:57 +0200 Subject: [PATCH 11/17] Try to revert some changes? --- src/pages/dashboard/index.page.tsx | 7 ++- src/utils/getApplicationServerSideProps.ts | 52 +++++++--------------- 2 files changed, 18 insertions(+), 41 deletions(-) diff --git a/src/pages/dashboard/index.page.tsx b/src/pages/dashboard/index.page.tsx index 85012b67a..f0cb60ad9 100644 --- a/src/pages/dashboard/index.page.tsx +++ b/src/pages/dashboard/index.page.tsx @@ -733,11 +733,10 @@ const getServerSideProps = getApplicationServerSideProps( await Promise.all( Object.entries(UseGetItemsByCreatorMap).map(([key, hook]) => { const page = - query.tab === key ? parseInt((query.page as string) ?? '1') : 1; + query.tab === key ? (query.page ? parseInt(query.page) : 1) : 1; - const sort = (query?.sort ?? '') as string; - const sortingField = sort.split('_')[0] ?? SortingField.CREATED; - const sortingOrder = sort.split('_')[1] ?? SortingOrder.DESC; + const sortingField = query?.sort?.split('_')[0] ?? SortingField.CREATED; + const sortingOrder = query?.sort?.split('_')[1] ?? SortingOrder.DESC; return hook({ req, diff --git a/src/utils/getApplicationServerSideProps.ts b/src/utils/getApplicationServerSideProps.ts index 3de3b2cea..da1bd212e 100644 --- a/src/utils/getApplicationServerSideProps.ts +++ b/src/utils/getApplicationServerSideProps.ts @@ -1,16 +1,17 @@ import * as Sentry from '@sentry/nextjs'; import getConfig from 'next/config'; -import { GetServerSidePropsContext } from 'next/types'; import absoluteUrl from 'next-absolute-url'; import { QueryClient } from 'react-query'; import { generatePath, matchPath } from 'react-router'; import UniversalCookies from 'universal-cookie'; -import { useGetUserQueryServerSide } from '@/hooks/api/user'; +import { useGetUserQuery, useGetUserQueryServerSide } from '@/hooks/api/user'; +import { defaultCookieOptions } from '@/hooks/useCookiesWithOptions'; import { isFeatureFlagEnabledInCookies } from '@/hooks/useFeatureFlag'; import { getRedirects } from '../redirects'; import { FetchError } from './fetchFromApi'; +import { isTokenValid } from './isTokenValid'; class Cookies extends UniversalCookies { toString() { @@ -18,7 +19,7 @@ class Cookies extends UniversalCookies { return cookieEntries.reduce((previous, [key, value], currentIndex) => { const end = currentIndex !== cookieEntries.length - 1 ? '; ' : ''; - const pair = `${key}=${encodeURIComponent(value as string)}${end}`; + const pair = `${key}=${encodeURIComponent(value)}${end}`; return `${previous}${pair}`; }, ''); } @@ -60,13 +61,7 @@ const getRedirect = (originalPath, environment, cookies) => { .find((match) => !!match); }; -const redirectToLogin = ({ - cookies, - req, - resolvedUrl, -}: Pick & { - cookies: Cookies; -}) => { +const redirectToLogin = (cookies, req, resolvedUrl) => { Sentry.setUser(null); cookies.remove('token'); @@ -81,31 +76,22 @@ const redirectToLogin = ({ }; }; -type ExtendedGetServerSidePropsContext = GetServerSidePropsContext & { - cookies: string; - queryClient: QueryClient; -}; - const getApplicationServerSideProps = - (callbackFn?: (context: ExtendedGetServerSidePropsContext) => any) => - async ({ - req, - query, - resolvedUrl, - ...context - }: GetServerSidePropsContext) => { + (callbackFn) => + async ({ req, query, resolvedUrl }) => { const { publicRuntimeConfig } = getConfig(); if (publicRuntimeConfig.environment === 'development') { - process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; } - const cookies = new Cookies(req.cookies); + const rawCookies = req?.headers?.cookie ?? req.cookies ?? ''; + + const cookies = new Cookies(rawCookies); req.headers.cookie = cookies.toString(); - const params = (query.params as string[]) ?? []; - const isDynamicUrl = Object.keys(params).length > 0; - const path = isDynamicUrl ? `/${params.join('/')}` : resolvedUrl; + const isDynamicUrl = !!query.params; + const path = isDynamicUrl ? `/${query.params.join('/')}` : resolvedUrl; const redirect = getRedirect( path, @@ -116,9 +102,7 @@ const getApplicationServerSideProps = if (redirect) { // Don't include the `params` in the redirect URL's query. delete query.params; - const queryParameters = new URLSearchParams( - query as Record, - ); + const queryParameters = new URLSearchParams(query); // Return the redirect as-is if there are no additional query parameters // to append. @@ -140,11 +124,7 @@ const getApplicationServerSideProps = await useGetUserQueryServerSide({ req, queryClient }); } catch (error) { if (error instanceof FetchError) { - return redirectToLogin({ - cookies, - req, - resolvedUrl, - }); + return redirectToLogin(cookies, req, resolvedUrl); } } @@ -153,8 +133,6 @@ const getApplicationServerSideProps = if (!callbackFn) return { props: { cookies: cookies.toString() } }; return await callbackFn({ - ...context, - resolvedUrl, req, query, queryClient, From e21e07f89954b31786d086a1b64746c4b0397dad Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 25 Aug 2023 15:21:33 +0200 Subject: [PATCH 12/17] Try to make authentication work properly --- src/hooks/api/authenticated-query-v2.ts | 9 +--- src/layouts/index.tsx | 2 +- src/pages/dashboard/index.page.tsx | 9 ++-- src/pages/test.page.tsx | 2 +- src/utils/getApplicationServerSideProps.ts | 52 +++++++++++++++------- 5 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/hooks/api/authenticated-query-v2.ts b/src/hooks/api/authenticated-query-v2.ts index 5f01921de..7df7c7b39 100644 --- a/src/hooks/api/authenticated-query-v2.ts +++ b/src/hooks/api/authenticated-query-v2.ts @@ -115,14 +115,7 @@ const prefetchAuthenticatedQuery = async ({ headers, }); - try { - await queryClient.prefetchQuery( - queryKey, - queryFn, - ); - } catch {} - - return queryClient.getQueryState(queryKey); + return queryClient.fetchQuery(queryKey, queryFn); }; const useAuthenticatedQuery = ( diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 53bf05b31..18a08336b 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -34,7 +34,7 @@ const useHandleAuthentication = () => { useEffect(() => { if (!getUserQuery?.data) return; - Sentry.setUser({ id: getUserQuery.data.id }); + Sentry.setUser({ id: getUserQuery.data.sub }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [getUserQuery?.data]); diff --git a/src/pages/dashboard/index.page.tsx b/src/pages/dashboard/index.page.tsx index f0cb60ad9..74ba34024 100644 --- a/src/pages/dashboard/index.page.tsx +++ b/src/pages/dashboard/index.page.tsx @@ -725,7 +725,7 @@ const Dashboard = (): any => { const getServerSideProps = getApplicationServerSideProps( async ({ req, query, cookies: rawCookies, queryClient }) => { - const { data: user } = await useGetUserQueryServerSide({ + const user = await useGetUserQueryServerSide({ req, queryClient, }); @@ -733,10 +733,11 @@ const getServerSideProps = getApplicationServerSideProps( await Promise.all( Object.entries(UseGetItemsByCreatorMap).map(([key, hook]) => { const page = - query.tab === key ? (query.page ? parseInt(query.page) : 1) : 1; + query.tab === key ? parseInt((query.page as string) ?? '1') : 1; - const sortingField = query?.sort?.split('_')[0] ?? SortingField.CREATED; - const sortingOrder = query?.sort?.split('_')[1] ?? SortingOrder.DESC; + const sort = query?.sort as string | undefined; + const sortingField = sort?.split('_')[0] ?? SortingField.CREATED; + const sortingOrder = sort?.split('_')[1] ?? SortingOrder.DESC; return hook({ req, diff --git a/src/pages/test.page.tsx b/src/pages/test.page.tsx index 5bb9f7989..6bb08aca3 100644 --- a/src/pages/test.page.tsx +++ b/src/pages/test.page.tsx @@ -47,7 +47,7 @@ const Test = () => { export const getServerSideProps = getApplicationServerSideProps( async ({ req, cookies, queryClient }) => { - const { data: eventOnServer } = await prefetchAuthenticatedQuery({ + const eventOnServer = await prefetchAuthenticatedQuery({ req, queryClient, queryKey: ['events'], diff --git a/src/utils/getApplicationServerSideProps.ts b/src/utils/getApplicationServerSideProps.ts index da1bd212e..3de3b2cea 100644 --- a/src/utils/getApplicationServerSideProps.ts +++ b/src/utils/getApplicationServerSideProps.ts @@ -1,17 +1,16 @@ import * as Sentry from '@sentry/nextjs'; import getConfig from 'next/config'; +import { GetServerSidePropsContext } from 'next/types'; import absoluteUrl from 'next-absolute-url'; import { QueryClient } from 'react-query'; import { generatePath, matchPath } from 'react-router'; import UniversalCookies from 'universal-cookie'; -import { useGetUserQuery, useGetUserQueryServerSide } from '@/hooks/api/user'; -import { defaultCookieOptions } from '@/hooks/useCookiesWithOptions'; +import { useGetUserQueryServerSide } from '@/hooks/api/user'; import { isFeatureFlagEnabledInCookies } from '@/hooks/useFeatureFlag'; import { getRedirects } from '../redirects'; import { FetchError } from './fetchFromApi'; -import { isTokenValid } from './isTokenValid'; class Cookies extends UniversalCookies { toString() { @@ -19,7 +18,7 @@ class Cookies extends UniversalCookies { return cookieEntries.reduce((previous, [key, value], currentIndex) => { const end = currentIndex !== cookieEntries.length - 1 ? '; ' : ''; - const pair = `${key}=${encodeURIComponent(value)}${end}`; + const pair = `${key}=${encodeURIComponent(value as string)}${end}`; return `${previous}${pair}`; }, ''); } @@ -61,7 +60,13 @@ const getRedirect = (originalPath, environment, cookies) => { .find((match) => !!match); }; -const redirectToLogin = (cookies, req, resolvedUrl) => { +const redirectToLogin = ({ + cookies, + req, + resolvedUrl, +}: Pick & { + cookies: Cookies; +}) => { Sentry.setUser(null); cookies.remove('token'); @@ -76,22 +81,31 @@ const redirectToLogin = (cookies, req, resolvedUrl) => { }; }; +type ExtendedGetServerSidePropsContext = GetServerSidePropsContext & { + cookies: string; + queryClient: QueryClient; +}; + const getApplicationServerSideProps = - (callbackFn) => - async ({ req, query, resolvedUrl }) => { + (callbackFn?: (context: ExtendedGetServerSidePropsContext) => any) => + async ({ + req, + query, + resolvedUrl, + ...context + }: GetServerSidePropsContext) => { const { publicRuntimeConfig } = getConfig(); if (publicRuntimeConfig.environment === 'development') { - process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; + process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; } - const rawCookies = req?.headers?.cookie ?? req.cookies ?? ''; - - const cookies = new Cookies(rawCookies); + const cookies = new Cookies(req.cookies); req.headers.cookie = cookies.toString(); - const isDynamicUrl = !!query.params; - const path = isDynamicUrl ? `/${query.params.join('/')}` : resolvedUrl; + const params = (query.params as string[]) ?? []; + const isDynamicUrl = Object.keys(params).length > 0; + const path = isDynamicUrl ? `/${params.join('/')}` : resolvedUrl; const redirect = getRedirect( path, @@ -102,7 +116,9 @@ const getApplicationServerSideProps = if (redirect) { // Don't include the `params` in the redirect URL's query. delete query.params; - const queryParameters = new URLSearchParams(query); + const queryParameters = new URLSearchParams( + query as Record, + ); // Return the redirect as-is if there are no additional query parameters // to append. @@ -124,7 +140,11 @@ const getApplicationServerSideProps = await useGetUserQueryServerSide({ req, queryClient }); } catch (error) { if (error instanceof FetchError) { - return redirectToLogin(cookies, req, resolvedUrl); + return redirectToLogin({ + cookies, + req, + resolvedUrl, + }); } } @@ -133,6 +153,8 @@ const getApplicationServerSideProps = if (!callbackFn) return { props: { cookies: cookies.toString() } }; return await callbackFn({ + ...context, + resolvedUrl, req, query, queryClient, From 8eac43b35a19aa165fe6e56c926045e6ca81e343 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 25 Aug 2023 15:28:10 +0200 Subject: [PATCH 13/17] Fix optional feature flag property --- src/utils/getApplicationServerSideProps.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/getApplicationServerSideProps.ts b/src/utils/getApplicationServerSideProps.ts index 3de3b2cea..4fabcad37 100644 --- a/src/utils/getApplicationServerSideProps.ts +++ b/src/utils/getApplicationServerSideProps.ts @@ -26,7 +26,7 @@ class Cookies extends UniversalCookies { const getRedirect = (originalPath, environment, cookies) => { return getRedirects(environment, cookies['udb-language']) - .map(({ source, destination, permanent, featureFlag }) => { + .map(({ source, destination, permanent, featureFlag = null }) => { // Don't follow redirects that are behind a feature flag if (featureFlag && !isFeatureFlagEnabledInCookies(featureFlag, cookies)) { return false; From 32feb8f2d9ef9aa0f04e2692f1240c761db9ba29 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 25 Aug 2023 15:34:45 +0200 Subject: [PATCH 14/17] Make return type explicit --- src/redirects.tsx | 7 ++++++- src/utils/getApplicationServerSideProps.ts | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/redirects.tsx b/src/redirects.tsx index e6afc9d01..8dc975298 100644 --- a/src/redirects.tsx +++ b/src/redirects.tsx @@ -42,7 +42,12 @@ const createDashboardRedirects = (environment: Environment) => { const getRedirects = ( environment: Environment, language: Values = 'nl', -) => [ +): { + featureFlag?: 'react_create'; + permanent: boolean; + destination: string; + source: string; +}[] => [ // Only make the permanent redirects really permanent in environments other // than development, so we don't get permanent redirects on localhost which // may conflict with other projects. diff --git a/src/utils/getApplicationServerSideProps.ts b/src/utils/getApplicationServerSideProps.ts index 4fabcad37..3de3b2cea 100644 --- a/src/utils/getApplicationServerSideProps.ts +++ b/src/utils/getApplicationServerSideProps.ts @@ -26,7 +26,7 @@ class Cookies extends UniversalCookies { const getRedirect = (originalPath, environment, cookies) => { return getRedirects(environment, cookies['udb-language']) - .map(({ source, destination, permanent, featureFlag = null }) => { + .map(({ source, destination, permanent, featureFlag }) => { // Don't follow redirects that are behind a feature flag if (featureFlag && !isFeatureFlagEnabledInCookies(featureFlag, cookies)) { return false; From 343ecd129826eaf1cea6141288d3cbb5ed1d71d2 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Fri, 25 Aug 2023 15:39:26 +0200 Subject: [PATCH 15/17] Linting --- src/pages/dashboard/index.page.tsx | 6 +----- src/redirects.tsx | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pages/dashboard/index.page.tsx b/src/pages/dashboard/index.page.tsx index 74ba34024..00abdc001 100644 --- a/src/pages/dashboard/index.page.tsx +++ b/src/pages/dashboard/index.page.tsx @@ -22,11 +22,7 @@ import { useDeletePlaceByIdMutation, useGetPlacesByCreatorQuery, } from '@/hooks/api/places'; -import { - useGetUserQuery, - useGetUserQueryServerSide, - User, -} from '@/hooks/api/user'; +import { useGetUserQuery, useGetUserQueryServerSide } from '@/hooks/api/user'; import { FeatureFlags, useFeatureFlag } from '@/hooks/useFeatureFlag'; import { Footer } from '@/pages/Footer'; import type { Event } from '@/types/Event'; diff --git a/src/redirects.tsx b/src/redirects.tsx index 8dc975298..7fc5ca4dc 100644 --- a/src/redirects.tsx +++ b/src/redirects.tsx @@ -43,7 +43,7 @@ const getRedirects = ( environment: Environment, language: Values = 'nl', ): { - featureFlag?: 'react_create'; + featureFlag?: string; permanent: boolean; destination: string; source: string; From d8a21e12c0deca3a150165ff6a11d95d6bfdea64 Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Thu, 7 Sep 2023 15:50:58 +0200 Subject: [PATCH 16/17] Better handling of undefined query page --- src/pages/dashboard/index.page.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/dashboard/index.page.tsx b/src/pages/dashboard/index.page.tsx index 00abdc001..0897e3d96 100644 --- a/src/pages/dashboard/index.page.tsx +++ b/src/pages/dashboard/index.page.tsx @@ -729,7 +729,9 @@ const getServerSideProps = getApplicationServerSideProps( await Promise.all( Object.entries(UseGetItemsByCreatorMap).map(([key, hook]) => { const page = - query.tab === key ? parseInt((query.page as string) ?? '1') : 1; + query.tab === key && query.page + ? parseInt((query.page as string) ?? '1') + : 1; const sort = query?.sort as string | undefined; const sortingField = sort?.split('_')[0] ?? SortingField.CREATED; From 73936c47a1eb0314bd048943efd39feae54df3fb Mon Sep 17 00:00:00 2001 From: Emma Fabre Date: Thu, 7 Sep 2023 15:57:12 +0200 Subject: [PATCH 17/17] Correct feature flag type --- src/hooks/useFeatureFlag.ts | 2 ++ src/redirects.tsx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hooks/useFeatureFlag.ts b/src/hooks/useFeatureFlag.ts index e6721346e..55a1f0e5a 100644 --- a/src/hooks/useFeatureFlag.ts +++ b/src/hooks/useFeatureFlag.ts @@ -80,3 +80,5 @@ export { isFeatureFlagEnabledInCookies, useFeatureFlag, }; + +export type { FeatureFlagName }; diff --git a/src/redirects.tsx b/src/redirects.tsx index 7fc5ca4dc..b96a12a5a 100644 --- a/src/redirects.tsx +++ b/src/redirects.tsx @@ -1,4 +1,4 @@ -import { FeatureFlags } from './hooks/useFeatureFlag'; +import { FeatureFlagName, FeatureFlags } from './hooks/useFeatureFlag'; import type { SupportedLanguages } from './i18n'; import type { Values } from './types/Values'; @@ -43,7 +43,7 @@ const getRedirects = ( environment: Environment, language: Values = 'nl', ): { - featureFlag?: string; + featureFlag?: FeatureFlagName; permanent: boolean; destination: string; source: string;