All files / apps/web/src/pages _protected.tsx

57.14% Statements 8/14
33.33% Branches 2/6
100% Functions 2/2
57.14% Lines 8/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55                            978x 1415x             332x   842x 66x   776x 776x 776x                                                  
import React from "react";
 
import { Outlet, createFileRoute, redirect } from "@tanstack/react-router";
import { TRPCClientError } from "@trpc/client";
import { serialize } from "cookie";
 
import { ProtectedPage } from "~app/components/protected-page";
import type { TRPCError } from "~app/trpc";
import { AUTH_COOKIE } from "~app/utils/auth";
import { Spinner } from "~components/spinner";
import { getOptions } from "~web/utils/cookies";
import { captureSentryError } from "~web/utils/sentry";
import { getLoaderTrpcClient } from "~web/utils/trpc";
 
const Wrapper = () => (
	<ProtectedPage>
		<React.Suspense fallback={<Spinner size="lg" />}>
			<Outlet />
		</React.Suspense>
	</ProtectedPage>
);
 
export const Route = createFileRoute("/_protected")({
	beforeLoad: async ({ context, location }) => {
		if (!context.request) {
			return;
		}
		const trpc = getLoaderTrpcClient(context);
		try {
			await context.queryClient.fetchQuery(trpc.user.get.queryOptions());
		} catch (error) {
			if (error instanceof TRPCClientError) {
				const castedError = error as TRPCError;
				if (castedError.data?.code === "UNAUTHORIZED") {
					// oxlint-disable-next-line typescript/only-throw-error
					throw redirect({
						to: "/login",
						search: { redirect: location.href, ...location.search },
						headers: {
							"set-cookie": serialize(
								AUTH_COOKIE,
								"",
								getOptions({ expires: Temporal.Now.zonedDateTimeISO() }),
							),
						},
					});
				}
			}
			captureSentryError(error as Error);
			throw error;
		}
	},
	component: Wrapper,
});