From 4397b07d2f8c14388101e1ea5c5c62bd09662e76 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Thu, 16 Jul 2026 16:14:30 +0300 Subject: [PATCH] fix(auth): resolve tenant slug to UUID before user queries --- backend/src/modules/auth/auth.module.ts | 2 ++ backend/src/modules/auth/auth.service.ts | 14 +++++++++++++- backend/src/modules/tenants/tenants.service.ts | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/backend/src/modules/auth/auth.module.ts b/backend/src/modules/auth/auth.module.ts index c1ce585..18ef676 100644 --- a/backend/src/modules/auth/auth.module.ts +++ b/backend/src/modules/auth/auth.module.ts @@ -5,11 +5,13 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { AuthService } from './auth.service'; import { AuthController } from './auth.controller'; import { UsersModule } from '../users/users.module'; +import { TenantsModule } from '../tenants/tenants.module'; import { JwtStrategy } from './strategies/jwt.strategy'; @Module({ imports: [ UsersModule, + TenantsModule, PassportModule, JwtModule.registerAsync({ imports: [ConfigModule], diff --git a/backend/src/modules/auth/auth.service.ts b/backend/src/modules/auth/auth.service.ts index 851e996..565a98d 100644 --- a/backend/src/modules/auth/auth.service.ts +++ b/backend/src/modules/auth/auth.service.ts @@ -3,6 +3,7 @@ import { JwtService } from '@nestjs/jwt'; import { ConfigService } from '@nestjs/config'; import { UsersService } from '../users/users.service'; import { User } from '../users/entities/user.entity'; +import { TenantsService } from '../tenants/tenants.service'; @Injectable() export class AuthService { @@ -12,8 +13,16 @@ export class AuthService { private usersService: UsersService, private jwtService: JwtService, private config: ConfigService, + private tenantsService: TenantsService, ) {} + /** يحوّل الـ slug القادم من الهيدر إلى UUID المستأجر (tenant_id). */ + private async resolveTenantId(tenantSlugOrId: string): Promise { + const tenant = await this.tenantsService.resolve(tenantSlugOrId); + if (!tenant) throw new UnauthorizedException('Unknown tenant'); + return tenant.id; + } + private get devCode(): string { // رمز التطوير الثابت — يُستبدل بمحوّل SMS في P2 (راجع docs/07). return '1234'; @@ -29,11 +38,14 @@ export class AuthService { }; } - async verifyOtp(tenantId: string, phone: string, code: string) { + async verifyOtp(tenantSlug: string, phone: string, code: string) { if (code !== this.devCode) { throw new UnauthorizedException('Invalid OTP code'); } + // الهيدر يحمل slug — نحوّله لـ UUID قبل أي استعلام على tenant_id. + const tenantId = await this.resolveTenantId(tenantSlug); + let user = await this.usersService.findByPhone(tenantId, phone); if (!user) { user = await this.usersService.create(tenantId, phone); diff --git a/backend/src/modules/tenants/tenants.service.ts b/backend/src/modules/tenants/tenants.service.ts index 6af73a6..90e30b3 100644 --- a/backend/src/modules/tenants/tenants.service.ts +++ b/backend/src/modules/tenants/tenants.service.ts @@ -18,6 +18,23 @@ export class TenantsService { return this.repo.findOne({ where: { slug } }); } + private static readonly UUID_RE = + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + + /** + * يحوّل معرّف المستأجر القادم من الهيدر (slug مثل "siro" أو UUID) إلى سجل المستأجر. + * التطبيقات ترسل الـ slug؛ نحوّله للـ UUID المستخدَم في tenant_id (راجع docs/06). + */ + async resolve(idOrSlug: string): Promise { + if (!idOrSlug) return null; + const bySlug = await this.findBySlug(idOrSlug); + if (bySlug) return bySlug; + if (TenantsService.UUID_RE.test(idOrSlug)) { + return this.repo.findOne({ where: { id: idOrSlug } }); + } + return null; + } + create(data: Partial): Promise { return this.repo.save(this.repo.create(data)); }