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:
@@ -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');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user