2026-09-15 14:10:52 +03:30
|
|
|
import {
|
2026-10-15 10:48:30 +03:30
|
|
|
BadRequestException,
|
2026-09-15 14:10:52 +03:30
|
|
|
Body,
|
|
|
|
|
Controller,
|
|
|
|
|
Delete,
|
|
|
|
|
Get,
|
|
|
|
|
Patch,
|
|
|
|
|
Post,
|
|
|
|
|
StreamableFile,
|
|
|
|
|
UploadedFile,
|
|
|
|
|
UseGuards,
|
|
|
|
|
UseInterceptors,
|
|
|
|
|
} from '@nestjs/common';
|
|
|
|
|
import { FileInterceptor } from '@nestjs/platform-express';
|
|
|
|
|
import { memoryStorage } from 'multer';
|
2026-08-29 21:06:30 +03:30
|
|
|
import { AuthService } from './auth.service';
|
2026-09-05 00:47:33 +03:30
|
|
|
import {
|
|
|
|
|
LoginDto,
|
2026-09-05 01:37:15 +03:30
|
|
|
LoginOtpRequestDto,
|
|
|
|
|
LoginOtpVerifyDto,
|
2026-09-05 00:47:33 +03:30
|
|
|
RegisterOrganizationDto,
|
|
|
|
|
RegisterVerifyOtpDto,
|
2026-09-15 21:37:58 +03:30
|
|
|
SelectOrganizationDto,
|
|
|
|
|
SwitchOrganizationDto,
|
2026-09-15 14:10:52 +03:30
|
|
|
UpdateProfileDto,
|
2026-09-05 00:47:33 +03:30
|
|
|
} from './dto';
|
2026-08-29 21:06:30 +03:30
|
|
|
import { JwtAuthGuard } from './jwt-auth.guard';
|
|
|
|
|
import { CurrentUser } from './current-user.decorator';
|
|
|
|
|
|
2026-09-15 14:10:52 +03:30
|
|
|
type AuthActor = { userId: string; organizationId: string };
|
|
|
|
|
|
2026-08-29 21:06:30 +03:30
|
|
|
@Controller('auth')
|
|
|
|
|
export class AuthController {
|
|
|
|
|
constructor(private readonly authService: AuthService) {}
|
|
|
|
|
|
|
|
|
|
@Post('register')
|
|
|
|
|
register(@Body() dto: RegisterOrganizationDto) {
|
2026-09-05 00:47:33 +03:30
|
|
|
return this.authService.startRegister(dto);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Post('register/verify')
|
|
|
|
|
registerVerify(@Body() dto: RegisterVerifyOtpDto) {
|
|
|
|
|
return this.authService.verifyRegister(dto);
|
2026-08-29 21:06:30 +03:30
|
|
|
}
|
|
|
|
|
|
2026-09-05 01:37:15 +03:30
|
|
|
/** ورود با رمز (بدون OTP) */
|
2026-08-29 21:06:30 +03:30
|
|
|
@Post('login')
|
|
|
|
|
login(@Body() dto: LoginDto) {
|
2026-09-05 01:37:15 +03:30
|
|
|
return this.authService.loginWithPassword(dto);
|
2026-09-05 00:47:33 +03:30
|
|
|
}
|
|
|
|
|
|
2026-09-05 01:37:15 +03:30
|
|
|
/** درخواست کد ورود با موبایل */
|
|
|
|
|
@Post('login/otp')
|
|
|
|
|
loginOtpRequest(@Body() dto: LoginOtpRequestDto) {
|
|
|
|
|
return this.authService.requestLoginOtp(dto);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** تأیید کد ورود با موبایل */
|
|
|
|
|
@Post('login/otp/verify')
|
|
|
|
|
loginOtpVerify(@Body() dto: LoginOtpVerifyDto) {
|
|
|
|
|
return this.authService.verifyLoginOtp(dto);
|
2026-08-29 21:06:30 +03:30
|
|
|
}
|
|
|
|
|
|
2026-09-15 21:37:58 +03:30
|
|
|
@Post('select-organization')
|
|
|
|
|
selectOrganization(@Body() dto: SelectOrganizationDto) {
|
|
|
|
|
return this.authService.selectOrganization(dto.selectionToken, dto.organizationId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
|
|
|
@Post('switch-organization')
|
|
|
|
|
switchOrganization(
|
|
|
|
|
@CurrentUser() user: AuthActor,
|
|
|
|
|
@Body() dto: SwitchOrganizationDto,
|
|
|
|
|
) {
|
|
|
|
|
return this.authService.switchOrganization(user.userId, dto.organizationId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
|
|
|
@Get('organizations')
|
|
|
|
|
listOrganizations(@CurrentUser() user: AuthActor) {
|
|
|
|
|
return this.authService.listMyOrganizations(user.userId);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-29 21:06:30 +03:30
|
|
|
@UseGuards(JwtAuthGuard)
|
|
|
|
|
@Get('me')
|
2026-09-15 14:10:52 +03:30
|
|
|
me(@CurrentUser() user: AuthActor) {
|
2026-09-15 21:37:58 +03:30
|
|
|
return this.authService.me(user.userId, user.organizationId);
|
2026-08-29 21:06:30 +03:30
|
|
|
}
|
2026-09-15 14:10:52 +03:30
|
|
|
|
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
|
|
|
@Patch('me')
|
|
|
|
|
updateMe(@CurrentUser() user: AuthActor, @Body() dto: UpdateProfileDto) {
|
2026-09-15 21:37:58 +03:30
|
|
|
return this.authService.updateMe(user.userId, user.organizationId, dto);
|
2026-09-15 14:10:52 +03:30
|
|
|
}
|
|
|
|
|
|
2026-10-15 10:48:30 +03:30
|
|
|
@UseGuards(JwtAuthGuard)
|
|
|
|
|
@Patch('me/prior-archive')
|
|
|
|
|
setPriorLens(
|
|
|
|
|
@CurrentUser() user: AuthActor,
|
|
|
|
|
@Body() body: { lens?: string },
|
|
|
|
|
) {
|
|
|
|
|
if (body.lens !== 'archive' && body.lens !== 'current') {
|
|
|
|
|
throw new BadRequestException('حالت بایگانی نامعتبر است');
|
|
|
|
|
}
|
|
|
|
|
return this.authService.setPriorLens(user.userId, user.organizationId, body.lens);
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-15 14:10:52 +03:30
|
|
|
/** عکس پروفایل کاربر جاری */
|
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
|
|
|
@Get('me/avatar')
|
|
|
|
|
async avatar(@CurrentUser() user: AuthActor) {
|
|
|
|
|
const file = await this.authService.openAvatar(user.userId);
|
|
|
|
|
return new StreamableFile(file.stream, { type: file.mimeType });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
|
|
|
@Post('me/avatar')
|
|
|
|
|
@UseInterceptors(
|
|
|
|
|
FileInterceptor('file', {
|
|
|
|
|
storage: memoryStorage(),
|
|
|
|
|
limits: { fileSize: 2 * 1024 * 1024 },
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
uploadAvatar(
|
|
|
|
|
@CurrentUser() user: AuthActor,
|
|
|
|
|
@UploadedFile() file: Express.Multer.File,
|
|
|
|
|
) {
|
|
|
|
|
return this.authService.saveAvatar(user.userId, user.organizationId, file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
|
|
|
@Delete('me/avatar')
|
|
|
|
|
removeAvatar(@CurrentUser() user: AuthActor) {
|
2026-09-15 21:37:58 +03:30
|
|
|
return this.authService.removeAvatar(user.userId, user.organizationId);
|
2026-09-15 14:10:52 +03:30
|
|
|
}
|
2026-08-29 21:06:30 +03:30
|
|
|
}
|