fix: updating managed user email (#23794)

This commit is contained in:
Lauris Skraucis authored and GitHub committed 2025-09-12 18:26:52 +01:00
1 parent 74288b0ecb
commit 79169de8d8
7 files changed
+49 -5

No files matched your search

@@ -15,6 +15,7 @@ import { OAuthClientRepository } from "@/modules/oauth-clients/oauth-client.repo
import { OAuthClientUsersService } from "@/modules/oauth-clients/services/oauth-clients-users.service";
import { OAuthFlowService } from "@/modules/oauth-clients/services/oauth-flow.service";
import { PrismaModule } from "@/modules/prisma/prisma.module";
import { ProfilesModule } from "@/modules/profiles/profiles.module";
import { RedisModule } from "@/modules/redis/redis.module";
import { SelectedCalendarsRepository } from "@/modules/selected-calendars/selected-calendars.repository";
import { TokensModule } from "@/modules/tokens/tokens.module";
@@ -33,6 +34,7 @@ import { Module } from "@nestjs/common";
EventTypesModule_2024_04_15,
SchedulesModule_2024_04_15,
EventTypesModule_2024_06_14,
ProfilesModule,
],
providers: [
TokensRepository,
@@ -30,6 +30,7 @@ import { OAuthFlowService } from "@/modules/oauth-clients/services/oauth-flow.se
import { OrganizationsRepository } from "@/modules/organizations/index/organizations.repository";
import { OrganizationsTeamsRepository } from "@/modules/organizations/teams/index/organizations-teams.repository";
import { PrismaModule } from "@/modules/prisma/prisma.module";
import { ProfilesModule } from "@/modules/profiles/profiles.module";
import { RedisModule } from "@/modules/redis/redis.module";
import { SelectedCalendarsRepository } from "@/modules/selected-calendars/selected-calendars.repository";
import { StripeModule } from "@/modules/stripe/stripe.module";
@@ -56,6 +57,7 @@ import { Module } from "@nestjs/common";
TeamsModule,
TeamsEventTypesModule,
MembershipsModule,
ProfilesModule,
],
providers: [
TokensRepository,
@@ -627,7 +627,7 @@ describe("OAuth Client Users Endpoints", () => {
expect(responseBody.data.metadata).toEqual(postResponseData.user.metadata);
});
it(`/PUT/:id`, async () => {
it(`/PATCH/:id`, async () => {
const userUpdatedEmail = "pineapple-pizza@gmail.com";
const body: UpdateManagedUserInput = { email: userUpdatedEmail, locale: Locales.PT_BR };
@@ -652,6 +652,13 @@ describe("OAuth Client Users Endpoints", () => {
const [domainName, TLD] = emailDomain.split(".");
expect(responseBody.data.username).toEqual(slugify(`${emailUser}-${domainName}-${TLD}`));
expect(responseBody.data.locale).toEqual(Locales.PT_BR);
const profile = await profilesRepositoryFixture.findByOrgIdUserId(
organization.id,
responseBody.data.id
);
expect(profile).toBeDefined();
expect(profile?.username).toEqual(responseBody.data.username);
});
it("should force refresh tokens", async () => {
@@ -1,4 +1,5 @@
import { API_VERSIONS_VALUES } from "@/lib/api-versions";
import { GetOrgId } from "@/modules/auth/decorators/get-org-id/get-org-id.decorator";
import { MembershipRoles } from "@/modules/auth/decorators/roles/membership-roles.decorator";
import { ApiAuthGuard } from "@/modules/auth/guards/api-auth/api-auth.guard";
import { OrganizationRolesGuard } from "@/modules/auth/guards/organization-roles/organization-roles.guard";
@@ -127,12 +128,18 @@ export class OAuthClientUsersController {
async updateUser(
@Param("clientId") clientId: string,
@Param("userId") userId: number,
@Body() body: UpdateManagedUserInput
@Body() body: UpdateManagedUserInput,
@GetOrgId() organizationId: number
): Promise<GetManagedUserOutput> {
await this.validateManagedUserOwnership(clientId, userId);
this.logger.log(`Updating user with ID ${userId}: ${JSON.stringify(body, null, 2)}`);
const user = await this.oAuthClientUsersService.updateOAuthClientUser(clientId, userId, body);
const user = await this.oAuthClientUsersService.updateOAuthClientUser(
clientId,
userId,
body,
organizationId
);
return {
status: SUCCESS_STATUS,
@@ -21,6 +21,7 @@ import { OAuthFlowService } from "@/modules/oauth-clients/services/oauth-flow.se
import { OrganizationsModule } from "@/modules/organizations/organizations.module";
import { OrganizationsTeamsService } from "@/modules/organizations/teams/index/services/organizations-teams.service";
import { PrismaModule } from "@/modules/prisma/prisma.module";
import { ProfilesModule } from "@/modules/profiles/profiles.module";
import { RedisModule } from "@/modules/redis/redis.module";
import { SelectedCalendarsRepository } from "@/modules/selected-calendars/selected-calendars.repository";
import { StripeModule } from "@/modules/stripe/stripe.module";
@@ -44,6 +45,7 @@ import { JwtService } from "@nestjs/jwt";
StripeModule,
BillingModule,
SchedulesModule_2024_04_15,
ProfilesModule,
],
providers: [
OAuthClientRepository,
@@ -3,6 +3,7 @@ import { EventTypesService_2024_04_15 } from "@/ee/event-types/event-types_2024_
import { SchedulesService_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/services/schedules.service";
import { Locales } from "@/lib/enums/locales";
import { GetManagedUsersInput } from "@/modules/oauth-clients/controllers/oauth-client-users/inputs/get-managed-users.input";
import { ProfilesRepository } from "@/modules/profiles/profiles.repository";
import { TokensRepository } from "@/modules/tokens/tokens.repository";
import { CreateManagedUserInput } from "@/modules/users/inputs/create-managed-user.input";
import { UpdateManagedUserInput } from "@/modules/users/inputs/update-managed-user.input";
@@ -21,7 +22,8 @@ export class OAuthClientUsersService {
private readonly tokensRepository: TokensRepository,
private readonly eventTypesService: EventTypesService_2024_04_15,
private readonly schedulesService: SchedulesService_2024_04_15,
private readonly calendarsService: CalendarsService
private readonly calendarsService: CalendarsService,
private readonly profilesRepository: ProfilesRepository
) {}
async createOAuthClientUser(oAuthClient: PlatformOAuthClient, body: CreateManagedUserInput) {
@@ -130,7 +132,12 @@ export class OAuthClientUsersService {
return managedUsers;
}
async updateOAuthClientUser(oAuthClientId: string, userId: number, body: UpdateManagedUserInput) {
async updateOAuthClientUser(
oAuthClientId: string,
userId: number,
body: UpdateManagedUserInput,
organizationId: number
) {
if (body.email) {
const emailWithOAuthId = OAuthClientUsersService.getOAuthUserEmail(oAuthClientId, body.email);
body.email = emailWithOAuthId;
@@ -138,6 +145,9 @@ export class OAuthClientUsersService {
const [domainName, TLD] = emailDomain.split(".");
const newUsername = slugify(`${emailUser}-${domainName}-${TLD}`);
await this.userRepository.updateUsername(userId, newUsername);
await this.profilesRepository.updateProfile(organizationId, userId, {
username: newUsername,
});
}
return this.userRepository.update(userId, body);
@@ -2,6 +2,8 @@ import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
import { Injectable } from "@nestjs/common";
import { v4 as uuidv4 } from "uuid";
import type { Prisma } from "@calcom/prisma/client";
@Injectable()
export class ProfilesRepository {
constructor(private readonly dbRead: PrismaReadService) {}
@@ -29,4 +31,16 @@ export class ProfilesRepository {
},
});
}
async updateProfile(orgId: number, userId: number, body: Prisma.ProfileUpdateInput) {
return this.dbRead.prisma.profile.update({
where: {
userId_organizationId: {
userId,
organizationId: orgId,
},
},
data: body,
});
}
}