Skip to content

Commit 1175ab1

Browse files
committed
fix(dash/team): 🛂 Update edit permissions to use shared perms instead of sso perms
1 parent 1ca7205 commit 1175ab1

3 files changed

Lines changed: 98 additions & 22 deletions

File tree

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,46 @@
1-
import { User } from '@/types/User';
21
import { getSession } from '@/util/auth';
3-
import { authedFetcher } from '@/util/data';
42
import prisma from '@/util/db';
3+
import { cache } from 'react';
54

65
export const getUser = async () => {
76
const session = await getSession();
87
if (!session) throw Error('No session found');
98

10-
const user = await prisma.user.findFirst({
11-
where: { ssoId: session.user.id },
12-
select: {
13-
id: true,
14-
ssoId: true,
15-
username: true,
16-
discordId: true,
17-
minecraft: true,
18-
avatar: true,
19-
},
20-
});
9+
const user = await cache(
10+
async (id: string) =>
11+
await prisma.user.findFirst({
12+
where: { ssoId: id },
13+
select: {
14+
id: true,
15+
ssoId: true,
16+
username: true,
17+
discordId: true,
18+
minecraft: true,
19+
avatar: true,
20+
},
21+
}),
22+
)(session.user.id);
2123

2224
if (!user) throw Error('User not found');
2325

24-
return user;
26+
return user!;
2527
};
28+
29+
export const getUserPermissions = cache(async (ssoId?: string) => {
30+
if (!ssoId) {
31+
const session = await getSession();
32+
if (!session) throw Error('No session found');
33+
ssoId = session.user.id;
34+
}
35+
36+
const permissions = await prisma.userPermission.findMany({
37+
where: {
38+
user: { ssoId },
39+
},
40+
include: {
41+
permission: true,
42+
buildTeam: { select: { id: true, slug: true, name: true } },
43+
},
44+
});
45+
return permissions;
46+
});

apps/dashboard/src/app/(sideNavbar)/team/[slug]/edit/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default async function Page({ params }: { params: Promise<{ slug: string
4545
const ownerGenerateTokenAction = ownerGenerateToken.bind(null, { userId: user.id, id: team.id });
4646

4747
return (
48-
<Protection requiredRole="get-teams">
48+
<Protection requiredBuildTeam={{ permission: 'team.settings.edit', slug: 'de' }}>
4949
<ContentWrapper maw="90vw">
5050
<SaveNotification />
5151
<form action={userEditTeamInfo}>

apps/dashboard/src/components/Protection.tsx

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,71 @@ import { getSession, hasRole } from '@/util/auth';
33

44
import ErrorDisplay from './core/ErrorDisplay';
55

6+
import { getUserPermissions } from '@/actions/getUser';
7+
import { Permisision } from '@repo/db';
68
import type { JSX } from 'react';
79

8-
export async function Protection({ children, requiredRole }: { children: JSX.Element; requiredRole: string }) {
9-
const session = await getSession();
10+
export async function Protection(
11+
props:
12+
| { children: JSX.Element; requiredRole: string }
13+
| {
14+
children: JSX.Element;
15+
requiredBuildTeam: ({ id: string } | { slug: string }) & { permission: Permisision['id'] };
16+
},
17+
) {
18+
if ('requiredRole' in props) {
19+
const session = await getSession();
1020

11-
if (!hasRole(session, requiredRole)) {
12-
return (
13-
<ErrorDisplay message="The Page you are trying to open requires special permissions. You are not authorized to view it. If you think this is a mistake please contact us." />
14-
);
21+
if (!hasRole(session, props.requiredRole)) {
22+
return (
23+
<ErrorDisplay message="The Page you are trying to open requires special permissions. You are not authorized to view it. If you think this is a mistake please contact us." />
24+
);
25+
}
26+
27+
return props.children;
28+
}
29+
30+
if ('requiredBuildTeam' in props && props.requiredBuildTeam) {
31+
const permissions = await getUserPermissions();
32+
33+
const hasPermission = permissions.some((perm) => {
34+
// 1. user has global permission (no buildteam referenced)
35+
if (props.requiredBuildTeam.permission === perm.permission.id && !perm.buildTeam) {
36+
return true;
37+
}
38+
// 2. user has permission for buildteam with id
39+
if (
40+
'id' in props.requiredBuildTeam &&
41+
perm.buildTeam &&
42+
props.requiredBuildTeam.permission === perm.permission.id &&
43+
props.requiredBuildTeam.id === perm.buildTeam.id
44+
) {
45+
return true;
46+
}
47+
// 3. user has permission for buildteam with slug
48+
if (
49+
'slug' in props.requiredBuildTeam &&
50+
perm.buildTeam &&
51+
props.requiredBuildTeam.permission === perm.permission.id &&
52+
props.requiredBuildTeam.slug === perm.buildTeam.slug
53+
) {
54+
return true;
55+
}
56+
});
57+
58+
if (!hasPermission) {
59+
return (
60+
<ErrorDisplay message="The Page you are trying to open requires special permissions. You are not authorized to view it. If you think this is a mistake please contact us." />
61+
);
62+
}
63+
64+
return props.children;
1565
}
1666

17-
return children;
67+
return (
68+
<ErrorDisplay
69+
message="There was an error computing your permissions to access this page. Please reload the page and message us."
70+
showBackButton
71+
/>
72+
);
1873
}

0 commit comments

Comments
 (0)