Skip to content

Commit

Permalink
fix: unauthorised error on dashboard (#647)
Browse files Browse the repository at this point in the history
  • Loading branch information
nunocaseiro authored Nov 30, 2022
1 parent 0ccb518 commit 9a2d814
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 89 deletions.
18 changes: 9 additions & 9 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"fast-json-patch": "^3.1.1",
"joi": "^17.6.0",
"next": "^12.1.4",
"next-auth": "^4.12.0",
"next-auth": "^4.17.0",
"react": "^17.0.2",
"react-calendar": "^3.7.0",
"react-dom": "^17.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type CardBodyProps = {
const CardBody = React.memo<CardBodyProps>(({ userId, team }) => {
const { data: session } = useSession();

const isSAdmin = session?.isSAdmin;
const isSAdmin = session?.user.isSAdmin;

const { _id: id, users } = team;

Expand Down
84 changes: 40 additions & 44 deletions frontend/src/pages/api/auth/[...nextauth].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import CredentialsProvider from 'next-auth/providers/credentials';

import { createOrLoginUserAzure, login, refreshAccessToken } from '@/api/authService';
import { Token } from '@/types/token';
import { LoginUser, User } from '@/types/user/user';
import { LoginUser } from '@/types/user/user';
import {
CLIENT_ID,
CLIENT_SECRET,
Expand All @@ -17,13 +17,12 @@ import {
} from '@/utils/constants';
import { DASHBOARD_ROUTE, ERROR_500_PAGE, START_PAGE_ROUTE } from '@/utils/routes';

async function getNewAccessToken(prevToken: JWT) {
async function getNewAccessToken(prevToken: JWT): Promise<JWT> {
try {
const data: Token = await refreshAccessToken(prevToken.refreshToken);
const data: Token = await refreshAccessToken(prevToken.user.refreshToken.token);
return {
...prevToken,
accessToken: data.token,
accessTokenExpires: Date.now() + +data.expiresIn * 1000,
accessToken: { token: data.token, expiresIn: String(Date.now() + +data.expiresIn * 1000) },
error: '',
};
} catch (error) {
Expand All @@ -49,21 +48,20 @@ export default NextAuth({
email: credentials?.email,
password: credentials?.password,
};
const data: User = await login(loginUser);
const data = await login(loginUser);
const { firstName, lastName, isSAdmin, accessToken, refreshToken, id } = data || {};
if (!id || !accessToken || !refreshToken) return null;

if (data) {
const token = {
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
id: data.id,
accessToken: data.accessToken?.token,
refreshToken: data.refreshToken?.token,
isSAdmin: data.isSAdmin,
};
return token;
}
return null;
const token = {
firstName,
lastName,
isSAdmin,
accessToken,
refreshToken,
id,
strategy: 'local',
};
return token;
},
}),
],
Expand All @@ -77,7 +75,7 @@ export default NextAuth({
},
callbacks: {
async signIn({ account, user }) {
if (account.provider === 'azure-ad') {
if (account && account.provider === 'azure-ad') {
const { access_token: azureAccessToken } = account;

const data = await createOrLoginUserAzure(azureAccessToken ?? '');
Expand All @@ -86,9 +84,8 @@ export default NextAuth({
const { firstName, lastName, accessToken, refreshToken, email, id, isSAdmin } = data;
user.firstName = firstName;
user.lastName = lastName;
user.accessToken = accessToken.token;
user.accessTokenExpiresIn = accessToken.expiresIn;
user.refreshToken = refreshToken.token;
user.accessToken = accessToken;
user.refreshToken = refreshToken;
user.email = email;
user.strategy = 'azure';
user.id = id;
Expand All @@ -99,37 +96,36 @@ export default NextAuth({
},
async jwt({ token, user, account }) {
if (account && user) {
return {
accessToken: user.accessToken,
accessTokenExpires: Date.now() + +user.accessTokenExpiresIn * 1000,
refreshToken: user.refreshToken,
id: user.id,
firstName: user.firstName,
lastName: user.lastName,
email: token.email,
const jwt: JWT = {
user: {
accessToken: {
token: user.accessToken.token,
expiresIn: String(Date.now() + +user.accessToken.expiresIn * 1000),
},
id: user.id,
firstName: user.firstName,
lastName: user.lastName,
email: user.email ?? '',
isSAdmin: user.isSAdmin,
refreshToken: user.refreshToken,
},
strategy: user.strategy ?? 'local',
error: '',
isSAdmin: user.isSAdmin,
};

return jwt;
}
if (Date.now() < token.accessTokenExpires - 5000) {

if (Date.now() < +token.user.accessToken.expiresIn - 5000) {
return token;
}

return getNewAccessToken(token);
},
async session({ session, token }) {
const newSession: Session = { ...session };
let newSession: Session = { ...session };
if (token) {
newSession.user.firstName = token.firstName;
newSession.user.lastName = token.lastName;
newSession.accessToken = token.accessToken;
newSession.refreshToken = token.refreshToken;
newSession.user.email = token.email;
newSession.user.id = token.id;
newSession.error = token.error;
newSession.expires = token.accessTokenExpires;
newSession.strategy = token.strategy;
newSession.isSAdmin = token.isSAdmin;
newSession = { ...token, expires: token.user.accessToken.expiresIn };
}
return newSession;
},
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/boards/[boardId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const Board: NextPage<Props> = ({ boardId, mainBoardId }) => {
// Show board settings button if current user is allowed to edit
const isResponsibleInSubBoard = isSubBoard && isResponsible;
const hasAdminRole =
isStakeholderOrAdmin || session?.isSAdmin || isOwner || isResponsibleInSubBoard;
isStakeholderOrAdmin || session?.user.isSAdmin || isOwner || isResponsibleInSubBoard;

// Show Alert message if any sub-board wasn't merged
const showMessageHaveSubBoardsMerged =
Expand Down Expand Up @@ -168,7 +168,7 @@ const Board: NextPage<Props> = ({ boardId, mainBoardId }) => {
isOpen={isOpen}
isOwner={isOwner}
isResponsible={isResponsible}
isSAdmin={session?.isSAdmin}
isSAdmin={session?.user.isSAdmin}
isStakeholderOrAdmin={isStakeholderOrAdmin}
setIsOpen={setIsOpen}
socketId={socketId}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/boards/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const Boards = () => {
<Flex direction="column">
<Suspense fallback={<LoadingPage />}>
<QueryError>
<MyBoards isSuperAdmin={session.isSAdmin} userId={session.user.id} />
<MyBoards isSuperAdmin={session.user.isSAdmin} userId={session.user.id} />
</QueryError>
</Suspense>
</Flex>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/boards/new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const NewBoard: NextPage = () => {
(teamUser) =>
teamUser.user._id === session?.user.id &&
[TeamUserRoles.ADMIN, TeamUserRoles.STAKEHOLDER].includes(teamUser.role),
) || session?.isSAdmin
) || session?.user.isSAdmin
: false;
if (!isAdminOrStakeHolder && !haveError) {
setHaveError(!isAdminOrStakeHolder);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/dashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const getServerSideProps: GetServerSideProps = requireAuthentication(
await queryClient.prefetchInfiniteQuery('boards/dashboard', ({ pageParam = 0 }) =>
getDashboardBoardsRequest(pageParam, context),
);
await queryClient.prefetchQuery('team', () => getTeamsOfUser);
await queryClient.prefetchQuery('team', () => getTeamsOfUser(context));

return {
props: {
Expand Down
32 changes: 16 additions & 16 deletions frontend/src/types/next-auth.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { DefaultSession } from 'next-auth';
import { Token } from './token';

declare module 'next-auth' {
interface Session {
Expand All @@ -8,19 +9,17 @@ declare module 'next-auth' {
firstName: string;
lastName: string;
email: string;
isSAdmin: boolean;
accessToken: Token;
refreshToken?: Token;
} & DefaultSession['user'];
accessToken: string;
refreshToken?: string;
expires: number;
strategy: string;
isSAdmin: boolean;
error: string;
}

interface User {
accessToken: string;
accessTokenExpiresIn: string;
refreshToken: string;
refreshTokenExpiresIn: string;
accessToken: Token;
refreshToken: Token;
strategy: string;
id: string;
firstName: string;
Expand All @@ -31,15 +30,16 @@ declare module 'next-auth' {

declare module 'next-auth/jwt' {
interface JWT {
accessToken: string;
refreshToken: string;
firstName: string;
lastName: string;
email: string;
id: string;
user: {
accessToken: Token;
refreshToken: Token;
firstName: string;
lastName: string;
email: string;
id: string;
isSAdmin: boolean;
};
error: string;
accessTokenExpires: number;
strategy: string;
isSAdmin: boolean;
}
}
8 changes: 0 additions & 8 deletions frontend/src/types/token.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
export interface AccessToken {
[accessToken: string]: Token;
}

export interface RefreshToken {
[refreshToken: string]: Token;
}

export interface Token {
token: string;
expiresIn: string;
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/types/user/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { UseMutationResult } from 'react-query/types/react/types';
import { AxiosError } from 'axios';

import { Nullable } from '../common';
import { AccessToken, RefreshToken } from '../token';
import { Token } from '../token';

export interface User {
id?: string;
Expand All @@ -12,8 +12,8 @@ export interface User {
email: string;
password?: string;
passwordConf?: string;
accessToken?: AccessToken;
refreshToken?: RefreshToken;
accessToken?: Token;
refreshToken?: Token;
isSAdmin: boolean;
joinedAt: string;
}
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/utils/fetchData.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { GetServerSidePropsContext } from 'next';
import { getSession } from 'next-auth/react';

import axios, { AxiosRequestConfig } from 'axios';

import { getSession } from 'next-auth/react';
import { NEXT_PUBLIC_BACKEND_URL } from './constants';

export const instance = axios.create({
Expand All @@ -15,7 +16,7 @@ const nonNeededToken = ['/auth/login', '/auth/refresh', '/auth/registerAzure'];

export const getToken = async (context?: GetServerSidePropsContext) => {
const session = await getSession(context);
if (session) return `Bearer ${session?.accessToken}`;
if (session) return `Bearer ${session?.user.accessToken.token}`;
return 'Bearer ';
};

Expand Down Expand Up @@ -52,6 +53,7 @@ const fetchData = async <T,>(url: string, options?: Options): Promise<T> => {
Authorization: refreshToken ? `Bearer ${refreshToken}` : await getToken(context),
};
}

const { data } = !serverSide
? await instance(instanceOptions)
: await serverSideInstance(instanceOptions);
Expand Down

0 comments on commit 9a2d814

Please sign in to comment.