This project integrates Single Sign-On (SSO) functionality using the @mirats/mirats-auth
package. Follow the steps below to set up the SSO in your application.
First, install the SSO package:
npm i @mirats/mirats-auth
Create a file called GlobalContext.js inside the root of your app directory with the following content:
"use client";
import ProtectRoute from "../components/ProtectRoute";
import { getAuth } from "@mirats/mirats-auth";
import { createContext, useContext, useEffect, useState } from "react";
const AppContext = createContext(null);
export const useGlobalContext = () => {
return useContext(AppContext);
};
const GlobalContext = ({ children }) => {
const [userData, setUserData] = useState({});
const getUserData = async () => {
try {
const user = await getAuth();
if (user && user?.currentUser?._id) {
setUserData(user?.currentUser);
return;
}
} catch (error) {
console.log(error);
}
};
useEffect(() => {
if (!Object.keys(userData || {})?.length) {
getUserData();
}
}, [userData?._id]);
return (
<AppContext.Provider value={{ userData }}>
<ProtectRoute>
{children}
</ProtectRoute>
</AppContext.Provider>
);
};
export default GlobalContext;
Create a file outside the app directory called ProtectRoute.js with the following content:
"use client";
import { isLoggedIn, signIn } from "@mirats/mirats-auth";
const ProtectRoute = ({ children }) => {
const { user, loading } = isLoggedIn();
if (user && !loading) {
console.log("user & loading", { user, loading });
return children;
} else {
signIn();
console.log("no user found");
return null;
}
};
export default ProtectRoute;
Import the GlobalContext file inside your layout.js file as shown below:
import dynamic from "next/dynamic";
const GlobalContext = dynamic(() => import("@/context/index"), { ssr: false });
const inter = Inter({ subsets: ["latin"] });
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>
<GlobalContext>
{children}
</GlobalContext>
</body>
</html>
);
}
This documentation outlines the process of inviting a user to join a team using the inviteLink function and its associated steps. The goal is to generate an invite link for the user, ensuring they are properly registered and assigned a gasId, then sending the invite through the appropriate backend services.
inviteLink(email: string, id: string, firstName?: string, lastName?: string, days: number = 30): string | null
Parameters:
email:"example@gmail.com"// required,
id: "" // required,
firstName: "testers", // optional
lastName: "test", // optional
days: 30 // optional(default: expires in 30 days)
This function generates an invitation link for a given user, ensuring they exist in the system. It performs several steps:
-Check if the user exists in the backend system.
-Retrieve or generate a gasId for the user.
-Call the sendUserInvite function to send the invitation.
await getGasId(email: string): Promise<{ gasId: string | null } | null>
For getGasId:
email:"example@gmail.com"// required,
{
gasId: "data?.gasId" //mongoose objectId
email: "data?.email" //email
}
await getGasIds([email: string]): Promise<{ gasId: string | null } | null>
For getGAsIds: (max limit 10)
[
"example1@gmail.com" , # required
"example2@gmail.com" ,
"example3@gmail.com" ,
"example4@gmail.com" ,
"example5@gmail.com"
]
{
gasId: "data?.gasId" //mongoose objectId
email: "data?.email" //email
}
await sendUserInvite(body: inviteBody): Promise<void>
For sendUserInvite:
type inviteBody
{
name: string //req
email: string, //req
id: string, //req
organizationName: string, //Optional
invitedBy: string, //req
days: number //optional
}
{ success: true, msg: "Invite sent successfully", email:"userEmail", id:"mongooseId" }
await sendUserInvite(body: inviteBody): Promise<void>
For sendUserInvites: (max limit of 10)
type inviteBody[]
[
{
name: string, // required
email: string, // required
id: string, // required
organizationName: string, // optional
invitedBy: string, // required
days: number // optional
},
{
name: string, // required
email: string, // required
id: string, // required
organizationName: string, // optional
invitedBy: string, // required
days: number // optional
},
// More inviteBody objects can be added as needed
]
[{ success: true, msg: "Invite sent successfully", email:"userEmail", id:"mongooseId" }]
-The function starts by verifying if the provided email corresponds to an existing user in the backend portal.
-If the user is not found, the system still proceeds to create a gasId for the new user.
-The function sendUserInvite takes a body object containing user details (e.g., name, email, ID, etc.).
-It checks that all required fields (name, email, id, and invitedBy) are present and correctly formatted.
-Optional fields like organizationName and days are validated for type and format if provided.
-The function sendUserInvites accepts an array of inviteBody objects.
-Each object in the array is validated against the same criteria as for a single user.
-If any object fails validation, it is excluded from the process, and the system logs or returns the failure reason.
-The sendUserInvite function sends the invitation to the specified email address.
-If successful, it confirms that the invitation has been sent.
-The sendUserInvites function iterates through the array of inviteBody objects:
-Each validated user receives an invitation.
-Failed invitations (due to missing/invalid data or other issues) are logged or included in a failure response.