186 lines
8.5 KiB
TypeScript
186 lines
8.5 KiB
TypeScript
import { Body, Controller, Get, Param, Patch, Post, UseInterceptors } from "@nestjs/common";
|
||
import { ApiHeader, ApiOperation, ApiTags } from "@nestjs/swagger";
|
||
|
||
import { UpdateBusinessDomainDto } from "./DTO/business-domain.dto";
|
||
import { BusinessSlugParamDto } from "./DTO/business-slug-param.dto";
|
||
import { UpdateBusinessSettingsDto } from "./DTO/update-business-settings.dto";
|
||
import { Business } from "./entities/business.entity";
|
||
import { BusinessesService } from "./services/businesses.service";
|
||
import { DomainVerificationService } from "./services/domain-verification.service";
|
||
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||
import { BusinessDec } from "../../common/decorators/business.decorator";
|
||
import { BusinessInterceptor } from "../../core/interceptors/business.interceptor";
|
||
|
||
@Controller("business")
|
||
@ApiHeader({ name: "x-business-id", description: "Business ID" })
|
||
@ApiTags("Business")
|
||
@UseInterceptors(BusinessInterceptor)
|
||
export class BusinessesController {
|
||
constructor(
|
||
private readonly businessesService: BusinessesService,
|
||
private readonly domainVerificationService: DomainVerificationService,
|
||
) {}
|
||
|
||
@Get("slug/:slug")
|
||
@ApiOperation({ summary: "Get business by slug" })
|
||
getBusinessBySlug(@Param() params: BusinessSlugParamDto) {
|
||
return this.businessesService.getBusinessBySlug(params.slug);
|
||
}
|
||
|
||
@Patch("settings")
|
||
@ApiOperation({ summary: "Update business settings" })
|
||
@AuthGuards()
|
||
updateBusinessSettings(@BusinessDec("id") businessId: string, @Body() settingsDto: UpdateBusinessSettingsDto) {
|
||
return this.businessesService.updateBusinessSettings(businessId, settingsDto);
|
||
}
|
||
|
||
@Get("settings")
|
||
@ApiOperation({ summary: "Get business settings" })
|
||
@AuthGuards()
|
||
getBusinessSettings(@BusinessDec("id") businessId: string) {
|
||
return this.businessesService.getBusinessSettings(businessId);
|
||
}
|
||
|
||
// Domain management endpoints - simplified flow
|
||
@Post("domain")
|
||
@ApiOperation({ summary: "Set/update business domain and get verification instructions" })
|
||
@AuthGuards()
|
||
setDomain(@BusinessDec() business: Business, @Body() domainDto: UpdateBusinessDomainDto) {
|
||
return this.domainVerificationService.setDomain(business.id, domainDto);
|
||
}
|
||
|
||
@Post("domain/verify")
|
||
@ApiOperation({ summary: "Verify domain ownership and connection" })
|
||
@AuthGuards()
|
||
verifyDomain(@BusinessDec() business: Business) {
|
||
return this.domainVerificationService.verifyDomain(business.id);
|
||
}
|
||
|
||
@Get("domain/status")
|
||
@ApiOperation({ summary: "Get current domain status" })
|
||
@AuthGuards()
|
||
getDomainStatus(@BusinessDec() business: Business) {
|
||
return this.domainVerificationService.getDomainStatus(business.id);
|
||
}
|
||
|
||
@Post("domain/update-dns-records")
|
||
@ApiOperation({ summary: "Get detailed instructions for updating DNS records" })
|
||
@AuthGuards()
|
||
getDetailedDnsInstructions(@BusinessDec() business: Business) {
|
||
// This endpoint provides detailed DNS setup instructions for various DNS providers
|
||
if (!business.domain) {
|
||
return {
|
||
success: false,
|
||
message: "No domain configured for this business",
|
||
};
|
||
}
|
||
|
||
return {
|
||
success: true,
|
||
domain: business.domain,
|
||
instructions: {
|
||
title: "راهنمای تنظیم رکوردهای DNS برای دامنه شما",
|
||
description: "برای اتصال دامنه خود به سرویس دیزون، لطفا یکی از روشهای زیر را انتخاب کنید:",
|
||
methods: [
|
||
{
|
||
title: "روش A: استفاده از رکورد A (آدرس IP)",
|
||
description: "این روش برای همه ارائهدهندگان DNS کار میکند و برای دامنه اصلی مناسب است.",
|
||
steps: [
|
||
"۱. وارد پنل مدیریت DNS خود شوید",
|
||
"۲. یک رکورد A جدید ایجاد کنید",
|
||
"۳. در فیلد Host یا Name، @ را وارد کنید (برای دامنه اصلی)",
|
||
`۴. در فیلد Value یا Points to، آدرس IP سرور ما را وارد کنید: 194.5.192.20`,
|
||
"۵. TTL را روی 3600 (یک ساعت) یا کمترین مقدار ممکن تنظیم کنید",
|
||
"۶. تغییرات را ذخیره کنید",
|
||
],
|
||
},
|
||
{
|
||
title: "روش B: استفاده از رکورد CNAME (نام مستعار)",
|
||
description: "این روش برای زیردامنهها مانند www توصیه میشود.",
|
||
steps: [
|
||
"۱. وارد پنل مدیریت DNS خود شوید",
|
||
"۲. یک رکورد CNAME جدید ایجاد کنید",
|
||
"۳. در فیلد Host یا Name، www را وارد کنید (یا زیردامنه دلخواه)",
|
||
`۴. در فیلد Value یا Points to، آدرس سرور ما را وارد کنید: app.dzone.danakcorp.com`,
|
||
"۵. TTL را روی 3600 (یک ساعت) یا کمترین مقدار ممکن تنظیم کنید",
|
||
"۶. تغییرات را ذخیره کنید",
|
||
],
|
||
note: "توجه: برخی ارائهدهندگان DNS اجازه استفاده از CNAME برای دامنه اصلی (@) را نمیدهند. در این صورت از روش A استفاده کنید.",
|
||
},
|
||
],
|
||
providerSpecific: [
|
||
{
|
||
provider: "Cloudflare",
|
||
instructions: [
|
||
"۱. حالت ابری (پروکسی) را خاموش کنید و فقط از DNS استفاده کنید",
|
||
"۲. برای دامنه اصلی (@) از رکورد A استفاده کنید",
|
||
"۳. برای زیردامنه www از رکورد CNAME استفاده کنید",
|
||
],
|
||
},
|
||
{
|
||
provider: "cPanel",
|
||
instructions: [
|
||
"۱. به بخش Zone Editor بروید",
|
||
"۲. روی دامنه خود کلیک کنید",
|
||
"۳. برای دامنه اصلی، رکورد A با مقدار 194.5.192.20 اضافه کنید",
|
||
"۴. برای www، رکورد CNAME با مقدار app.dzone.danakcorp.com اضافه کنید",
|
||
],
|
||
},
|
||
{
|
||
provider: "سایر ارائهدهندگان",
|
||
instructions: [
|
||
"اگر نمیتوانید CNAME برای دامنه اصلی تنظیم کنید، از رکورد A استفاده کنید",
|
||
"برخی ارائهدهندگان از رکوردهای ANAME یا ALIAS برای دامنه اصلی پشتیبانی میکنند",
|
||
"اگر در تنظیم رکوردها مشکل دارید، با پشتیبانی ارائهدهنده DNS خود تماس بگیرید",
|
||
],
|
||
},
|
||
],
|
||
troubleshooting: [
|
||
"- تغییرات DNS ممکن است بین ۱۵ دقیقه تا ۴۸ ساعت طول بکشد تا در سراسر اینترنت منتشر شود",
|
||
"- اگر پس از ۴۸ ساعت هنوز مشکل دارید، مطمئن شوید که رکوردها را درست تنظیم کردهاید",
|
||
"- برای بررسی وضعیت رکوردهای DNS خود میتوانید از ابزارهایی مانند dnschecker.org استفاده کنید",
|
||
"- اگر همچنان مشکل دارید، با پشتیبانی ما تماس بگیرید",
|
||
],
|
||
},
|
||
};
|
||
}
|
||
|
||
@Post("domain/configure-caprover")
|
||
@ApiOperation({ summary: "Manually configure domain in Caprover (Admin use only)" })
|
||
@AuthGuards()
|
||
async manualCaproverConfig(@BusinessDec() business: Business) {
|
||
if (!business.domain) {
|
||
return {
|
||
success: false,
|
||
message: "No domain configured for this business",
|
||
};
|
||
}
|
||
|
||
if (!business.isDomainVerified) {
|
||
return {
|
||
success: false,
|
||
message: "Domain must be verified before configuring in Caprover",
|
||
domain: business.domain,
|
||
};
|
||
}
|
||
|
||
try {
|
||
const result = await this.domainVerificationService.configureCaproverDomain(business.domain);
|
||
|
||
return {
|
||
success: result,
|
||
message: result
|
||
? `Domain ${business.domain} successfully configured in Caprover`
|
||
: `Failed to configure domain ${business.domain} in Caprover`,
|
||
domain: business.domain,
|
||
};
|
||
} catch (error: unknown) {
|
||
return {
|
||
success: false,
|
||
message: `Error configuring domain in Caprover: ${error instanceof Error ? error.message : String(error)}`,
|
||
domain: business.domain,
|
||
};
|
||
}
|
||
}
|
||
}
|