update: domain service
This commit is contained in:
@@ -60,15 +60,15 @@ export class AuthService {
|
|||||||
try {
|
try {
|
||||||
await entityManager.begin();
|
await entityManager.begin();
|
||||||
//
|
//
|
||||||
const isValid = await this.otpService.verifyOtp(phone, code, "REGISTER");
|
|
||||||
|
|
||||||
if (!isValid) throw new BadRequestException(AuthMessage.INVALID_OTP);
|
|
||||||
|
|
||||||
await this.otpService.delOtpFormCache(phone, "REGISTER");
|
|
||||||
const hashedPassword = await this.passwordService.hashPassword(completeRegistrationDto.password);
|
const hashedPassword = await this.passwordService.hashPassword(completeRegistrationDto.password);
|
||||||
|
|
||||||
const user = await this.usersService.createUser(completeRegistrationDto, hashedPassword, business, entityManager);
|
const user = await this.usersService.createUser(completeRegistrationDto, hashedPassword, business, entityManager);
|
||||||
|
|
||||||
|
const isValid = await this.otpService.verifyOtp(phone, code, "REGISTER");
|
||||||
|
if (!isValid) throw new BadRequestException(AuthMessage.INVALID_OTP);
|
||||||
|
await this.otpService.delOtpFormCache(phone, "REGISTER");
|
||||||
|
|
||||||
const tokens = await this.tokensService.generateTokens(user, entityManager);
|
const tokens = await this.tokensService.generateTokens(user, entityManager);
|
||||||
|
|
||||||
await entityManager.commit();
|
await entityManager.commit();
|
||||||
@@ -113,8 +113,9 @@ export class AuthService {
|
|||||||
//****************** */
|
//****************** */
|
||||||
//****************** */
|
//****************** */
|
||||||
|
|
||||||
async requestLoginOtp(requestOtpDto: RequestOtpDto, businessId: string, isAdmin: boolean = false) {
|
async requestLoginOtp(requestOtpDto: RequestOtpDto, businessId: string) {
|
||||||
const { phone } = requestOtpDto;
|
const { phone } = requestOtpDto;
|
||||||
|
|
||||||
const user = await this.usersService.findOneWithPhone(phone, businessId);
|
const user = await this.usersService.findOneWithPhone(phone, businessId);
|
||||||
if (!user) throw new BadRequestException(AuthMessage.PHONE_NOT_FOUND);
|
if (!user) throw new BadRequestException(AuthMessage.PHONE_NOT_FOUND);
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ export class AuthService {
|
|||||||
|
|
||||||
const isUserAdmin = this.checkUserIsAdmin(user.role);
|
const isUserAdmin = this.checkUserIsAdmin(user.role);
|
||||||
|
|
||||||
if (isAdmin && !isUserAdmin) throw new BadRequestException(AuthMessage.NOT_ADMIN);
|
if (isUserAdmin) throw new BadRequestException(AuthMessage.NOT_ADMIN);
|
||||||
|
|
||||||
const existCode = await this.otpService.checkExistOtp(phone, "LOGIN");
|
const existCode = await this.otpService.checkExistOtp(phone, "LOGIN");
|
||||||
if (existCode) {
|
if (existCode) {
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
import { IsEnum, IsNotEmpty, IsOptional, IsString, Matches } from "class-validator";
|
import { IsNotEmpty, IsOptional, IsString, Matches } from "class-validator";
|
||||||
|
|
||||||
export enum DomainVerificationMethod {
|
|
||||||
DNS_TXT = "DNS_TXT",
|
|
||||||
FILE = "FILE",
|
|
||||||
META_TAG = "META_TAG",
|
|
||||||
}
|
|
||||||
|
|
||||||
export class UpdateBusinessDomainDto {
|
export class UpdateBusinessDomainDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@@ -14,10 +8,6 @@ export class UpdateBusinessDomainDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class VerifyDomainDto {
|
export class VerifyDomainDto {
|
||||||
@IsNotEmpty()
|
|
||||||
@IsEnum(DomainVerificationMethod)
|
|
||||||
method: DomainVerificationMethod;
|
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
businessId?: string;
|
businessId?: string;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Body, Controller, Get, Param, Post } from "@nestjs/common";
|
import { Body, Controller, Get, Param, Post } from "@nestjs/common";
|
||||||
import { ApiOperation } from "@nestjs/swagger";
|
import { ApiOperation } from "@nestjs/swagger";
|
||||||
|
|
||||||
import { UpdateBusinessDomainDto, VerifyDomainDto } from "./DTO/business-domain.dto";
|
import { UpdateBusinessDomainDto } from "./DTO/business-domain.dto";
|
||||||
import { BusinessSlugParamDto } from "./DTO/business-slug-param.dto";
|
import { BusinessSlugParamDto } from "./DTO/business-slug-param.dto";
|
||||||
import { Business } from "./entities/business.entity";
|
import { Business } from "./entities/business.entity";
|
||||||
import { BusinessesService } from "./services/businesses.service";
|
import { BusinessesService } from "./services/businesses.service";
|
||||||
@@ -22,7 +22,6 @@ export class BusinessesController {
|
|||||||
return this.businessesService.getBusinessBySlug(params.slug);
|
return this.businessesService.getBusinessBySlug(params.slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Domain management endpoints
|
|
||||||
@Post("domain")
|
@Post("domain")
|
||||||
@ApiOperation({ summary: "Update business domain" })
|
@ApiOperation({ summary: "Update business domain" })
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@@ -40,8 +39,8 @@ export class BusinessesController {
|
|||||||
@Post("domain/verify")
|
@Post("domain/verify")
|
||||||
@ApiOperation({ summary: "Initiate domain verification" })
|
@ApiOperation({ summary: "Initiate domain verification" })
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
async verifyDomain(@BusinessDec() business: Business, @Body() verifyDto: VerifyDomainDto) {
|
async verifyDomain(@BusinessDec() business: Business) {
|
||||||
return this.domainVerificationService.initiateVerification(business.id, verifyDto);
|
return this.domainVerificationService.initiateVerification(business.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("domain/verify/check")
|
@Post("domain/verify/check")
|
||||||
@@ -70,8 +69,8 @@ export class BusinessesController {
|
|||||||
@Post("admin/:businessId/domain/verify")
|
@Post("admin/:businessId/domain/verify")
|
||||||
@ApiOperation({ summary: "Admin initiate domain verification" })
|
@ApiOperation({ summary: "Admin initiate domain verification" })
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
async adminVerifyDomain(@Param("businessId") businessId: string, @Body() verifyDto: VerifyDomainDto) {
|
async adminVerifyDomain(@Param("businessId") businessId: string) {
|
||||||
return this.domainVerificationService.initiateVerification(businessId, verifyDto);
|
return this.domainVerificationService.initiateVerification(businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("admin/:businessId/domain/verify/check")
|
@Post("admin/:businessId/domain/verify/check")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Cascade, Collection, Entity, EntityRepositoryType, Enum, OneToMany, Opt, Property, Unique } from "@mikro-orm/core";
|
import { Cascade, Collection, Entity, EntityRepositoryType, OneToMany, Opt, Property, Unique } from "@mikro-orm/core";
|
||||||
|
|
||||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
import { Announcement } from "../../announcements/entities/announcement.entity";
|
import { Announcement } from "../../announcements/entities/announcement.entity";
|
||||||
@@ -9,7 +9,6 @@ import { Invoice } from "../../invoices/entities/invoice.entity";
|
|||||||
import { TicketCategory } from "../../tickets/entities/ticket-category.entity";
|
import { TicketCategory } from "../../tickets/entities/ticket-category.entity";
|
||||||
import { Ticket } from "../../tickets/entities/ticket.entity";
|
import { Ticket } from "../../tickets/entities/ticket.entity";
|
||||||
import { User } from "../../users/entities/user.entity";
|
import { User } from "../../users/entities/user.entity";
|
||||||
import { DomainVerificationMethod } from "../DTO/business-domain.dto";
|
|
||||||
import { BusinessRepository } from "../repositories/business.repository";
|
import { BusinessRepository } from "../repositories/business.repository";
|
||||||
|
|
||||||
@Entity({ repository: () => BusinessRepository })
|
@Entity({ repository: () => BusinessRepository })
|
||||||
@@ -30,9 +29,6 @@ export class Business extends BaseEntity {
|
|||||||
@Property({ type: "boolean", default: false })
|
@Property({ type: "boolean", default: false })
|
||||||
isDomainVerified: boolean & Opt;
|
isDomainVerified: boolean & Opt;
|
||||||
|
|
||||||
@Enum({ items: () => DomainVerificationMethod, nullable: true })
|
|
||||||
domainVerificationMethod?: DomainVerificationMethod;
|
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 255, nullable: true })
|
@Property({ type: "varchar", length: 255, nullable: true })
|
||||||
domainVerificationToken?: string;
|
domainVerificationToken?: string;
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ import { promisify } from "node:util";
|
|||||||
|
|
||||||
import { EntityManager } from "@mikro-orm/postgresql";
|
import { EntityManager } from "@mikro-orm/postgresql";
|
||||||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||||
import axios from "axios";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
import { BusinessesService } from "./businesses.service";
|
import { BusinessesService } from "./businesses.service";
|
||||||
import { BusinessMessage } from "../../../common/enums/message.enum";
|
import { BusinessMessage } from "../../../common/enums/message.enum";
|
||||||
import { DomainVerificationMethod, UpdateBusinessDomainDto, VerifyDomainDto } from "../DTO/business-domain.dto";
|
import { UpdateBusinessDomainDto } from "../DTO/business-domain.dto";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DomainVerificationService {
|
export class DomainVerificationService {
|
||||||
@@ -18,9 +17,8 @@ export class DomainVerificationService {
|
|||||||
private readonly resolveA = promisify(dns.resolve4);
|
private readonly resolveA = promisify(dns.resolve4);
|
||||||
private readonly resolveCname = promisify(dns.resolveCname);
|
private readonly resolveCname = promisify(dns.resolveCname);
|
||||||
|
|
||||||
// The server IP or domain users should point their domain to
|
private readonly serverIP = "IP_OF_YOUR_SERVER";
|
||||||
private readonly serverIP = "IP_OF_YOUR_SERVER"; // Replace with actual IP
|
private readonly serverDomain = "app.dzone.danakcorp.com";
|
||||||
private readonly serverDomain = "app.dzone.danakcorp.com"; // Replace with actual domain
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly businessesService: BusinessesService,
|
private readonly businessesService: BusinessesService,
|
||||||
@@ -33,7 +31,6 @@ export class DomainVerificationService {
|
|||||||
async updateBusinessDomain(businessId: string, domainDto: UpdateBusinessDomainDto) {
|
async updateBusinessDomain(businessId: string, domainDto: UpdateBusinessDomainDto) {
|
||||||
const business = await this.businessesService.getBusinessById(businessId);
|
const business = await this.businessesService.getBusinessById(businessId);
|
||||||
|
|
||||||
// Domain hasn't changed, check if it's already verified
|
|
||||||
if (business.domain === domainDto.domain && business.isDomainVerified) {
|
if (business.domain === domainDto.domain && business.isDomainVerified) {
|
||||||
return {
|
return {
|
||||||
message: BusinessMessage.DOMAIN_ALREADY_VERIFIED,
|
message: BusinessMessage.DOMAIN_ALREADY_VERIFIED,
|
||||||
@@ -42,15 +39,12 @@ export class DomainVerificationService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate verification token if domain changed or not verified
|
|
||||||
const verificationToken = this.generateVerificationToken();
|
const verificationToken = this.generateVerificationToken();
|
||||||
|
|
||||||
// Update the domain and verification data
|
|
||||||
business.domain = domainDto.domain;
|
business.domain = domainDto.domain;
|
||||||
business.isDomainVerified = false;
|
business.isDomainVerified = false;
|
||||||
business.domainVerificationToken = verificationToken;
|
business.domainVerificationToken = verificationToken;
|
||||||
business.domainVerifiedAt = undefined;
|
business.domainVerifiedAt = undefined;
|
||||||
business.domainVerificationMethod = undefined;
|
|
||||||
|
|
||||||
await this.em.flush();
|
await this.em.flush();
|
||||||
|
|
||||||
@@ -65,12 +59,10 @@ export class DomainVerificationService {
|
|||||||
/**
|
/**
|
||||||
* Initiate domain verification with specific method
|
* Initiate domain verification with specific method
|
||||||
*/
|
*/
|
||||||
async initiateVerification(businessId: string, verifyDto: VerifyDomainDto) {
|
async initiateVerification(businessId: string) {
|
||||||
const business = await this.businessesService.getBusinessById(businessId);
|
const business = await this.businessesService.getBusinessById(businessId);
|
||||||
|
|
||||||
if (!business.domain) {
|
if (!business.domain) throw new BadRequestException(BusinessMessage.DOMAIN_INVALID);
|
||||||
throw new BadRequestException(BusinessMessage.DOMAIN_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (business.isDomainVerified) {
|
if (business.isDomainVerified) {
|
||||||
return {
|
return {
|
||||||
@@ -81,21 +73,17 @@ export class DomainVerificationService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no token exists, generate one
|
|
||||||
if (!business.domainVerificationToken) {
|
if (!business.domainVerificationToken) {
|
||||||
business.domainVerificationToken = this.generateVerificationToken();
|
business.domainVerificationToken = this.generateVerificationToken();
|
||||||
await this.em.flush();
|
await this.em.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update verification method
|
|
||||||
business.domainVerificationMethod = verifyDto.method;
|
|
||||||
await this.em.flush();
|
await this.em.flush();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
message: BusinessMessage.DOMAIN_VERIFICATION_INITIATED,
|
message: BusinessMessage.DOMAIN_VERIFICATION_INITIATED,
|
||||||
domain: business.domain,
|
domain: business.domain,
|
||||||
method: verifyDto.method,
|
instructions: this.getDomainSetupInstructions(business.domain, business.domainVerificationToken),
|
||||||
instructions: this.getVerificationInstructions(business.domain, business.domainVerificationToken)[verifyDto.method],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,15 +125,11 @@ export class DomainVerificationService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//************************************** */
|
||||||
* Check domain verification status
|
|
||||||
*/
|
|
||||||
async verifyDomain(businessId: string) {
|
async verifyDomain(businessId: string) {
|
||||||
const business = await this.businessesService.getBusinessById(businessId);
|
const business = await this.businessesService.getBusinessById(businessId);
|
||||||
|
|
||||||
if (!business.domain || !business.domainVerificationToken || !business.domainVerificationMethod) {
|
if (!business.domain || !business.domainVerificationToken) throw new BadRequestException(BusinessMessage.DOMAIN_VERIFICATION_METHOD_INVALID);
|
||||||
throw new BadRequestException(BusinessMessage.DOMAIN_VERIFICATION_METHOD_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (business.isDomainVerified) {
|
if (business.isDomainVerified) {
|
||||||
return {
|
return {
|
||||||
@@ -159,19 +143,7 @@ export class DomainVerificationService {
|
|||||||
try {
|
try {
|
||||||
let isVerified = false;
|
let isVerified = false;
|
||||||
|
|
||||||
switch (business.domainVerificationMethod) {
|
|
||||||
case DomainVerificationMethod.DNS_TXT:
|
|
||||||
isVerified = await this.checkDnsTxtRecord(business.domain, business.domainVerificationToken);
|
isVerified = await this.checkDnsTxtRecord(business.domain, business.domainVerificationToken);
|
||||||
break;
|
|
||||||
case DomainVerificationMethod.FILE:
|
|
||||||
isVerified = await this.verifyFileMethod(business.domain, business.domainVerificationToken);
|
|
||||||
break;
|
|
||||||
case DomainVerificationMethod.META_TAG:
|
|
||||||
isVerified = await this.verifyMetaTagMethod(business.domain, business.domainVerificationToken);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new BadRequestException(BusinessMessage.DOMAIN_VERIFICATION_METHOD_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isVerified) {
|
if (isVerified) {
|
||||||
business.isDomainVerified = true;
|
business.isDomainVerified = true;
|
||||||
@@ -185,12 +157,11 @@ export class DomainVerificationService {
|
|||||||
verifiedAt: business.domainVerifiedAt,
|
verifiedAt: business.domainVerifiedAt,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const verificationMethod = business.domainVerificationMethod;
|
|
||||||
return {
|
return {
|
||||||
message: BusinessMessage.DOMAIN_VERIFICATION_FAILED,
|
message: BusinessMessage.DOMAIN_VERIFICATION_FAILED,
|
||||||
domain: business.domain,
|
domain: business.domain,
|
||||||
isVerified: false,
|
isVerified: false,
|
||||||
instructions: this.getVerificationInstructions(business.domain, business.domainVerificationToken)[verificationMethod],
|
instructions: this.getDomainSetupInstructions(business.domain, business.domainVerificationToken),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -199,15 +170,11 @@ export class DomainVerificationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//************************************** */
|
||||||
* Verify DNS TXT record and domain pointing
|
|
||||||
*/
|
|
||||||
async verifyDnsTxtRecord(businessId: string) {
|
async verifyDnsTxtRecord(businessId: string) {
|
||||||
const business = await this.businessesService.getBusinessById(businessId);
|
const business = await this.businessesService.getBusinessById(businessId);
|
||||||
|
|
||||||
if (!business.domain || !business.domainVerificationToken) {
|
if (!business.domain || !business.domainVerificationToken) throw new BadRequestException(BusinessMessage.DOMAIN_INVALID);
|
||||||
throw new BadRequestException(BusinessMessage.DOMAIN_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (business.isDomainVerified) {
|
if (business.isDomainVerified) {
|
||||||
const domainPointsToServer = await this.checkDomainPointsToServer(business.domain);
|
const domainPointsToServer = await this.checkDomainPointsToServer(business.domain);
|
||||||
@@ -275,9 +242,7 @@ export class DomainVerificationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//************************************** */
|
||||||
* Get domain verification status
|
|
||||||
*/
|
|
||||||
async getDomainVerificationStatus(businessId: string) {
|
async getDomainVerificationStatus(businessId: string) {
|
||||||
const business = await this.businessesService.getBusinessById(businessId);
|
const business = await this.businessesService.getBusinessById(businessId);
|
||||||
|
|
||||||
@@ -304,97 +269,7 @@ export class DomainVerificationService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//*********************************** */
|
||||||
* Verify domain using file method
|
|
||||||
*/
|
|
||||||
private async verifyFileMethod(domain: string, token: string): Promise<boolean> {
|
|
||||||
try {
|
|
||||||
// Try HTTPS first
|
|
||||||
try {
|
|
||||||
const response = await axios.get(`https://${domain}/.well-known/${token}.html`, {
|
|
||||||
timeout: 5000, // 5 seconds timeout
|
|
||||||
headers: {
|
|
||||||
"User-Agent": "Mozilla/5.0 (compatible; DzoneVerification/1.0; +https://dzone.danakcorp.com/domain-verification)",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status === 200 && response.data.toString().trim() === token.trim()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.debug(`HTTPS file verification failed, trying HTTP: ${error instanceof Error ? error.message : String(error)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try HTTP if HTTPS fails
|
|
||||||
const httpResponse = await axios.get(`http://${domain}/.well-known/${token}.html`, {
|
|
||||||
timeout: 5000,
|
|
||||||
headers: {
|
|
||||||
"User-Agent": "Mozilla/5.0 (compatible; DzoneVerification/1.0; +https://dzone.danakcorp.com/domain-verification)",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (httpResponse.status === 200 && httpResponse.data.toString().trim() === token.trim()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
} catch (error: unknown) {
|
|
||||||
this.logger.error(`Error verifying file method: ${error instanceof Error ? error.message : String(error)}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify domain using meta tag method
|
|
||||||
*/
|
|
||||||
private async verifyMetaTagMethod(domain: string, token: string): Promise<boolean> {
|
|
||||||
try {
|
|
||||||
// Try HTTPS first
|
|
||||||
try {
|
|
||||||
const response = await axios.get(`https://${domain}`, {
|
|
||||||
timeout: 5000, // 5 seconds timeout
|
|
||||||
headers: {
|
|
||||||
"User-Agent": "Mozilla/5.0 (compatible; DzoneVerification/1.0; +https://dzone.danakcorp.com/domain-verification)",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status === 200) {
|
|
||||||
// Check for meta tag in the HTML
|
|
||||||
const content = response.data.toString();
|
|
||||||
const metaTagRegex = new RegExp(`<meta[^>]*name=["']dzone-verification["'][^>]*content=["']${token}["']`, "i");
|
|
||||||
if (metaTagRegex.test(content)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.debug(`HTTPS meta tag verification failed, trying HTTP: ${error instanceof Error ? error.message : String(error)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try HTTP if HTTPS fails
|
|
||||||
const httpResponse = await axios.get(`http://${domain}`, {
|
|
||||||
timeout: 5000,
|
|
||||||
headers: {
|
|
||||||
"User-Agent": "Mozilla/5.0 (compatible; DzoneVerification/1.0; +https://dzone.danakcorp.com/domain-verification)",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (httpResponse.status === 200) {
|
|
||||||
// Check for meta tag in the HTML
|
|
||||||
const content = httpResponse.data.toString();
|
|
||||||
const metaTagRegex = new RegExp(`<meta[^>]*name=["']dzone-verification["'][^>]*content=["']${token}["']`, "i");
|
|
||||||
return metaTagRegex.test(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
} catch (error: unknown) {
|
|
||||||
this.logger.error(`Error verifying meta tag method: ${error instanceof Error ? error.message : String(error)}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get domain verification and connection status
|
|
||||||
*/
|
|
||||||
async getDomainStatus(businessId: string) {
|
async getDomainStatus(businessId: string) {
|
||||||
const business = await this.businessesService.getBusinessById(businessId);
|
const business = await this.businessesService.getBusinessById(businessId);
|
||||||
|
|
||||||
@@ -430,33 +305,6 @@ export class DomainVerificationService {
|
|||||||
return `dzone-verify-${crypto.randomBytes(16).toString("hex")}`;
|
return `dzone-verify-${crypto.randomBytes(16).toString("hex")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get verification instructions for all methods
|
|
||||||
*/
|
|
||||||
private getVerificationInstructions(domain: string, token: string) {
|
|
||||||
return {
|
|
||||||
[DomainVerificationMethod.DNS_TXT]: {
|
|
||||||
title: "Verify using DNS TXT record",
|
|
||||||
description: "Add a TXT record to your domain with the following values:",
|
|
||||||
host: "@", // or "_dzone-verification"
|
|
||||||
type: "TXT",
|
|
||||||
value: token,
|
|
||||||
},
|
|
||||||
[DomainVerificationMethod.FILE]: {
|
|
||||||
title: "Verify using a file",
|
|
||||||
description: "Create a file at the root of your domain with the following properties:",
|
|
||||||
path: `/.well-known/${token}.html`,
|
|
||||||
content: token,
|
|
||||||
fullUrl: `https://${domain}/.well-known/${token}.html`,
|
|
||||||
},
|
|
||||||
[DomainVerificationMethod.META_TAG]: {
|
|
||||||
title: "Verify using meta tag",
|
|
||||||
description: "Add the following meta tag to the <head> section of your homepage:",
|
|
||||||
tag: `<meta name="dzone-verification" content="${token}">`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get domain connection instructions
|
* Get domain connection instructions
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user