feat: chuẩn bị backend cho tính năng anonymous user upload ảnh không cần đăng nhập
This commit is contained in:
+3
-2
@@ -5,8 +5,8 @@ export declare class JwtStrategy extends JwtStrategy_base {
|
||||
constructor(prisma: PrismaService);
|
||||
validate(payload: any): Promise<{
|
||||
id: string;
|
||||
email: string;
|
||||
passwordHash: string;
|
||||
email: string | null;
|
||||
passwordHash: string | null;
|
||||
name: string | null;
|
||||
phone: string | null;
|
||||
address: string | null;
|
||||
@@ -14,6 +14,7 @@ export declare class JwtStrategy extends JwtStrategy_base {
|
||||
createdAt: Date;
|
||||
isAdmin: boolean;
|
||||
isBlocked: boolean;
|
||||
isAnonymous: boolean;
|
||||
}>;
|
||||
}
|
||||
export {};
|
||||
|
||||
Vendored
+48
@@ -279,6 +279,47 @@ let AuthController = class AuthController {
|
||||
this.emailService = emailService;
|
||||
this.cacheManager = cacheManager;
|
||||
}
|
||||
async convertGuestToOfficial(body) {
|
||||
const { guestId, email, password, name } = body;
|
||||
if (!guestId || !email || !password) {
|
||||
throw new common_1.BadRequestException('Vui lòng cung cấp đủ guestId, email và mật khẩu.');
|
||||
}
|
||||
const existingOfficialUser = await this.prisma.user.findFirst({
|
||||
where: {
|
||||
email: email,
|
||||
isAnonymous: false,
|
||||
},
|
||||
});
|
||||
if (existingOfficialUser) {
|
||||
throw new common_1.BadRequestException('Email này đã được một tài khoản khác sử dụng.');
|
||||
}
|
||||
const guestUser = await this.prisma.user.findUnique({
|
||||
where: { id: guestId },
|
||||
});
|
||||
if (!guestUser || !guestUser.isAnonymous) {
|
||||
throw new common_1.NotFoundException('Không tìm thấy tài khoản khách hoặc tài khoản này đã được chuyển đổi.');
|
||||
}
|
||||
const passwordHash = await bcrypt.hash(password, 10);
|
||||
const updatedUser = await this.prisma.user.update({
|
||||
where: { id: guestId },
|
||||
data: {
|
||||
email: email,
|
||||
passwordHash: passwordHash,
|
||||
name: name || guestUser.name,
|
||||
isAnonymous: false,
|
||||
},
|
||||
});
|
||||
const payload = { email: updatedUser.email, sub: updatedUser.id };
|
||||
return {
|
||||
access_token: this.jwtService.sign(payload),
|
||||
user: {
|
||||
id: updatedUser.id,
|
||||
email: updatedUser.email,
|
||||
name: updatedUser.name,
|
||||
isAdmin: updatedUser.isAdmin,
|
||||
},
|
||||
};
|
||||
}
|
||||
async getStatus() {
|
||||
const userCount = await this.prisma.user.count();
|
||||
console.log(`[Status Check] Users found: ${userCount}`);
|
||||
@@ -346,6 +387,13 @@ let AuthController = class AuthController {
|
||||
return user;
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
(0, common_1.Post)('convert-guest'),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AuthController.prototype, "convertGuestToOfficial", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('status'),
|
||||
__metadata("design:type", Function),
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Photo" DROP CONSTRAINT "Photo_tourId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Photo" ADD COLUMN "originalUrl" TEXT,
|
||||
ALTER COLUMN "tourId" DROP NOT NULL,
|
||||
ALTER COLUMN "imageUrl" DROP NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "isAnonymous" BOOLEAN NOT NULL DEFAULT false,
|
||||
ALTER COLUMN "email" DROP NOT NULL,
|
||||
ALTER COLUMN "passwordHash" DROP NOT NULL;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Photo" ADD CONSTRAINT "Photo_tourId_fkey" FOREIGN KEY ("tourId") REFERENCES "Tour"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -57,8 +57,8 @@ enum PrivacyLevel {
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
email String @unique
|
||||
passwordHash String
|
||||
email String? @unique
|
||||
passwordHash String?
|
||||
name String?
|
||||
phone String?
|
||||
address String?
|
||||
@@ -66,6 +66,7 @@ model User {
|
||||
createdAt DateTime @default(now())
|
||||
isAdmin Boolean @default(false)
|
||||
isBlocked Boolean @default(false)
|
||||
isAnonymous Boolean @default(false)
|
||||
|
||||
createdTours Tour[] @relation("TourCreator")
|
||||
tourParticipations TourParticipant[]
|
||||
|
||||
@@ -262,6 +262,61 @@ class AuthController {
|
||||
@Inject(CACHE_MANAGER) private cacheManager: Cache
|
||||
) {}
|
||||
|
||||
@Post('convert-guest')
|
||||
async convertGuestToOfficial(@Body() body: any) {
|
||||
const { guestId, email, password, name } = body;
|
||||
|
||||
if (!guestId || !email || !password) {
|
||||
throw new BadRequestException('Vui lòng cung cấp đủ guestId, email và mật khẩu.');
|
||||
}
|
||||
|
||||
// 1. Kiểm tra xem email đã tồn tại với một tài khoản chính thức khác chưa
|
||||
const existingOfficialUser = await this.prisma.user.findFirst({
|
||||
where: {
|
||||
email: email,
|
||||
isAnonymous: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (existingOfficialUser) {
|
||||
throw new BadRequestException('Email này đã được một tài khoản khác sử dụng.');
|
||||
}
|
||||
|
||||
// 2. Tìm tài khoản khách
|
||||
const guestUser = await this.prisma.user.findUnique({
|
||||
where: { id: guestId },
|
||||
});
|
||||
|
||||
if (!guestUser || !guestUser.isAnonymous) {
|
||||
throw new NotFoundException('Không tìm thấy tài khoản khách hoặc tài khoản này đã được chuyển đổi.');
|
||||
}
|
||||
|
||||
// 3. Mã hóa mật khẩu và cập nhật người dùng
|
||||
const passwordHash = await bcrypt.hash(password, 10);
|
||||
|
||||
const updatedUser = await this.prisma.user.update({
|
||||
where: { id: guestId },
|
||||
data: {
|
||||
email: email,
|
||||
passwordHash: passwordHash,
|
||||
name: name || guestUser.name, // Cập nhật tên mới nếu có, nếu không giữ lại tên ẩn danh cũ
|
||||
isAnonymous: false, // Đánh dấu đây là tài khoản chính thức
|
||||
},
|
||||
});
|
||||
|
||||
// 4. Tạo và trả về token để người dùng đăng nhập ngay lập tức
|
||||
const payload = { email: updatedUser.email, sub: updatedUser.id };
|
||||
return {
|
||||
access_token: this.jwtService.sign(payload),
|
||||
user: {
|
||||
id: updatedUser.id,
|
||||
email: updatedUser.email,
|
||||
name: updatedUser.name,
|
||||
isAdmin: updatedUser.isAdmin,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@Get('status')
|
||||
async getStatus() {
|
||||
const userCount = await this.prisma.user.count();
|
||||
|
||||
Reference in New Issue
Block a user