diff --git a/backend/services/identity-service/prisma/migrations/20251215000000_add_user_totp/migration.sql b/backend/services/identity-service/prisma/migrations/20251215000000_add_user_totp/migration.sql new file mode 100644 index 00000000..21f064b4 --- /dev/null +++ b/backend/services/identity-service/prisma/migrations/20251215000000_add_user_totp/migration.sql @@ -0,0 +1,21 @@ +-- CreateTable: user_totp +-- TOTP 二次验证表,用于提现、转账等敏感操作 + +CREATE TABLE "user_totp" ( + "id" BIGSERIAL NOT NULL, + "user_id" BIGINT NOT NULL, + "encrypted_secret" VARCHAR(100) NOT NULL, + "is_enabled" BOOLEAN NOT NULL DEFAULT false, + "is_verified" BOOLEAN NOT NULL DEFAULT false, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "enabled_at" TIMESTAMP(3), + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "user_totp_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "user_totp_user_id_key" ON "user_totp"("user_id"); + +-- CreateIndex +CREATE INDEX "idx_totp_user" ON "user_totp"("user_id"); diff --git a/backend/services/identity-service/src/shared/decorators/index.ts b/backend/services/identity-service/src/shared/decorators/index.ts index 1b66c86a..82016787 100644 --- a/backend/services/identity-service/src/shared/decorators/index.ts +++ b/backend/services/identity-service/src/shared/decorators/index.ts @@ -1,6 +1,12 @@ import { createParamDecorator, ExecutionContext, SetMetadata } from '@nestjs/common'; import { IS_PUBLIC_KEY } from '../guards/jwt-auth.guard'; +export interface CurrentUserPayload { + userId: string; + accountSequence: string; + deviceId: string; +} + export const CurrentUser = createParamDecorator( (data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); diff --git a/backend/services/wallet-service/package.json b/backend/services/wallet-service/package.json index 0475a3ab..c700bc74 100644 --- a/backend/services/wallet-service/package.json +++ b/backend/services/wallet-service/package.json @@ -38,6 +38,7 @@ "@nestjs/schedule": "^4.1.2", "@nestjs/swagger": "^7.1.17", "@prisma/client": "^5.7.0", + "axios": "^1.13.2", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "decimal.js": "^10.4.3", diff --git a/backend/services/wallet-service/src/application/event-handlers/withdrawal-status.handler.ts b/backend/services/wallet-service/src/application/event-handlers/withdrawal-status.handler.ts index 052c26c9..b8fb3a98 100644 --- a/backend/services/wallet-service/src/application/event-handlers/withdrawal-status.handler.ts +++ b/backend/services/wallet-service/src/application/event-handlers/withdrawal-status.handler.ts @@ -103,12 +103,12 @@ export class WithdrawalStatusHandler implements OnModuleInit { // Refund frozen funds back to available balance if needed if (order.needsUnfreeze()) { - const wallet = await this.walletRepo.findByUserId(order.userId.toString()); + const wallet = await this.walletRepo.findByUserId(order.userId.value); if (wallet) { // Unfreeze the amount (add back to available balance) - wallet.unfreezeUsdt(order.amount.asNumber); + wallet.unfreeze(order.amount); await this.walletRepo.save(wallet); - this.logger.log(`[FAILED] Refunded ${order.amount.asNumber} USDT to user ${order.userId}`); + this.logger.log(`[FAILED] Refunded ${order.amount.value} USDT to user ${order.userId}`); } }