fix(platform): apply production hardening from audit plan
Close billing, tenancy, migration, build, and CI/CD gaps identified in the audit: wallet/gateway guards, full-UUID namespaces, idempotent migrations with base schema, stateful service stability, safer Dockerfiles/git builds, and platform chart hardening (Redis auth, RollingUpdate, backups, Swagger off). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,7 +14,11 @@ import {
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { BillingService } from './billing.service';
|
||||
import { assertStubGatewayAllowed } from './payment-gateway.util';
|
||||
import {
|
||||
assertStubGatewayAllowed,
|
||||
issueGatewayTrackingCode,
|
||||
assertGatewayTrackingCodeValid,
|
||||
} from './payment-gateway.util';
|
||||
import { AppLifecycleService } from '../lifecycle/app-lifecycle.service';
|
||||
import { ApplicationsService } from '../applications/applications.service';
|
||||
import { ChargeWalletDto, PayApplicationDto } from './dto/billing.dto';
|
||||
@@ -43,8 +47,11 @@ export class BillingWalletController {
|
||||
}
|
||||
|
||||
@Post('wallet/charge')
|
||||
@ApiOperation({ summary: 'Charge my wallet (self top-up)' })
|
||||
@ApiOperation({ summary: 'Charge my wallet (self top-up — stub gateway, dev/staging only)' })
|
||||
async chargeMyWallet(@Request() req: any, @Body() dto: ChargeWalletDto) {
|
||||
// Direct self-credit is only for environments with the stub gateway enabled.
|
||||
// In production a real payment gateway must credit wallets.
|
||||
assertStubGatewayAllowed();
|
||||
return this.billingService.chargeWallet(req.user.id, dto.amount, dto.description || 'Self top-up');
|
||||
}
|
||||
|
||||
@@ -160,7 +167,7 @@ export class BillingWalletController {
|
||||
@Body() body: { amount: number; description?: string; callbackUrl: string },
|
||||
) {
|
||||
assertStubGatewayAllowed();
|
||||
const trackingCode = `PAY-${Date.now()}-${Math.random().toString(36).substring(2, 8).toUpperCase()}`;
|
||||
const trackingCode = issueGatewayTrackingCode(req.user.id, body.amount);
|
||||
return {
|
||||
success: true,
|
||||
trackingCode,
|
||||
@@ -176,6 +183,8 @@ export class BillingWalletController {
|
||||
@Body() body: { trackingCode: string; amount: number },
|
||||
) {
|
||||
assertStubGatewayAllowed();
|
||||
// The tracking code binds user + amount at initiate time; reject tampered amounts.
|
||||
assertGatewayTrackingCodeValid(body.trackingCode, req.user.id, body.amount);
|
||||
await this.billingService.chargeWallet(
|
||||
req.user.id,
|
||||
body.amount,
|
||||
|
||||
Reference in New Issue
Block a user