Add named teams and per-user data visibility (own/team/org) with settings UI and org module.
This commit is contained in:
@@ -2,8 +2,11 @@ import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||
import type { DataVisibility } from '@mento/shared';
|
||||
import { BillingService } from '../billing/billing.service';
|
||||
import { normalizeDataVisibility } from '../common/record-scope';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { canViewAllRecords } from '@mento/shared';
|
||||
|
||||
export type JwtPayload = {
|
||||
sub: string;
|
||||
@@ -50,16 +53,58 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
isActive: true,
|
||||
organization: { isActive: true },
|
||||
},
|
||||
select: { organizationId: true, role: true },
|
||||
select: { organizationId: true, role: true, dataVisibility: true },
|
||||
});
|
||||
if (!membership) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
await this.billing.requireActiveForOrganization(membership.organizationId);
|
||||
|
||||
const dataVisibility = normalizeDataVisibility(membership.dataVisibility);
|
||||
const visibleUserIds = await this.resolveVisibleUserIds(
|
||||
membership.organizationId,
|
||||
user.id,
|
||||
membership.role,
|
||||
dataVisibility,
|
||||
);
|
||||
|
||||
return {
|
||||
userId: user.id,
|
||||
organizationId: membership.organizationId,
|
||||
role: membership.role,
|
||||
dataVisibility,
|
||||
visibleUserIds,
|
||||
};
|
||||
}
|
||||
|
||||
private async resolveVisibleUserIds(
|
||||
organizationId: string,
|
||||
userId: string,
|
||||
role: string,
|
||||
dataVisibility: DataVisibility,
|
||||
): Promise<string[] | null> {
|
||||
if (canViewAllRecords(role) || dataVisibility === 'org') {
|
||||
return null;
|
||||
}
|
||||
if (dataVisibility === 'own') {
|
||||
return [userId];
|
||||
}
|
||||
|
||||
const memberships = await this.prisma.teamMember.findMany({
|
||||
where: {
|
||||
userId,
|
||||
team: { organizationId },
|
||||
},
|
||||
select: { teamId: true },
|
||||
});
|
||||
if (!memberships.length) return [userId];
|
||||
|
||||
const peers = await this.prisma.teamMember.findMany({
|
||||
where: {
|
||||
teamId: { in: memberships.map((m) => m.teamId) },
|
||||
},
|
||||
select: { userId: true },
|
||||
});
|
||||
return [...new Set([userId, ...peers.map((p) => p.userId)])];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user