fix: check profiles and orgId from user.profiles apiv2 (#16249)

* fix: check profiles and orgId from user.profiles apiv2

* fixup! fix: check profiles and orgId from user.profiles apiv2

---------

Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
This commit is contained in:
Morgan
2024-08-21 15:15:48 +00:00
committed by GitHub
co-authored by Lauris Skraucis
parent 7759e6a029
commit 1690770d6a
11 changed files with 49 additions and 23 deletions
@@ -1,6 +1,7 @@
import { CreateEventTypeInput_2024_04_15 } from "@/ee/event-types/event-types_2024_04_15/inputs/create-event-type.input";
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
import { UsersService } from "@/modules/users/services/users.service";
import { UserWithProfile } from "@/modules/users/users.repository";
import { Injectable } from "@nestjs/common";
@@ -9,7 +10,11 @@ import type { PrismaClient } from "@calcom/prisma";
@Injectable()
export class EventTypesRepository_2024_04_15 {
constructor(private readonly dbRead: PrismaReadService, private readonly dbWrite: PrismaWriteService) {}
constructor(
private readonly dbRead: PrismaReadService,
private readonly dbWrite: PrismaWriteService,
private usersService: UsersService
) {}
async createUserEventType(
userId: number,
@@ -46,7 +51,7 @@ export class EventTypesRepository_2024_04_15 {
eventTypeId: number
) {
return await getEventTypeById({
currentOrganizationId: user.movedToProfile?.organizationId || user.organizationId,
currentOrganizationId: this.usersService.getUserMainOrgId(user),
eventTypeId,
userId: user.id,
prisma: this.dbRead.prisma as unknown as PrismaClient,
@@ -6,6 +6,7 @@ import { EventTypeOutput } from "@/ee/event-types/event-types_2024_04_15/outputs
import { MembershipsRepository } from "@/modules/memberships/memberships.repository";
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
import { SelectedCalendarsRepository } from "@/modules/selected-calendars/selected-calendars.repository";
import { UsersService } from "@/modules/users/services/users.service";
import { UserWithProfile, UsersRepository } from "@/modules/users/users.repository";
import { BadRequestException, ForbiddenException, Injectable, NotFoundException } from "@nestjs/common";
@@ -24,7 +25,8 @@ export class EventTypesService_2024_04_15 {
private readonly membershipsRepository: MembershipsRepository,
private readonly usersRepository: UsersRepository,
private readonly selectedCalendarsRepository: SelectedCalendarsRepository,
private readonly dbWrite: PrismaWriteService
private readonly dbWrite: PrismaWriteService,
private usersService: UsersService
) {}
async createUserEventType(
@@ -53,11 +55,11 @@ export class EventTypesService_2024_04_15 {
}
async getUserToCreateEvent(user: UserWithProfile) {
const organizationId = user.movedToProfile?.organizationId || user.organizationId;
const organizationId = this.usersService.getUserMainOrgId(user);
const isOrgAdmin = organizationId
? await this.membershipsRepository.isUserOrganizationAdmin(user.id, organizationId)
: false;
const profileId = user.movedToProfile?.id || null;
const profileId = this.usersService.getUserMainProfile(user)?.id || null;
return {
id: user.id,
role: user.role,
@@ -80,7 +82,7 @@ export class EventTypesService_2024_04_15 {
}
async getUserEventTypeForAtom(user: UserWithProfile, eventTypeId: number) {
const organizationId = user.movedToProfile?.organizationId || user.organizationId;
const organizationId = this.usersService.getUserMainOrgId(user);
const isUserOrganizationAdmin = organizationId
? await this.membershipsRepository.isUserOrganizationAdmin(user.id, organizationId)
@@ -153,7 +155,7 @@ export class EventTypesService_2024_04_15 {
}
async getUserToUpdateEvent(user: UserWithProfile) {
const profileId = user.movedToProfile?.id || null;
const profileId = this.usersService.getUserMainProfile(user)?.id || null;
const selectedCalendars = await this.selectedCalendarsRepository.getUserSelectedCalendars(user.id);
return { ...user, profile: { id: profileId }, selectedCalendars };
}
@@ -1,5 +1,6 @@
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
import { UsersService } from "@/modules/users/services/users.service";
import { UserWithProfile } from "@/modules/users/users.repository";
import { Injectable } from "@nestjs/common";
@@ -34,7 +35,11 @@ type InputEventTransformed = Omit<
@Injectable()
export class EventTypesRepository_2024_06_14 {
constructor(private readonly dbRead: PrismaReadService, private readonly dbWrite: PrismaWriteService) {}
constructor(
private readonly dbRead: PrismaReadService,
private readonly dbWrite: PrismaWriteService,
private usersService: UsersService
) {}
async createUserEventType(userId: number, body: InputEventTransformed) {
return this.dbWrite.prisma.eventType.create({
@@ -80,7 +85,7 @@ export class EventTypesRepository_2024_06_14 {
eventTypeId: number
) {
return await getEventTypeById({
currentOrganizationId: user.movedToProfile?.organizationId || user.organizationId,
currentOrganizationId: this.usersService.getUserMainOrgId(user),
eventTypeId,
userId: user.id,
prisma: this.dbRead.prisma as unknown as PrismaClient,
@@ -119,11 +119,11 @@ export class EventTypesService_2024_06_14 {
}
async getUserToCreateEvent(user: UserWithProfile) {
const organizationId = user.movedToProfile?.organizationId || user.organizationId;
const organizationId = this.usersService.getUserMainOrgId(user);
const isOrgAdmin = organizationId
? await this.membershipsRepository.isUserOrganizationAdmin(user.id, organizationId)
: false;
const profileId = user.movedToProfile?.id || null;
const profileId = this.usersService.getUserMainProfile(user)?.id || null;
const selectedCalendars = await this.selectedCalendarsRepository.getUserSelectedCalendars(user.id);
return {
id: user.id,
@@ -159,7 +159,7 @@ export class EventTypesService_2024_06_14 {
}
async getUserEventTypeForAtom(user: UserWithProfile, eventTypeId: number) {
const organizationId = user.movedToProfile?.organizationId || user.organizationId;
const organizationId = this.usersService.getUserMainOrgId(user);
const isUserOrganizationAdmin = organizationId
? await this.membershipsRepository.isUserOrganizationAdmin(user.id, organizationId)
@@ -270,7 +270,7 @@ export class EventTypesService_2024_06_14 {
}
async getUserToUpdateEvent(user: UserWithProfile) {
const profileId = user.movedToProfile?.id || null;
const profileId = this.usersService.getUserMainProfile(user)?.id || null;
const selectedCalendars = await this.selectedCalendarsRepository.getUserSelectedCalendars(user.id);
return { ...user, profile: { id: profileId }, selectedCalendars };
}
@@ -1,6 +1,7 @@
import { MembershipRoles } from "@/modules/auth/decorators/roles/membership-roles.decorator";
import { MembershipsRepository } from "@/modules/memberships/memberships.repository";
import { OrganizationsService } from "@/modules/organizations/services/organizations.service";
import { UsersService } from "@/modules/users/services/users.service";
import { UserWithProfile } from "@/modules/users/users.repository";
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
@@ -12,13 +13,14 @@ export class OrganizationRolesGuard implements CanActivate {
constructor(
private reflector: Reflector,
private organizationsService: OrganizationsService,
private membershipRepository: MembershipsRepository
private membershipRepository: MembershipsRepository,
private usersService: UsersService
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const user: UserWithProfile = request.user;
const organizationId = user?.movedToProfile?.organizationId || user?.organizationId;
const organizationId = user ? this.usersService.getUserMainOrgId(user) : null;
if (!user || !organizationId) {
throw new ForbiddenException("No organization associated with the user.");
@@ -7,6 +7,7 @@ import { MembershipsModule } from "@/modules/memberships/memberships.module";
import { OrganizationsModule } from "@/modules/organizations/organizations.module";
import { PrismaModule } from "@/modules/prisma/prisma.module";
import { StripeModule } from "@/modules/stripe/stripe.module";
import { UsersModule } from "@/modules/users/users.module";
import { BullModule } from "@nestjs/bull";
import { Module } from "@nestjs/common";
@@ -23,6 +24,7 @@ import { Module } from "@nestjs/common";
duration: 1000,
},
}),
UsersModule,
],
providers: [BillingConfigService, BillingService, BillingRepository, BillingProcessor],
exports: [BillingService, BillingRepository],
@@ -13,6 +13,7 @@ import { OAuthClientGuard } from "@/modules/oauth-clients/guards/oauth-client-gu
import { UpdateOAuthClientInput } from "@/modules/oauth-clients/inputs/update-oauth-client.input";
import { OAuthClientRepository } from "@/modules/oauth-clients/oauth-client.repository";
import { OrganizationsRepository } from "@/modules/organizations/organizations.repository";
import { UsersService } from "@/modules/users/services/users.service";
import { UserWithProfile } from "@/modules/users/users.repository";
import { UsersRepository } from "@/modules/users/users.repository";
import {
@@ -59,7 +60,8 @@ export class OAuthClientsController {
constructor(
private readonly oauthClientRepository: OAuthClientRepository,
private readonly userRepository: UsersRepository,
private readonly teamsRepository: OrganizationsRepository
private readonly teamsRepository: OrganizationsRepository,
private usersService: UsersService
) {}
@Post("/")
@@ -74,7 +76,7 @@ export class OAuthClientsController {
@GetUser() user: UserWithProfile,
@Body() body: CreateOAuthClientInput
): Promise<CreateOAuthClientResponseDto> {
const organizationId = (user.movedToProfile?.organizationId ?? user.organizationId) as number;
const organizationId = this.usersService.getUserMainOrgId(user) as number;
this.logger.log(
`For organisation ${organizationId} creating OAuth Client with data: ${JSON.stringify(body)}`
);
@@ -100,7 +102,7 @@ export class OAuthClientsController {
@MembershipRoles([MembershipRole.ADMIN, MembershipRole.OWNER, MembershipRole.MEMBER])
@DocsOperation({ description: AUTH_DOCUMENTATION })
async getOAuthClients(@GetUser() user: UserWithProfile): Promise<GetOAuthClientsResponseDto> {
const organizationId = (user.movedToProfile?.organizationId ?? user.organizationId) as number;
const organizationId = this.usersService.getUserMainOrgId(user) as number;
const clients = await this.oauthClientRepository.getOrganizationOAuthClients(organizationId);
return { status: SUCCESS_STATUS, data: clients };
@@ -1,5 +1,6 @@
import { GetUserReturnType } from "@/modules/auth/decorators/get-user/get-user.decorator";
import { OAuthClientRepository } from "@/modules/oauth-clients/oauth-client.repository";
import { UsersService } from "@/modules/users/services/users.service";
import {
Injectable,
CanActivate,
@@ -11,12 +12,12 @@ import { Request } from "express";
@Injectable()
export class OAuthClientGuard implements CanActivate {
constructor(private oAuthClientRepository: OAuthClientRepository) {}
constructor(private oAuthClientRepository: OAuthClientRepository, private usersService: UsersService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest<Request & { user: GetUserReturnType }>();
const user: GetUserReturnType = request.user;
const organizationId = user?.movedToProfile?.organizationId || user?.organizationId;
const organizationId = user ? this.usersService.getUserMainOrgId(user) : null;
const oAuthClientId = request.params.clientId;
if (!oAuthClientId) {
@@ -96,7 +96,8 @@ export class OrganizationsEventTypesService {
async getUserToCreateTeamEvent(user: UserWithProfile, organizationId: number) {
const isOrgAdmin = await this.membershipsRepository.isUserOrganizationAdmin(user.id, organizationId);
const profileId =
this.usersService.getUserProfileByOrgId(user, organizationId)?.id || user.movedToProfileId;
this.usersService.getUserProfileByOrgId(user, organizationId)?.id ||
this.usersService.getUserMainProfile(user)?.id;
return {
id: user.id,
role: user.role,
@@ -30,6 +30,10 @@ export class UsersService {
);
}
getUserMainOrgId(user: UserWithProfile) {
return this.getUserMainProfile(user)?.organizationId ?? user.organizationId;
}
getUserProfileByOrgId(user: UserWithProfile, organizationId: number) {
return user.profiles?.find((p) => p.organizationId === organizationId);
}
@@ -1,5 +1,6 @@
import { GetUserReturnType } from "@/modules/auth/decorators/get-user/get-user.decorator";
import { OAuthClientRepository } from "@/modules/oauth-clients/oauth-client.repository";
import { UsersService } from "@/modules/users/services/users.service";
import { WebhooksService } from "@/modules/webhooks/services/webhooks.service";
import {
CanActivate,
@@ -17,7 +18,8 @@ import { PlatformOAuthClient, Webhook } from "@calcom/prisma/client";
export class IsOAuthClientWebhookGuard implements CanActivate {
constructor(
private readonly webhooksService: WebhooksService,
private readonly oAuthClientRepository: OAuthClientRepository
private readonly oAuthClientRepository: OAuthClientRepository,
private usersService: UsersService
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
@@ -27,7 +29,7 @@ export class IsOAuthClientWebhookGuard implements CanActivate {
const user = request.user as GetUserReturnType;
const webhookId = request.params.webhookId;
const oAuthClientId = request.params.clientId;
const organizationId = user.movedToProfile?.organizationId || user.organizationId;
const organizationId = this.usersService.getUserMainOrgId(user);
if (!user) {
throw new ForbiddenException("User not authenticated");