Open helabenkhalfallah opened 1 month ago
Frontend:
Frontend BO:
Authentication UI exists. You should connect this files to BFF: https://github.com/ekino/v6y/blob/main/src/v6y-front-bo/src/infrastructure/providers/GraphQLProvider.ts#L30
Use the same BFF authentication as the Frontend.
Final result: All Frontend and Frontend BO screens should been protected with authentication access.
Inspirational examples: https://github.com/ekino/v6y/blob/main/src/v6y-front-bo/src/app/page.tsx#L11 https://github.com/ekino/v6y/blob/main/src/v6y-front-bo/src/app/v6y-faqs/layout.tsx#L6 https://gitlab.ekino.com/renault/mfs/myze-battery/-/blob/main/apps/front/components/ProtectedRoute.tsx#L7
"use client";
import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { useLogin } from "../hooks/useAuth";
export function ProtectedRoute({ children }: React.PropsWithChildren<{}>) {
const { isLoggedIn, isLoginLoading } = useLogin();
const router = useRouter();
useEffect(() => {
if (!isLoggedIn && !isLoginLoading) {
router.replace("/");
}
}, [isLoggedIn, isLoginLoading, router]);
return isLoggedIn ? children : null;
}
import { PropsWithChildren } from "react";
import { ProtectedRoute } from "./ProtectedRoute";
import RouteErrorHandler from "./errors/RouteErrorHandler";
type Props = {
error?: Error | null;
};
export default function RouteWrapper({
error,
children,
}: PropsWithChildren<Props>) {
return (
<ProtectedRoute>
<RouteErrorHandler error={error}>{children}</RouteErrorHandler>
</ProtectedRoute>
);
}
// https://gitlab.ekino.com/renault/mfs/myze-battery/-/blob/main/apps/front/app/profile/layout.tsx
import { PropsWithChildren } from "react";
import RouteWrapper from "../../components/RouteWrapper";
export default function ProfileLayout({ children }: PropsWithChildren) {
return (
<RouteWrapper>
<div className="flex flex-col items-center h-full pt-10 pb-16 lg:pt-12 lg:pb-16 lg:px-20 bg-backgroundMain">
<section className="bg-backgroundPrimary flex flex-col px-6 py-8 w-full lg:py-15 lg:px-17">
{children}
</section>
</div>
</RouteWrapper>
);
}
"use client";
import { useQuery } from "@tanstack/react-query";
import { useRouter } from "next/navigation";
import { getLogoutUrl, logoutJWT, retrieveJWT } from "@myze/fo-sdk";
import { getFOSDKConfig } from "../helpers/getFOSDKConfig";
import { useStorage } from "./useStorage";
const queryKey = ["jwt"];
const logoutUrl = getLogoutUrl(getFOSDKConfig());
export const useLogin = () => {
const { isSuccess: isLoggedIn, isLoading: isLoginLoading } = useQuery({
queryKey,
queryFn: () => retrieveJWT(window.gigya!),
});
return {
isLoggedIn,
isLoginLoading,
};
};
export const useLogout = () => {
const { replace } = useRouter();
const { clearStorage } = useStorage();
const logout = async (): Promise<void> => {
await logoutJWT(window.gigya!);
clearStorage();
replace(logoutUrl);
};
return { logout };
};
Dans le frontend:
const { isLoading, data }: VitalityFaqQueryType = useClientQuery({
queryCacheKey: ['getFaqListByPageAndParams'],
queryBuilder: async () =>
buildClientQuery({
queryBaseUrl: VitalityApiConfig.VITALITY_BFF_URL,
query: GetFaqListByPageAndParams,
variables: {},
}),
});
Mutation example:
Frontend:
const CreateOrEditApplication = gql`
mutation CreateOrEditAccount($accountInput: ApplicationCreateOrEditInput!) {
createOrEditApplication(applicationInput: $applicationInput) {
_id
}
}
`;
Create useMutationAdapter
:
https://github.com/ekino/v6y/tree/main/src/v6y-front/src/infrastructure/adapters/api
Inside useMutationAdapter
, we use TanStackQuery Mutation
:
https://tanstack.com/query/latest/docs/framework/react/reference/useMutation
export const useClientMutation = <TData = unknown,>({
mutationCacheKey,
mutationBuilder,
}: UseClientMutationParams<TData>) => {
return useMutation<TData, Error>(params);
};
Consume Mutation:
const {
isLoading,
data,
} = useClientMutation(params);
BFF:
1) Create a folder account
2) Create a type: AccountType
3) Add AccountType
to VitalityTypes
4) Add type : CreateOrEditAccountType
5) Add AccountType
to CreateOrEditAccountType
6) Add AccountMutationsType
7) Add type : AccountMutationsType
8) Create resolver for each AccountMutationsType
function
const createOrEditApplication = async (
_: unknown,
params: { applicationInput: ApplicationInputType },
) => {
try {
9) Add Database model and Provider in v6y-commons/database
then export on v6y-commons/index.js
10) Use exposed model and provider in the resolver.
Tasks:
✨ Description
Authentication interfaces for both the Vitality frontend application and the frontend of the Backoffice (BO), with a focus on protecting source code privacy.
🚀 Motivation
By controlling access to projects, the authentication system ensures that only authorized users can configure and view sensitive source code and reports, preserving their confidentiality and integrity.
📝 Proposed Solution
The Frontend and Frontend BO are the only components directly exposed to users, the authentication layer should be implemented primarily on the BFF side.
How the authentication flow would work:
Verify that all Frontend & Frontend BO routes are protected.
Along with Apollo Server Authentication, we can use passportjs:
🔗 Relevant Links (if any)