use global user type detection for pages

This commit is contained in:
vchikalkin 2024-04-10 23:52:52 +03:00
parent 7156477731
commit 76accc138f
6 changed files with 136 additions and 89 deletions

View File

@ -13,11 +13,11 @@ const Main = styled.main`
}
`;
export default function Layout({ children }) {
export default function Layout({ children, user }) {
return (
<>
<Header />
<AppNavigation />
{user?.admin ? <AppNavigation /> : false}
<Main>{children}</Main>
</>
);

View File

@ -54,7 +54,7 @@ function App({ Component, pageProps }) {
>
<Notification>
<MediaContextProvider>
<Layout>
<Layout {...pageProps}>
<Component {...pageProps} />
</Layout>
</MediaContextProvider>

View File

@ -1,11 +1,9 @@
import { getQueries } from '@/api/cache/query';
import { getUser } from '@/api/user/query';
import initializeApollo from '@/apollo/client';
import * as Admin from '@/Components/Admin';
import { Error } from '@/Components/Common/Error';
import { adminRoles } from '@/config/users';
import * as CRMTypes from '@/graphql/crm.types';
import { getPageTitle } from '@/utils/page';
import { makeGetUserType } from '@/utils/user';
import { dehydrate, QueryClient } from '@tanstack/react-query';
import Head from 'next/head';
@ -31,30 +29,13 @@ export async function getServerSideProps({ req }) {
const { cookie = '' } = req.headers;
const queryClient = new QueryClient();
const user = await queryClient.fetchQuery(['user'], ({ signal }) =>
getUser({
headers: {
cookie,
},
signal,
})
);
const apolloClient = initializeApollo();
const getUserType = makeGetUserType({ apolloClient, queryClient });
try {
const {
data: { systemuser },
} = await apolloClient.query({
fetchPolicy: 'network-only',
query: CRMTypes.GetSystemUserDocument,
variables: {
domainname: user.domainName,
},
});
const user = await getUserType({ cookie });
if (!systemuser?.roles?.some((x) => x?.name && adminRoles.includes(x.name))) {
if (!user.admin) {
return {
props: {
initialQueryState: dehydrate(queryClient),
@ -73,6 +54,7 @@ export async function getServerSideProps({ req }) {
initialApolloState: apolloClient.cache.extract(),
initialQueryState: dehydrate(queryClient),
statusCode: 200,
user,
},
};
} catch (error) {

View File

@ -1,11 +1,9 @@
import { getUser } from '@/api/user/query';
import initializeApollo from '@/apollo/client';
import * as Calculation from '@/Components/Calculation';
import { Error } from '@/Components/Common/Error';
import { defaultRoles } from '@/config/users';
import * as CRMTypes from '@/graphql/crm.types';
import * as hooks from '@/process/hooks';
import { getPageTitle } from '@/utils/page';
import { makeGetUserType } from '@/utils/user';
import { dehydrate, QueryClient } from '@tanstack/react-query';
import Head from 'next/head';
@ -33,63 +31,42 @@ export default function Page(props) {
return <Content />;
}
export const makeGetServerSideProps = ({ roles }) =>
/** @type {import('next').GetServerSideProps} */
(
async function ({ req }) {
const { cookie = '' } = req.headers;
/** @type {import('next').GetServerSideProps} */
export async function getServerSideProps({ req }) {
const { cookie = '' } = req.headers;
const queryClient = new QueryClient();
const queryClient = new QueryClient();
const apolloClient = initializeApollo();
const getUserType = makeGetUserType({ apolloClient, queryClient });
const user = await queryClient.fetchQuery(['user'], ({ signal }) =>
getUser({
headers: {
cookie,
},
signal,
})
);
try {
const user = await getUserType({ cookie });
const apolloClient = initializeApollo();
try {
const {
data: { systemuser },
} = await apolloClient.query({
fetchPolicy: 'network-only',
query: CRMTypes.GetSystemUserDocument,
variables: {
domainname: user.domainName,
},
});
if (!systemuser?.roles?.some((x) => x?.name && roles.includes(x.name))) {
return {
props: {
initialQueryState: dehydrate(queryClient),
statusCode: 403,
},
};
}
return {
props: {
calculation: {},
initialApolloState: apolloClient.cache.extract(),
initialQueryState: dehydrate(queryClient),
statusCode: 200,
},
};
} catch (error) {
return {
props: {
error: JSON.stringify(error),
initialQueryState: dehydrate(queryClient),
statusCode: 500,
},
};
}
if (!user.default) {
return {
props: {
initialQueryState: dehydrate(queryClient),
statusCode: 403,
},
};
}
);
export const getServerSideProps = makeGetServerSideProps({ roles: defaultRoles });
return {
props: {
calculation: {},
initialApolloState: apolloClient.cache.extract(),
initialQueryState: dehydrate(queryClient),
statusCode: 200,
user,
},
};
} catch (error) {
return {
props: {
error: JSON.stringify(error),
initialQueryState: dehydrate(queryClient),
statusCode: 500,
},
};
}
}

View File

@ -1,10 +1,11 @@
import { makeGetServerSideProps } from '.';
import initializeApollo from '@/apollo/client';
import * as Calculation from '@/Components/Calculation';
import { Error } from '@/Components/Common/Error';
import { unlimitedRoles } from '@/config/users';
import * as hooks from '@/process/hooks';
import { useStore } from '@/stores/hooks';
import { getPageTitle } from '@/utils/page';
import { makeGetUserType } from '@/utils/user';
import { dehydrate, QueryClient } from '@tanstack/react-query';
import Head from 'next/head';
function Content() {
@ -35,6 +36,42 @@ export default function Page(props) {
return <Content />;
}
export const getServerSideProps = makeGetServerSideProps({
roles: unlimitedRoles,
});
/** @type {import('next').GetServerSideProps} */
export async function getServerSideProps({ req }) {
const { cookie = '' } = req.headers;
const queryClient = new QueryClient();
const apolloClient = initializeApollo();
const getUserType = makeGetUserType({ apolloClient, queryClient });
try {
const user = await getUserType({ cookie });
if (!user.unlimited) {
return {
props: {
initialQueryState: dehydrate(queryClient),
statusCode: 403,
},
};
}
return {
props: {
calculation: {},
initialApolloState: apolloClient.cache.extract(),
initialQueryState: dehydrate(queryClient),
statusCode: 200,
user,
},
};
} catch (error) {
return {
props: {
error: JSON.stringify(error),
initialQueryState: dehydrate(queryClient),
statusCode: 500,
},
};
}
}

51
apps/web/utils/user.ts Normal file
View File

@ -0,0 +1,51 @@
import { getUser } from '@/api/user/query';
import { adminRoles, defaultRoles, unlimitedRoles } from '@/config/users';
import * as CRMTypes from '@/graphql/crm.types';
import type { ApolloClient, NormalizedCache } from '@apollo/client';
import type { QueryClient } from '@tanstack/react-query';
import { sift } from 'radash';
type GetUserTypeProps = {
cookie: string;
};
type UserType = {
admin: boolean;
default: boolean;
unlimited: boolean;
};
type MakeGetUserTypeProps = {
apolloClient: ApolloClient<NormalizedCache>;
queryClient: QueryClient;
};
export function makeGetUserType({ apolloClient, queryClient }: MakeGetUserTypeProps) {
return async function ({ cookie }: GetUserTypeProps): Promise<UserType> {
const user = await queryClient.fetchQuery(['user'], ({ signal }) =>
getUser({
headers: {
cookie,
},
signal,
})
);
const {
data: { systemuser },
} = await apolloClient.query({
fetchPolicy: 'network-only',
query: CRMTypes.GetSystemUserDocument,
variables: {
domainname: user.domainName,
},
});
const roles = systemuser?.roles ? sift(systemuser?.roles)?.map((x) => x?.name) : [];
return {
admin: adminRoles.some((x) => roles?.includes(x)),
default: defaultRoles.some((x) => roles?.includes(x)),
unlimited: unlimitedRoles.some((x) => roles?.includes(x)),
};
};
}