feat: include org role in org session data (#14652)

* feat: include org role in org session data

* update contents

* remove: files
This commit is contained in:
sean-brydon
2024-04-19 12:32:04 +01:00
committed by GitHub
parent f6e45842fd
commit dbbd78fb26
4 changed files with 65 additions and 27 deletions
@@ -511,6 +511,19 @@ export const AUTH_OPTIONS: AuthOptions = {
}
const profileOrg = profile?.organization;
let orgRole: MembershipRole | undefined;
// Get users role of org
if (profileOrg) {
const membership = await prisma.membership.findUnique({
where: {
userId_teamId: {
teamId: profileOrg.id,
userId: existingUser.id,
},
},
});
orgRole = membership?.role;
}
return {
...existingUserWithoutTeamsField,
@@ -528,6 +541,7 @@ export const AUTH_OPTIONS: AuthOptions = {
logoUrl: profileOrg.logoUrl,
fullDomain: getOrgFullOrigin(profileOrg.slug ?? profileOrg.requestedSlug ?? ""),
domainSuffix: subdomainSuffix(),
role: orgRole as MembershipRole, // It can't be undefined if we have a profileOrg
}
: null,
} as JWT;
@@ -1,6 +1,7 @@
import { createContext, useContext, createElement } from "react";
import type z from "zod";
import type { MembershipRole } from "@calcom/prisma/enums";
import type { teamMetadataSchema } from "@calcom/prisma/zod-utils";
/**
@@ -22,6 +23,7 @@ export type OrganizationBranding =
fullDomain: string;
/** cal.com */
domainSuffix: string;
role: MembershipRole;
} & z.infer<typeof teamMetadataSchema>)
| null
| undefined;
@@ -3,7 +3,7 @@ import { useSession } from "next-auth/react";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import type { ComponentProps } from "react";
import React, { Suspense, useEffect, useState } from "react";
import React, { Suspense, useEffect, useState, useMemo } from "react";
import { useOrgBranding } from "@calcom/features/ee/organizations/context/provider";
import Shell from "@calcom/features/shell/Shell";
@@ -135,41 +135,59 @@ tabs.find((tab) => {
// The following keys are assigned to admin only
const adminRequiredKeys = ["admin"];
const organizationRequiredKeys = ["organization"];
const organizationAdminKeys = ["privacy", "appearance", "billing", "OAuth Clients", "SSO", "directory_sync"];
const useTabs = () => {
const session = useSession();
const { data: user } = trpc.viewer.me.useQuery({ includePasswordAdded: true });
const orgBranding = useOrgBranding();
const isAdmin = session.data?.user.role === UserPermissionRole.ADMIN;
const isOrgAdminOrOwner =
orgBranding?.role === MembershipRole.ADMIN || orgBranding?.role === MembershipRole.OWNER;
tabs.map((tab) => {
if (tab.href === "/settings/my-account") {
tab.name = user?.name || "my_account";
tab.icon = undefined;
tab.avatar = getUserAvatarUrl(user);
} else if (tab.href === "/settings/organizations") {
tab.name = orgBranding?.name || "organization";
tab.avatar = getPlaceholderAvatar(orgBranding?.logoUrl, orgBranding?.name);
} else if (
tab.href === "/settings/security" &&
user?.identityProvider === IdentityProvider.GOOGLE &&
!user?.twoFactorEnabled &&
!user?.passwordAdded
) {
tab.children = tab?.children?.filter(
(childTab) => childTab.href !== "/settings/security/two-factor-auth"
);
}
return tab;
});
const processTabsMemod = useMemo(() => {
const processedTabs = tabs.map((tab) => {
if (tab.href === "/settings/my-account") {
return {
...tab,
name: user?.name || "my_account",
icon: undefined,
avatar: getUserAvatarUrl(user),
};
} else if (tab.href === "/settings/organizations") {
const newArray = (tab?.children ?? []).filter(
(child) => isOrgAdminOrOwner || !organizationAdminKeys.includes(child.name)
);
return {
...tab,
children: newArray,
name: orgBranding?.name || "organization",
avatar: getPlaceholderAvatar(orgBranding?.logoUrl, orgBranding?.name),
};
} else if (
tab.href === "/settings/security" &&
user?.identityProvider === IdentityProvider.GOOGLE &&
!user?.twoFactorEnabled &&
!user?.passwordAdded
) {
const filtered = tab?.children?.filter(
(childTab) => childTab.href !== "/settings/security/two-factor-auth"
);
return { ...tab, children: filtered };
}
return tab;
});
// check if name is in adminRequiredKeys
return tabs.filter((tab) => {
if (organizationRequiredKeys.includes(tab.name)) return !!session.data?.user?.org;
// check if name is in adminRequiredKeys
return processedTabs.filter((tab) => {
if (organizationRequiredKeys.includes(tab.name)) return !!orgBranding;
if (isAdmin) return true;
return !adminRequiredKeys.includes(tab.name);
});
if (isAdmin) return true;
return !adminRequiredKeys.includes(tab.name);
});
}, [isAdmin, orgBranding, isOrgAdminOrOwner, user]);
return processTabsMemod;
};
const BackButtonInSidebar = ({ name }: { name: string }) => {
+4
View File
@@ -1,6 +1,8 @@
import type { User as PrismaUser, UserPermissionRole } from "@prisma/client";
import type { DefaultUser } from "next-auth";
import type { MembershipRole } from "@calcom/prisma/enums";
import type { UserProfile } from "./UserProfile";
declare module "next-auth" {
@@ -30,6 +32,7 @@ declare module "next-auth" {
logoUrl?: string | null;
fullDomain: string;
domainSuffix: string;
role: MembershipRole;
};
username?: PrismaUser["username"];
avatarUrl?: PrismaUser["avatarUrl"];
@@ -61,6 +64,7 @@ declare module "next-auth/jwt" {
logoUrl?: string | null;
fullDomain: string;
domainSuffix: string;
role: MembershipRole;
};
organizationId?: number | null;
locale?: string;