diff --git a/.gitignore b/.gitignore index d361aee..a07bf24 100644 --- a/.gitignore +++ b/.gitignore @@ -17,8 +17,11 @@ # Environment Variables & Secrets .env -.env.local -.env.*.local +.env.* +*.env +*.env.* +**/.env +**/.env.* *.key *.pem diff --git a/apps/api/src/auth/auth.service.ts b/apps/api/src/auth/auth.service.ts index ed46371..92c24a3 100644 --- a/apps/api/src/auth/auth.service.ts +++ b/apps/api/src/auth/auth.service.ts @@ -208,14 +208,16 @@ export class AuthService { name, photoUrl, plan: isAdmin ? TenantPlan.ENTERPRISE : TenantPlan.FREE, + role: isAdmin ? TenantRole.ADMIN : TenantRole.USER, isActive: true, }); } } else { - // Auto-upgrade admins if they exist but are on lower plan - const isAdmin = email === 'hamzaaleghwairyeen@gmail.com' || email === 'hamzadoctor@gmail.com' || email === 'hamzaayedpython@gmail.com'; - if (isAdmin && tenant.plan !== TenantPlan.ENTERPRISE) { + // Auto-upgrade admins if they exist but are on lower plan or role + const isAdmin = email === 'hamzaayedpython@gmail.com'; + if (isAdmin && (tenant.plan !== TenantPlan.ENTERPRISE || tenant.role !== TenantRole.ADMIN)) { tenant.plan = TenantPlan.ENTERPRISE; + tenant.role = TenantRole.ADMIN; await this.tenantRepository.save(tenant); } diff --git a/apps/api/src/common/guards/admin.guard.ts b/apps/api/src/common/guards/admin.guard.ts index 8992a18..71263aa 100644 --- a/apps/api/src/common/guards/admin.guard.ts +++ b/apps/api/src/common/guards/admin.guard.ts @@ -11,8 +11,8 @@ export class AdminGuard implements CanActivate { throw new UnauthorizedException('Tenant not found in request'); } - if (tenant.plan !== TenantPlan.ENTERPRISE) { - throw new ForbiddenException('Admin access required. Your tenant plan must be ENTERPRISE.'); + if (tenant.plan !== TenantPlan.ENTERPRISE && tenant.role !== TenantRole.ADMIN) { + throw new ForbiddenException('Admin access required. Your tenant must have an ENTERPRISE plan or ADMIN clearance.'); } return true; diff --git a/apps/api/src/community/moderation.controller.ts b/apps/api/src/community/moderation.controller.ts index aad9a37..cf84493 100644 --- a/apps/api/src/community/moderation.controller.ts +++ b/apps/api/src/community/moderation.controller.ts @@ -3,10 +3,11 @@ import { ApiExcludeController } from '@nestjs/swagger'; import { CommunityService } from './community.service'; import { ReviewContributionDto } from './dto/review-contribution.dto'; import { ApiKeyGuard } from '../common/guards/api-key.guard'; +import { AdminGuard } from '../common/guards/admin.guard'; @ApiExcludeController() @Controller('v1/admin/moderation') -@UseGuards(ApiKeyGuard) +@UseGuards(ApiKeyGuard, AdminGuard) export class ModerationController { constructor(private readonly communityService: CommunityService) {} diff --git a/apps/api/src/heritage/heritage.controller.ts b/apps/api/src/heritage/heritage.controller.ts index 73bc65f..e04b6a9 100644 --- a/apps/api/src/heritage/heritage.controller.ts +++ b/apps/api/src/heritage/heritage.controller.ts @@ -54,7 +54,7 @@ export class HeritageController { }, variable: [ { key: "baseUrl", value: "https://map-saas.intaleqapp.com/api", type: "string" }, - { key: "apiKey", value: "zP9vL5mK2nQ8xR7jT4wS1yB6hG3fV0cX", type: "string" } + { key: "apiKey", value: process.env.MAP_API_KEY || "", type: "string" } ], item: [ { diff --git a/apps/api/src/maps/road-refinement.controller.ts b/apps/api/src/maps/road-refinement.controller.ts index d873a36..35f57b9 100644 --- a/apps/api/src/maps/road-refinement.controller.ts +++ b/apps/api/src/maps/road-refinement.controller.ts @@ -5,12 +5,13 @@ import { Repository, DataSource } from 'typeorm'; import { CandidateRoad } from './candidate-road.entity'; import { RoadSegmentStat } from './road-stat.entity'; import { ApiKeyGuard } from '../common/guards/api-key.guard'; +import { AdminGuard } from '../common/guards/admin.guard'; import { RedisService } from '../common/redis.service'; @ApiExcludeController() @ApiTags('map-refinement-roads') @Controller('map-refinement/roads') -@UseGuards(ApiKeyGuard) +@UseGuards(ApiKeyGuard, AdminGuard) export class RoadRefinementController { private readonly logger = new Logger(RoadRefinementController.name); diff --git a/apps/api/src/tactical/tactical.controller.ts b/apps/api/src/tactical/tactical.controller.ts index f3e8f7b..51db284 100644 --- a/apps/api/src/tactical/tactical.controller.ts +++ b/apps/api/src/tactical/tactical.controller.ts @@ -13,6 +13,7 @@ import { } from '@nestjs/common'; import { ApiExcludeController, ApiHeader, ApiOperation, ApiTags } from '@nestjs/swagger'; import { ApiKeyGuard } from '../common/guards/api-key.guard'; +import { AdminGuard } from '../common/guards/admin.guard'; import { TenantThrottlerGuard } from '../common/guards/rate-limiter.guard'; import { LineOfSightBodyDto, LineOfSightQueryDto } from './dto/line-of-sight.dto'; import { ArtilleryMissionRequestDto, SaveScenarioDto } from './dto/tactical.dto'; @@ -22,7 +23,7 @@ import { RoutingPackageService } from './routing-package.service'; @ApiExcludeController() @Controller('tactical') -@UseGuards(ApiKeyGuard, TenantThrottlerGuard) +@UseGuards(ApiKeyGuard, AdminGuard, TenantThrottlerGuard) export class TacticalController { constructor( private readonly tacticalService: TacticalService, diff --git a/apps/dashboard/src/pages/Playground.tsx b/apps/dashboard/src/pages/Playground.tsx index 4a50b5c..50d521d 100644 --- a/apps/dashboard/src/pages/Playground.tsx +++ b/apps/dashboard/src/pages/Playground.tsx @@ -11,7 +11,7 @@ import { useLanguage } from '../i18n'; type Key = { id: string; key: string; name: string }; type PlaygroundMode = 'search' | 'routing' | 'layers' | 'spatial'; -const DEFAULT_SOVEREIGN_KEY = 'zP9vL5mK2nQ8xR7jT4wS1yB6hG3fV0cX'; +const DEFAULT_SOVEREIGN_KEY = (import.meta as any).env.VITE_API_KEY || (import.meta as any).env.VITE_ADMIN_API_KEY || localStorage.getItem('map_admin_key') || localStorage.getItem('intaleq_api_key') || ''; interface RoutingResult { distanceKm?: number; diff --git a/apps/dashboard/tourism.html b/apps/dashboard/tourism.html index ad41277..a254d52 100644 --- a/apps/dashboard/tourism.html +++ b/apps/dashboard/tourism.html @@ -612,7 +612,7 @@