Skip to content

Commit

Permalink
Display errors correctly on Unauthenticated-Status
Browse files Browse the repository at this point in the history
  • Loading branch information
fraxachun committed Jan 26, 2024
1 parent 8e86516 commit f2307f0
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ export const createErrorDialogApolloLink = () => {
let title: React.ReactNode | undefined;
let userMessage: React.ReactNode | undefined;
let httpStatus: string | undefined;
let isUnauthenticated = false;

if (graphQLErrors) {
error = graphQLErrors.map(({ message }) => message);
errorType = "graphql";
title = <FormattedMessage id="comet.errorDialog.graphQLErrors.title" defaultMessage="Server error" />;
isUnauthenticated = graphQLErrors.some(
(e) => e.extensions?.exception?.status === StatusCodes.UNAUTHORIZED || e.extensions?.code === "UNAUTHENTICATED",
);
}

if (networkError) {
Expand All @@ -41,23 +45,24 @@ export const createErrorDialogApolloLink = () => {
if (isServerError(networkError)) {
const { statusCode } = networkError;
httpStatus = `${statusCode} ${getReasonPhrase(statusCode)}`;

if (statusCode === StatusCodes.UNAUTHORIZED) {
title = <FormattedMessage id="comet.errorDialog.sessionExpired.title" defaultMessage="Session expired" />;
userMessage = (
<>
<Typography gutterBottom>
<FormattedMessage id="comet.errorDialog.sessionExpired.message" defaultMessage="Your login-session has expired." />
</Typography>
<Button href="/" color="info" variant="outlined">
<FormattedMessage id="comet.errorDialog.sessionExpired.button" defaultMessage="Re-login" />
</Button>
</>
);
}
isUnauthenticated = statusCode === StatusCodes.UNAUTHORIZED;
}
}

if (!isUnauthenticated) {
title = <FormattedMessage id="comet.errorDialog.sessionExpired.title" defaultMessage="Session expired" />;
userMessage = (
<>
<Typography gutterBottom>
<FormattedMessage id="comet.errorDialog.sessionExpired.message" defaultMessage="Your login-session has expired." />
</Typography>
<Button href="/" color="info" variant="outlined">
<FormattedMessage id="comet.errorDialog.sessionExpired.button" defaultMessage="Re-login" />
</Button>
</>
);
}

errorDialogVar({
title,
error: error ?? "Unknown error",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { gql, useQuery } from "@apollo/client";
import { Loading } from "@comet/admin";
import { Button, Typography } from "@mui/material";
import React from "react";

import { ContentScopeInterface } from "../../contentScope/Provider";
Expand Down Expand Up @@ -34,7 +35,25 @@ export const CurrentUserProvider: React.FC<{
}
`);

if (error) throw error.message;
// As this Provider is very high up in the tree, don't rely on ErrorBoundary or a configured intl-Provider here
if (error) {
const isUnauthenticated = error.graphQLErrors.some(
(e) => e.extensions?.exception?.status === 401 || e.extensions?.code === "UNAUTHENTICATED",
);
return (
<>
<Typography gutterBottom>{isUnauthenticated ? "Your access-token is invalid. Re-login might help." : error.message}</Typography>
{isUnauthenticated && (
<Button href="/" color="info" variant="outlined">
{
// eslint-disable-next-line @calm/react-intl/missing-formatted-message
}
Re-Login
</Button>
)}
</>
);
}

if (!data) return <Loading behavior="fillPageHeight" />;

Expand Down
6 changes: 3 additions & 3 deletions packages/api/cms-api/src/auth/guards/comet.guard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CanActivate, ExecutionContext, HttpException, Injectable, mixin } from "@nestjs/common";
import { CanActivate, ExecutionContext, Injectable, mixin, UnauthorizedException } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { GqlExecutionContext } from "@nestjs/graphql";
import { AuthGuard, IAuthGuard, Type } from "@nestjs/passport";
Expand All @@ -19,14 +19,14 @@ export function createCometAuthGuard(type?: string | string[]): Type<IAuthGuard>
}

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
handleRequest<CurrentUserInterface>(err: unknown, user: any): CurrentUserInterface {
handleRequest<CurrentUserInterface>(err: unknown, user: any, info: any): CurrentUserInterface {
if (err) {
throw err;
}
if (user) {
return user;
}
throw new HttpException("UserNotAuthenticated", 200);
throw new UnauthorizedException(info[0]?.message);
}

async canActivate(context: ExecutionContext): Promise<boolean> {
Expand Down

0 comments on commit f2307f0

Please sign in to comment.