diff --git a/src/api.ts b/src/api.ts index d0ae10e21c..06f3f93786 100644 --- a/src/api.ts +++ b/src/api.ts @@ -30,6 +30,7 @@ import { makeWordByWordTranslationsUrl, } from '@/utils/apiPaths'; import generateSignature from '@/utils/auth/signature'; +import { isStaticBuild } from '@/utils/build'; import { SearchRequest, AdvancedCopyRequest, PagesLookUpRequest } from 'types/ApiRequests'; import { TranslationsResponse, @@ -65,7 +66,6 @@ export const X_AUTH_SIGNATURE = 'x-auth-signature'; export const X_TIMESTAMP = 'x-timestamp'; export const X_INTERNAL_CLIENT = 'x-internal-client'; -const isStaticBuild = process.env.IS_BUILD_TIME === 'true'; export const fetcher = async function fetcher( input: RequestInfo, init: RequestInit = {}, diff --git a/src/pages/auth.tsx b/src/pages/auth.tsx index fd82368123..05b19cd4a6 100644 --- a/src/pages/auth.tsx +++ b/src/pages/auth.tsx @@ -12,6 +12,8 @@ interface AuthProps { error?: string; } +const LOGIN_URL = '/login'; + const Auth: React.FC = ({ error }) => { const router = useRouter(); const toast = useToast(); @@ -37,14 +39,14 @@ const Auth: React.FC = ({ error }) => { * * @param {GetServerSidePropsContext} context - The context object containing request and response information. * @param {string} token - The token used for authentication and redirection. - * @param {string} redirectUrl - The URL to redirect the user to after successful token handling. + * @param {string} destination - The URL to redirect the user to after successful token handling. * @returns {Promise>} - A promise that resolves to the server-side props result, * which includes either a redirection or an error message. */ const handleTokenRedirection = async ( context: GetServerSidePropsContext, token: string, - redirectUrl: string, + destination: string, ): Promise> => { try { const baseUrl = getBaseUrl(context); @@ -59,7 +61,7 @@ const handleTokenRedirection = async ( return { props: {}, redirect: { - destination: redirectUrl, + destination, permanent: false, }, }; @@ -128,15 +130,16 @@ const setProxyCookies = (response: Response, context: GetServerSidePropsContext) export const getServerSideProps: GetServerSideProps = async (context) => { const { r, token } = context.query; const redirectUrl = (r || '/') as string; + const destination = redirectUrl === LOGIN_URL ? '/' : redirectUrl; if (token) { - return handleTokenRedirection(context, token as string, redirectUrl); + return handleTokenRedirection(context, token as string, destination); } return { props: {}, redirect: { - destination: redirectUrl, + destination, permanent: false, }, }; diff --git a/src/utils/api.ts b/src/utils/api.ts index d5b74c1264..52a92bc0f7 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -3,6 +3,7 @@ import { decamelizeKeys } from 'humps'; import stringify from './qs-stringify'; import { getBasePath } from './url'; +import { isStaticBuild } from '@/utils/build'; import { Mushaf, MushafLines, QuranFont, QuranFontMushaf } from 'types/QuranReader'; export const ITEMS_PER_PAGE = 10; @@ -17,7 +18,6 @@ export const API_HOST = process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' ? PRODUCTION_API_HOST : STAGING_API_HOST; const { API_GATEWAY_URL } = process.env; -const isStaticBuild = process.env.IS_BUILD_TIME === 'true'; /** * Generates a url to make an api call to our backend diff --git a/src/utils/apiPaths.ts b/src/utils/apiPaths.ts index 547f73a520..39f9ffa5f0 100644 --- a/src/utils/apiPaths.ts +++ b/src/utils/apiPaths.ts @@ -1,5 +1,6 @@ import { decamelizeKeys } from 'humps'; +// eslint-disable-next-line import/no-cycle import { getDefaultWordFields, getMushafId, ITEMS_PER_PAGE, makeUrl } from './api'; import stringify from './qs-stringify'; diff --git a/src/utils/auth/api.ts b/src/utils/auth/api.ts index ea9954aa0c..a9f6b6e8a0 100644 --- a/src/utils/auth/api.ts +++ b/src/utils/auth/api.ts @@ -1,12 +1,15 @@ /* eslint-disable max-lines */ +import { NextApiRequest } from 'next'; import { configureRefreshFetch } from 'refresh-fetch'; import { getTimezone } from '../datetime'; import { prepareGenerateMediaFileRequestData } from '../media/utils'; +import generateSignature from './signature'; import BookmarkByCollectionIdQueryParams from './types/BookmarkByCollectionIdQueryParams'; import GetAllNotesQueryParams from './types/Note/GetAllNotesQueryParams'; +import { fetcher, X_AUTH_SIGNATURE, X_INTERNAL_CLIENT, X_TIMESTAMP } from '@/api'; import { FilterActivityDaysParams, QuranActivityDay, @@ -72,7 +75,7 @@ import { makeGetMediaFileProgressUrl, makeGetMonthlyMediaFilesCountUrl, } from '@/utils/auth/apiPaths'; -import { fetcher } from 'src/api'; +import { isStaticBuild } from '@/utils/build'; import CompleteAnnouncementRequest from 'types/auth/CompleteAnnouncementRequest'; import { GetBookmarkCollectionsIdResponse } from 'types/auth/GetBookmarksByCollectionId'; import PreferenceGroup from 'types/auth/PreferenceGroup'; @@ -88,7 +91,6 @@ import { Collection } from 'types/Collection'; import CompleteSignupRequest from 'types/CompleteSignupRequest'; type RequestData = Record; - const IGNORE_ERRORS = [ MediaRenderError.MediaVersesRangeLimitExceeded, MediaRenderError.MediaFilesPerUserLimitExceeded, @@ -445,6 +447,23 @@ export const withCredentialsFetcher = async ( init?: RequestInit, ): Promise => { try { + let additionalHeaders = {}; + if (isStaticBuild) { + const req: NextApiRequest = { + url: typeof input === 'string' ? input : input.url, + method: init.method || 'GET', + body: init.body, + headers: init.headers, + query: {}, + } as NextApiRequest; + + const { signature, timestamp } = generateSignature(req, req.url); + additionalHeaders = { + [X_AUTH_SIGNATURE]: signature, + [X_TIMESTAMP]: timestamp, + [X_INTERNAL_CLIENT]: process.env.INTERNAL_CLIENT_ID, + }; + } const data = await fetcher(input, { ...init, credentials: 'include', @@ -452,6 +471,7 @@ export const withCredentialsFetcher = async ( ...init?.headers, // eslint-disable-next-line @typescript-eslint/naming-convention 'x-timezone': getTimezone(), + ...additionalHeaders, }, }); return data; diff --git a/src/utils/build.ts b/src/utils/build.ts new file mode 100644 index 0000000000..6e7ef2dc9c --- /dev/null +++ b/src/utils/build.ts @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/prefer-default-export +export const isStaticBuild = process.env.IS_BUILD_TIME === 'true'; diff --git a/src/utils/url.ts b/src/utils/url.ts index eca2f7c570..ac266250fd 100644 --- a/src/utils/url.ts +++ b/src/utils/url.ts @@ -1,3 +1,5 @@ +import { isStaticBuild } from '@/utils/build'; + const getLocalePostfix = (locale: string) => (locale !== 'en' ? `/${locale}` : ''); export const getCurrentPath = () => { @@ -43,7 +45,7 @@ export const navigateToExternalUrl = (url: string) => { * @returns {string} */ export const getBasePath = (): string => - `${process.env.NEXT_PUBLIC_VERCEL_ENV === 'development' ? 'http' : 'https'}://${ + `${process.env.NEXT_PUBLIC_VERCEL_ENV === 'development' ? 'https' : 'https'}://${ process.env.NEXT_PUBLIC_VERCEL_URL }`; @@ -54,6 +56,9 @@ export const getBasePath = (): string => * @returns {string} */ export const getAuthApiPath = (path: string): string => { - const BASE_PATH = getBasePath(); - return `${BASE_PATH}/api/proxy/auth/${path}`; + const PROXY_PATH = '/api/proxy/auth/'; + const BASE_PATH = isStaticBuild + ? `${process.env.API_GATEWAY_URL}/auth/` + : `${getBasePath()}${PROXY_PATH}`; + return `${BASE_PATH}${path}`; };