Allow editing org team member name, mobile, and password from settings.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import type {
|
||||
DataVisibility,
|
||||
InviteUserRequest,
|
||||
OrgUserDto,
|
||||
UpdateOrgUserRequest,
|
||||
UserRole,
|
||||
} from '@mento/shared';
|
||||
import { DATA_VISIBILITIES } from '@mento/shared';
|
||||
@@ -136,6 +137,80 @@ export class UsersService {
|
||||
}
|
||||
}
|
||||
|
||||
async updateProfile(
|
||||
organizationId: string,
|
||||
actorRole: UserRole,
|
||||
targetId: string,
|
||||
dto: UpdateOrgUserRequest,
|
||||
): Promise<OrgUserDto> {
|
||||
if (actorRole !== 'owner' && actorRole !== 'admin') {
|
||||
throw new ForbiddenException('فقط مالک یا مدیر میتواند مشخصات کاربر را ویرایش کند');
|
||||
}
|
||||
|
||||
const target = await this.memberships.findUserInOrgById(
|
||||
organizationId,
|
||||
targetId,
|
||||
);
|
||||
if (target.role === 'owner' && actorRole !== 'owner') {
|
||||
throw new ForbiddenException('مدیر نمیتواند مشخصات مالک را تغییر دهد');
|
||||
}
|
||||
|
||||
const fullName = dto.fullName.trim();
|
||||
if (fullName.length < 2) {
|
||||
throw new BadRequestException('نام باید حداقل دو حرف باشد');
|
||||
}
|
||||
const mobile = normalizeMobile(dto.mobile);
|
||||
if (!mobile) {
|
||||
throw new BadRequestException('شماره موبایل معتبر نیست');
|
||||
}
|
||||
|
||||
const previousMobile = target.user.mobile ?? '';
|
||||
if (mobile !== previousMobile) {
|
||||
const taken = await this.prisma.user.findFirst({
|
||||
where: { mobile, id: { not: targetId } },
|
||||
select: { id: true },
|
||||
});
|
||||
if (taken) {
|
||||
throw new ConflictException('این شماره موبایل قبلاً ثبت شده است');
|
||||
}
|
||||
}
|
||||
|
||||
const data: Prisma.UserUpdateInput = { fullName, mobile };
|
||||
const prevEmail = target.user.email;
|
||||
const wasSynthetic =
|
||||
prevEmail.endsWith('@users.mento.local') ||
|
||||
prevEmail === inviteEmailFromMobile(previousMobile);
|
||||
if (wasSynthetic && mobile !== previousMobile) {
|
||||
const nextEmail = inviteEmailFromMobile(mobile);
|
||||
const emailTaken = await this.prisma.user.findFirst({
|
||||
where: { email: nextEmail, id: { not: targetId } },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!emailTaken) data.email = nextEmail;
|
||||
}
|
||||
|
||||
const password = dto.password?.trim() ?? '';
|
||||
if (password) {
|
||||
if (password.length < 8) {
|
||||
throw new BadRequestException('رمز عبور باید حداقل ۸ کاراکتر باشد');
|
||||
}
|
||||
data.passwordHash = await bcrypt.hash(password, 10);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.prisma.user.update({
|
||||
where: { id: targetId },
|
||||
data,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === 'P2002') {
|
||||
throw new ConflictException('این شماره موبایل یا ایمیل قبلاً ثبت شده است');
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return this.dtoOf(organizationId, targetId);
|
||||
}
|
||||
|
||||
async updateCommission(
|
||||
organizationId: string,
|
||||
actorRole: UserRole,
|
||||
|
||||
Reference in New Issue
Block a user