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:
@@ -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 }) => {
|
||||
|
||||
Vendored
+4
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user