Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ENV value not being available in session on first hydrate #1304

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 7 additions & 20 deletions apps/cyberstorm-remix/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
redirect,
useLocation,
useRouteError,
useRouteLoaderData,
// useRouteLoaderData,
} from "@remix-run/react";
// import { LinksFunction } from "@remix-run/react/dist/routeModules";
import { Provider as RadixTooltip } from "@radix-ui/react-tooltip";
Expand Down Expand Up @@ -82,8 +82,6 @@ export const meta: MetaFunction = () => {
};

export async function loader() {
// const dapper = await getDapper();

return {
envStuff: {
ENV: getPublicEnvVariables([
Expand All @@ -102,9 +100,11 @@ export function shouldRevalidate() {
const adContainerIds = ["right-column-1", "right-column-2", "right-column-3"];

export function Layout({ children }: { children: React.ReactNode }) {
const data = useRouteLoaderData<typeof loader>("root");
// const error = useRouteError();
// console.log(error);
// const data = useRouteLoaderData<typeof loader>("root");

const domain =
getPublicEnvVariables(["PUBLIC_SITE_URL"]).PUBLIC_SITE_URL ??
"https://thunderstore.io";

const location = useLocation();
const shouldShowAds = location.pathname.startsWith("/teams")
Expand Down Expand Up @@ -147,23 +147,10 @@ export function Layout({ children }: { children: React.ReactNode }) {
<Links />
</head>
<body>
<SessionProvider
apiHost={
data?.envStuff.ENV.PUBLIC_API_URL ?? "APIHOST_MISSING_IN_ENV"
}
>
<SessionProvider apiHost={domain ?? "APIHOST_MISSING_IN_ENV"}>
<LinkingProvider value={LinkLibrary}>
<Toast.Provider toastDuration={10000}>
<RadixTooltip delayDuration={80}>
{data ? (
<script
dangerouslySetInnerHTML={{
__html: `window.ENV = ${JSON.stringify(
data.envStuff.ENV
)}`,
}}
/>
) : null}
<div className="nimbus-root">
<NavigationWrapper />
<section className="nimbus-root__content">
Expand Down
39 changes: 36 additions & 3 deletions apps/cyberstorm-remix/cyberstorm/security/publicEnvVariables.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
export const isRecord = (obj: unknown): obj is Record<string, unknown> =>
obj instanceof Object;

type rootLoaderType = {
root: {
envStuff: {
ENV: {
PUBLIC_API_URL?: string;
PUBLIC_CLIENT_SENTRY_DSN?: string;
PUBLIC_SITE_URL?: string;
};
};
};
};

export const isRootLoaderData = (obj: unknown): obj is rootLoaderType =>
isRecord(obj) &&
isRecord(obj.root) &&
isRecord(obj.root.envStuff) &&
isRecord(obj.root.envStuff.ENV) &&
(typeof obj.root.envStuff.ENV.PUBLIC_API_URL === "string" ||
typeof obj.root.envStuff.ENV.PUBLIC_API_URL === "undefined") &&
(typeof obj.root.envStuff.ENV.PUBLIC_CLIENT_SENTRY_DSN === "string" ||
typeof obj.root.envStuff.ENV.PUBLIC_CLIENT_SENTRY_DSN === "undefined") &&
(typeof obj.root.envStuff.ENV.PUBLIC_SITE_URL === "string" ||
typeof obj.root.envStuff.ENV.PUBLIC_SITE_URL === "undefined");

export type publicEnvVariablesKeys =
| "SITE_URL"
| "API_URL"
Expand All @@ -19,10 +46,16 @@ export function getPublicEnvVariables(
returnedVars[envVar] = process.env[envVar];
}
});
} else if (typeof window !== "undefined" && window.ENV) {
} else if (
typeof window !== "undefined" &&
typeof window.__remixContext.state.loaderData !== "undefined" &&
isRootLoaderData(window.__remixContext.state.loaderData)
) {
const availableENV =
window.__remixContext.state.loaderData.root.envStuff.ENV;
vars.forEach((envVar) => {
if (envVar.startsWith("PUBLIC_") && envVar in window.ENV) {
returnedVars[envVar] = window.ENV[envVar];
if (envVar.startsWith("PUBLIC_") && envVar in availableENV) {
returnedVars[envVar] = availableENV[envVar];
}
});
}
Expand Down
37 changes: 18 additions & 19 deletions packages/ts-api-react/src/SessionContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
PropsWithChildren,
// SetStateAction,
useContext,
useEffect,
// useState,
} from "react";

Expand All @@ -25,7 +24,7 @@ interface ContextInterface {
/** Remove session cookies. */
clearCookies: () => void;
/** Get RequestConfig for Dapper usage */
getConfig: () => RequestConfig;
getConfig: (domain?: string) => RequestConfig;
/** Check if session is valid and try to repair if not */
sessionValid: () => boolean;
/** apiHost of the session */
Expand Down Expand Up @@ -66,21 +65,6 @@ interface Props extends PropsWithChildren {
export function SessionProvider(props: Props) {
const _storage = new StorageManager("Session");

useEffect(() => {
const sessionidCookie = getCookie("sessionid");

if (sessionidCookie) {
setSession({
sessionId: sessionidCookie,
username: "",
apiHost: props.apiHost,
});
} else {
_storage.setValue(API_HOST_KEY, props.apiHost);
sessionValid();
}
}, []);

const setSession = (sessionData: SessionData) => {
_storage.setValue(API_HOST_KEY, sessionData.apiHost);
_storage.setValue(ID_KEY, sessionData.sessionId);
Expand All @@ -97,12 +81,12 @@ export function SessionProvider(props: Props) {
deleteCookie("sessionid");
};

const getConfig = (): RequestConfig => {
const getConfig = (domain?: string): RequestConfig => {
const apiHost = _storage.safeGetValue(API_HOST_KEY);
const sessionId = _storage.safeGetValue(ID_KEY);
return {
// THIS IS NOT KOSHER
apiHost: apiHost ?? "",
apiHost: apiHost ? apiHost : domain ? domain : "",
sessionId: sessionId ?? "",
};
};
Expand Down Expand Up @@ -171,6 +155,21 @@ export function SessionProvider(props: Props) {
}
};

if (typeof window !== "undefined") {
const sessionidCookie = getCookie("sessionid");

if (sessionidCookie) {
setSession({
sessionId: sessionidCookie,
username: "",
apiHost: props.apiHost,
});
} else {
_storage.setValue(API_HOST_KEY, props.apiHost);
sessionValid();
}
}

const value = {
clearSession,
clearCookies,
Expand Down
Loading