Generate random platform subdomains for apps without custom domains.
Assign unpredictable subdomains on create when no custom domain is set, and update deploy UI CNAME hints to reference the app Platform Domain after creation. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -30,6 +30,33 @@ export class ApplicationsService {
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
private toDnsLabel(value: string): string {
|
||||
return (value || '')
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9-]/g, '-')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-|-$/g, '')
|
||||
.slice(0, 63);
|
||||
}
|
||||
|
||||
private async generateRandomSubdomain(baseLabel: string): Promise<string> {
|
||||
const base = this.toDnsLabel(baseLabel) || 'app';
|
||||
const suffixLenBytes = 5; // 10 hex chars
|
||||
const suffixLen = suffixLenBytes * 2;
|
||||
|
||||
for (let attempt = 0; attempt < 10; attempt++) {
|
||||
const suffix = crypto.randomBytes(suffixLenBytes).toString('hex'); // [0-9a-f]
|
||||
const maxBaseLen = 63 - 1 - suffixLen; // base + '-' + suffix
|
||||
const truncatedBase = base.slice(0, Math.max(1, maxBaseLen)).replace(/-+$/g, '');
|
||||
const candidate = `${truncatedBase}-${suffix}`;
|
||||
|
||||
const exists = await this.appsRepository.findOne({ where: { subdomain: candidate } });
|
||||
if (!exists) return candidate;
|
||||
}
|
||||
|
||||
throw new BadRequestException('Failed to generate a unique subdomain. Please try again.');
|
||||
}
|
||||
|
||||
async create(userId: string, dto: CreateApplicationDto, userRole?: string): Promise<Application> {
|
||||
dto = normalizeCreateApplicationDto(dto);
|
||||
const productType = dto.productType ?? ProductType.APPLICATION;
|
||||
@@ -83,7 +110,10 @@ export class ApplicationsService {
|
||||
? 80
|
||||
: 3000;
|
||||
|
||||
const subdomain = `${dto.name}-${userId.split('-')[0]}`;
|
||||
const baseLabel = dto.name;
|
||||
const subdomain = customDomain
|
||||
? `${this.toDnsLabel(baseLabel)}-${this.toDnsLabel(userId.split('-')[0])}`
|
||||
: await this.generateRandomSubdomain(baseLabel);
|
||||
const platformDomain = this.configService.get('platform.domain') || 'apps.cloudhost.ir';
|
||||
|
||||
const app = this.appsRepository.create({
|
||||
|
||||
Reference in New Issue
Block a user