80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
import { captureException } from "@sentry/nextjs";
|
|
|
|
import db from "@calcom/prisma";
|
|
|
|
import type { AppFlags } from "./config";
|
|
import type { IFeaturesRepository } from "./features.repository.interface";
|
|
import { getFeatureFlag } from "./server/utils";
|
|
|
|
export class FeaturesRepository implements IFeaturesRepository {
|
|
async checkIfFeatureIsEnabledGlobally(slug: keyof AppFlags) {
|
|
try {
|
|
return await getFeatureFlag(db, slug);
|
|
} catch (err) {
|
|
captureException(err);
|
|
throw err;
|
|
}
|
|
}
|
|
async checkIfUserHasFeature(userId: number, slug: string) {
|
|
try {
|
|
/**
|
|
* findUnique was failing in prismock tests, so I'm using findFirst instead
|
|
* FIXME refactor when upgrading prismock
|
|
* https://github.com/morintd/prismock/issues/592
|
|
*/
|
|
const userHasFeature = await db.userFeatures.findFirst({
|
|
where: {
|
|
userId,
|
|
featureId: slug,
|
|
},
|
|
});
|
|
if (userHasFeature) return true;
|
|
// If the user doesn't have the feature, check if they belong to a team with the feature.
|
|
// This also covers organizations, which are teams.
|
|
const userBelongsToTeamWithFeature = await this.checkIfUserBelongsToTeamWithFeature(userId, slug);
|
|
if (userBelongsToTeamWithFeature) return true;
|
|
return false;
|
|
} catch (err) {
|
|
captureException(err);
|
|
throw err;
|
|
}
|
|
}
|
|
private async checkIfUserBelongsToTeamWithFeature(userId: number, slug: string) {
|
|
try {
|
|
const user = await db.user.findUnique({
|
|
where: {
|
|
id: userId,
|
|
teams: {
|
|
some: {
|
|
team: {
|
|
features: {
|
|
some: {
|
|
featureId: slug,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
select: { id: true },
|
|
});
|
|
if (user) return true;
|
|
return false;
|
|
} catch (err) {
|
|
captureException(err);
|
|
throw err;
|
|
}
|
|
}
|
|
async checkIfTeamHasFeature(teamId: number, featureId: keyof AppFlags) {
|
|
try {
|
|
const teamFeature = await db.teamFeatures.findUnique({
|
|
where: { teamId_featureId: { teamId, featureId } },
|
|
});
|
|
return !!teamFeature;
|
|
} catch (err) {
|
|
captureException(err);
|
|
throw err;
|
|
}
|
|
}
|
|
}
|