Skip to content

Commit e7b75d9

Browse files
authored
Merge pull request #612 from trycompai/main
[comp] Production Deploy
2 parents 8168c79 + 0a9a63f commit e7b75d9

File tree

9 files changed

+364
-157
lines changed

9 files changed

+364
-157
lines changed

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/settings/trust-portal/actions/check-dns-record.ts

Lines changed: 58 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,13 @@ export const checkDnsRecordAction = authActionClient
4848
const txtResponse = await fetch(
4949
`https://networkcalc.com/api/dns/lookup/${rootDomain}?type=TXT`,
5050
);
51+
const vercelTxtResponse = await fetch(
52+
`https://networkcalc.com/api/dns/lookup/_vercel.${rootDomain}?type=TXT`,
53+
);
54+
5155
const data = await response.json();
5256
const txtData = await txtResponse.json();
57+
const vercelTxtData = await vercelTxtResponse.json();
5358

5459
if (
5560
response.status !== 200 ||
@@ -66,9 +71,20 @@ export const checkDnsRecordAction = authActionClient
6671

6772
const cnameRecords = data.records?.CNAME;
6873
const txtRecords = txtData.records?.TXT;
69-
74+
const vercelTxtRecords = vercelTxtData.records?.TXT;
75+
const isVercelDomain = await db.trust.findUnique({
76+
where: {
77+
organizationId: activeOrgId,
78+
domain,
79+
},
80+
select: {
81+
isVercelDomain: true,
82+
vercelVerification: true,
83+
},
84+
});
7085
const expectedCnameValue = "cname.vercel-dns.com";
7186
const expectedTxtValue = `compai-domain-verification=${activeOrgId}`;
87+
const expectedVercelTxtValue = isVercelDomain?.vercelVerification;
7288

7389
let isCnameVerified = false;
7490

@@ -80,8 +96,10 @@ export const checkDnsRecordAction = authActionClient
8096
}
8197

8298
let isTxtVerified = false;
99+
let isVercelTxtVerified = false;
83100

84101
if (txtRecords) {
102+
// Check for our custom TXT record
85103
isTxtVerified = txtRecords.some((record: any) => {
86104
if (typeof record === "string") {
87105
return record === expectedTxtValue;
@@ -102,13 +120,36 @@ export const checkDnsRecordAction = authActionClient
102120
});
103121
}
104122

105-
const isVerified = isCnameVerified && isTxtVerified;
123+
if (vercelTxtRecords) {
124+
isVercelTxtVerified = vercelTxtRecords.some((record: any) => {
125+
if (typeof record === "string") {
126+
return record === expectedVercelTxtValue;
127+
}
128+
if (record && typeof record.value === "string") {
129+
return record.value === expectedVercelTxtValue;
130+
}
131+
if (
132+
record &&
133+
Array.isArray(record.txt) &&
134+
record.txt.length > 0
135+
) {
136+
return record.txt.some(
137+
(txt: string) => txt === expectedVercelTxtValue,
138+
);
139+
}
140+
return false;
141+
});
142+
}
143+
144+
const isVerified =
145+
isCnameVerified && isTxtVerified && isVercelTxtVerified;
106146

107147
if (!isVerified) {
108148
return {
109149
success: false,
110150
isCnameVerified,
111151
isTxtVerified,
152+
isVercelTxtVerified,
112153
error: "Error verifying DNS records. Please ensure both CNAME and TXT records are correctly configured, or wait a few minutes and try again.",
113154
};
114155
}
@@ -120,45 +161,21 @@ export const checkDnsRecordAction = authActionClient
120161
};
121162
}
122163

123-
const isExistingRecord = await vercel.projects.getProjectDomains({
124-
idOrName: env.TRUST_PORTAL_PROJECT_ID,
125-
teamId: env.VERCEL_TEAM_ID,
126-
});
127-
128-
if (isExistingRecord.domains.some((record) => record.name === domain)) {
129-
await vercel.projects.removeProjectDomain({
130-
idOrName: env.TRUST_PORTAL_PROJECT_ID,
131-
teamId: env.VERCEL_TEAM_ID,
164+
await db.trust.upsert({
165+
where: {
166+
organizationId: activeOrgId,
132167
domain,
133-
});
134-
}
135-
136-
const addDomainToProject = await vercel.projects
137-
.addProjectDomain({
138-
idOrName: env.TRUST_PORTAL_PROJECT_ID,
139-
teamId: env.VERCEL_TEAM_ID,
140-
slug: env.TRUST_PORTAL_PROJECT_ID,
141-
requestBody: {
142-
name: domain,
143-
},
144-
})
145-
.then(async (res) => {
146-
await db.trust.upsert({
147-
where: {
148-
organizationId: activeOrgId,
149-
domain,
150-
},
151-
update: {
152-
domainVerified: true,
153-
status: "published",
154-
},
155-
create: {
156-
organizationId: activeOrgId,
157-
domain,
158-
status: "published",
159-
},
160-
});
161-
});
168+
},
169+
update: {
170+
domainVerified: true,
171+
status: "published",
172+
},
173+
create: {
174+
organizationId: activeOrgId,
175+
domain,
176+
status: "published",
177+
},
178+
});
162179

163180
revalidatePath(`/${activeOrgId}/settings/trust-portal`);
164181
revalidateTag(`organization_${activeOrgId}`);
@@ -167,5 +184,6 @@ export const checkDnsRecordAction = authActionClient
167184
success: true,
168185
isCnameVerified,
169186
isTxtVerified,
187+
isVercelTxtVerified,
170188
};
171189
});

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/settings/trust-portal/actions/custom-domain.ts

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ import { db } from "@comp/db";
66
import { authActionClient } from "@/actions/safe-action";
77
import { z } from "zod";
88
import { revalidatePath, revalidateTag } from "next/cache";
9+
import { env } from "node:process";
10+
import { Vercel } from "@vercel/sdk";
911

1012
const customDomainSchema = z.object({
1113
domain: z.string().min(1),
1214
});
1315

16+
const vercel = new Vercel({
17+
bearerToken: env.VERCEL_ACCESS_TOKEN,
18+
});
19+
1420
export const customDomainAction = authActionClient
1521
.schema(customDomainSchema)
1622
.metadata({
@@ -33,19 +39,74 @@ export const customDomainAction = authActionClient
3339
where: { organizationId: activeOrganizationId },
3440
});
3541

36-
// Always set domainVerified to false when domain changes
3742
const domainVerified =
3843
currentDomain?.domain === domain
3944
? currentDomain.domainVerified
4045
: false;
4146

47+
const isExistingRecord = await vercel.projects.getProjectDomains({
48+
idOrName: env.TRUST_PORTAL_PROJECT_ID!,
49+
teamId: env.VERCEL_TEAM_ID!,
50+
});
51+
52+
if (
53+
isExistingRecord.domains.some(
54+
(record) => record.name === domain,
55+
)
56+
) {
57+
const domainOwner = await db.trust.findUnique({
58+
where: {
59+
organizationId: activeOrganizationId,
60+
domain: domain,
61+
},
62+
});
63+
64+
if (
65+
!domainOwner ||
66+
domainOwner.organizationId === activeOrganizationId
67+
) {
68+
await vercel.projects.removeProjectDomain({
69+
idOrName: env.TRUST_PORTAL_PROJECT_ID!,
70+
teamId: env.VERCEL_TEAM_ID!,
71+
domain,
72+
});
73+
} else {
74+
return {
75+
success: false,
76+
error: "Domain is already in use by another organization",
77+
};
78+
}
79+
}
80+
81+
const addDomainToProject = await vercel.projects.addProjectDomain({
82+
idOrName: env.TRUST_PORTAL_PROJECT_ID!,
83+
teamId: env.VERCEL_TEAM_ID!,
84+
slug: env.TRUST_PORTAL_PROJECT_ID!,
85+
requestBody: {
86+
name: domain,
87+
},
88+
});
89+
90+
const isVercelDomain = addDomainToProject.verified === false;
91+
92+
// Store the verification details from Vercel if available
93+
const vercelVerification =
94+
addDomainToProject.verification?.[0]?.value || null;
95+
4296
await db.trust.upsert({
4397
where: { organizationId: activeOrganizationId },
44-
update: { domain, domainVerified },
98+
update: {
99+
domain,
100+
domainVerified,
101+
isVercelDomain,
102+
vercelVerification,
103+
},
45104
create: {
46105
organizationId: activeOrganizationId,
47106
domain,
48107
domainVerified: false,
108+
isVercelDomain,
109+
vercelVerification,
49110
},
50111
});
51112

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/settings/trust-portal/actions/trust-portal-switch.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { z } from "zod";
99

1010
const trustPortalSwitchSchema = z.object({
1111
enabled: z.boolean(),
12-
contactEmail: z.string().email().optional(),
12+
contactEmail: z.string().email().optional().or(z.literal("")),
1313
});
1414

1515
export const trustPortalSwitchAction = authActionClient
@@ -34,12 +34,12 @@ export const trustPortalSwitchAction = authActionClient
3434
where: { organizationId: activeOrganizationId },
3535
update: {
3636
status: enabled ? "published" : "draft",
37-
contactEmail: contactEmail ?? null,
37+
contactEmail: contactEmail === "" ? null : contactEmail,
3838
},
3939
create: {
4040
organizationId: activeOrganizationId,
4141
status: enabled ? "published" : "draft",
42-
contactEmail: contactEmail ?? null,
42+
contactEmail: contactEmail === "" ? null : contactEmail,
4343
},
4444
});
4545

0 commit comments

Comments
 (0)