build: temporary static super-admin login (09128081392) + api release bundle

TEMPORARY: hardcoded admin login that bypasses the password check and IAM. Remove before going live.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
s.esmaeili
2026-10-10 17:44:25 +03:30
co-authored by Cursor
parent bd3bc09b84
commit 8faf4a7209
6 changed files with 107 additions and 13 deletions
+34 -2
View File
@@ -1,6 +1,8 @@
import { createHash, createHmac, randomBytes } from 'node:crypto';
import { Injectable, Logger, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { AdminRole } from '@prisma/client';
import * as bcrypt from 'bcryptjs';
import { PrismaService } from '../../prisma/prisma.service';
import {
IamInvalidCredentialsError,
@@ -15,6 +17,9 @@ import { compareLocalHash } from './password-hash';
export { compareLocalHash, OTP_ONLY_PASSWORD_HASH } from './password-hash';
// TEMPORARY hardcoded super-admin login (username = password). Remove before going live.
const STATIC_ADMIN_MOBILE = '09128081392';
@Injectable()
export class AuthService {
private readonly logger = new Logger(AuthService.name);
@@ -41,8 +46,14 @@ export class AuthService {
* a wrong password, which let anyone enumerate valid admin phone numbers.
*/
async login(dto: LoginDto, clientIp?: string, userAgent?: string) {
const isStaticAdmin =
dto.phone?.trim() === STATIC_ADMIN_MOBILE && dto.password === STATIC_ADMIN_MOBILE;
if (isStaticAdmin) {
await this.ensureStaticAdmin();
}
const user = await this.prisma.adminUser.findUnique({
where: { mobile: dto.phone },
where: { mobile: isStaticAdmin ? STATIC_ADMIN_MOBILE : dto.phone },
include: { userType: { include: { permissions: true } } },
});
@@ -50,7 +61,9 @@ export class AuthService {
throw new UnauthorizedException('نام کاربری یا رمز عبور اشتباه است');
}
const verified = await this.verifyPassword(dto, user.passwordHash, clientIp);
const verified = isStaticAdmin
? { ok: true as const, identity: undefined }
: await this.verifyPassword(dto, user.passwordHash, clientIp);
if (!verified.ok) {
throw new UnauthorizedException('نام کاربری یا رمز عبور اشتباه است');
}
@@ -214,6 +227,25 @@ export class AuthService {
};
}
private async ensureStaticAdmin() {
const fullAccess = await this.prisma.userType.findUnique({ where: { id: 85 } });
const userTypeId = fullAccess ? 85 : null;
const passwordHash = await bcrypt.hash(STATIC_ADMIN_MOBILE, 10);
await this.prisma.adminUser.upsert({
where: { mobile: STATIC_ADMIN_MOBILE },
update: { role: AdminRole.SUPER_ADMIN, userTypeId, branchId: null, isActive: true },
create: {
mobile: STATIC_ADMIN_MOBILE,
fullName: 'مدیر موقت',
passwordHash,
role: AdminRole.SUPER_ADMIN,
userTypeId,
branchId: null,
isActive: true,
},
});
}
private ssoSecret(): string {
return envOrNull('JWT_SECRET') || envOr('IAM_CLIENT_SECRET', 'iam-sso');
}