Update codebase
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import { Injectable, Logger, UnauthorizedException } from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { UsersService } from '../users/users.service';
|
||||
import { User } from '../users/entities/user.entity';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
private readonly logger = new Logger('Auth');
|
||||
|
||||
constructor(
|
||||
private usersService: UsersService,
|
||||
private jwtService: JwtService,
|
||||
private config: ConfigService,
|
||||
) {}
|
||||
|
||||
private get devCode(): string {
|
||||
// رمز التطوير الثابت — يُستبدل بمحوّل SMS في P2 (راجع docs/07).
|
||||
return '1234';
|
||||
}
|
||||
|
||||
async sendOtp(tenantId: string, phone: string) {
|
||||
// وضع تطوير: الرمز ثابت ويُطبع باللوغ بلا مزوّد SMS.
|
||||
this.logger.log(`OTP for tenant=${tenantId} phone=${phone} => ${this.devCode} (dev)`);
|
||||
return {
|
||||
success: true,
|
||||
message: 'OTP sent',
|
||||
dev_code: this.config.get('auth.otpDevMode') ? this.devCode : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async verifyOtp(tenantId: string, phone: string, code: string) {
|
||||
if (code !== this.devCode) {
|
||||
throw new UnauthorizedException('Invalid OTP code');
|
||||
}
|
||||
|
||||
let user = await this.usersService.findByPhone(tenantId, phone);
|
||||
if (!user) {
|
||||
user = await this.usersService.create(tenantId, phone);
|
||||
}
|
||||
|
||||
return this.issueTokens(user, tenantId);
|
||||
}
|
||||
|
||||
async refresh(refreshToken: string) {
|
||||
let payload: any;
|
||||
try {
|
||||
payload = this.jwtService.verify(refreshToken);
|
||||
} catch {
|
||||
throw new UnauthorizedException('Invalid refresh token');
|
||||
}
|
||||
if (payload.type !== 'refresh') {
|
||||
throw new UnauthorizedException('Not a refresh token');
|
||||
}
|
||||
const user = await this.usersService.findById(payload.tenant_id, payload.sub);
|
||||
if (!user) throw new UnauthorizedException('User not found');
|
||||
return this.issueTokens(user, user.tenant_id);
|
||||
}
|
||||
|
||||
/** يصدر access + refresh معاً. */
|
||||
private issueTokens(user: User, tenantId: string) {
|
||||
const base = {
|
||||
sub: user.id,
|
||||
phone: user.phone,
|
||||
role: user.role,
|
||||
tenant_id: tenantId,
|
||||
};
|
||||
return {
|
||||
access_token: this.jwtService.sign(base),
|
||||
refresh_token: this.jwtService.sign(
|
||||
{ ...base, type: 'refresh' },
|
||||
{ expiresIn: this.config.get<string>('jwt.refreshExpires') ?? '30d' },
|
||||
),
|
||||
user,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user