-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdns-verification.ts
More file actions
89 lines (79 loc) · 2.28 KB
/
Copy pathdns-verification.ts
File metadata and controls
89 lines (79 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { db } from '$lib/server/db';
import { dnsVerifications } from '$lib/server/db/schema';
import { eq } from 'drizzle-orm';
import { randomBytes } from 'crypto';
import { resolve } from 'dns/promises';
import { logger } from '$lib/server/logger';
export async function getOrCreateDnsVerification(orgId: string, domain: string) {
const existing = await db
.select()
.from(dnsVerifications)
.where(eq(dnsVerifications.orgId, orgId))
.limit(1);
if (existing[0]) return existing[0];
const txtRecord = `postguard-verify=${randomBytes(16).toString('hex')}`;
const [created] = await db
.insert(dnsVerifications)
.values({ orgId, domain, txtRecord })
.returning();
return created;
}
export async function verifyDns(orgId: string): Promise<{
verified: boolean;
error?: string;
}> {
const records = await db
.select()
.from(dnsVerifications)
.where(eq(dnsVerifications.orgId, orgId))
.limit(1);
if (!records[0]) return { verified: false, error: 'No DNS verification record found' };
const record = records[0];
try {
const txtRecords = await resolve(record.domain, 'TXT');
const flat = txtRecords.flat();
const found = flat.some((txt) => txt === record.txtRecord);
if (found) {
await db
.update(dnsVerifications)
.set({
verified: true,
verifiedAt: new Date(),
lastCheckedAt: new Date()
})
.where(eq(dnsVerifications.id, record.id));
return { verified: true };
} else {
await db
.update(dnsVerifications)
.set({ lastCheckedAt: new Date() })
.where(eq(dnsVerifications.id, record.id));
return {
verified: false,
error: `TXT record "${record.txtRecord}" not found in DNS for ${record.domain}`
};
}
} catch (err) {
const code = (err as NodeJS.ErrnoException)?.code;
logger.error(
{
orgId,
domain: record.domain,
code,
err: err instanceof Error ? err.message : String(err)
},
'dns resolve failed'
);
await db
.update(dnsVerifications)
.set({ lastCheckedAt: new Date() })
.where(eq(dnsVerifications.id, record.id));
const userMsg =
code === 'ENOTFOUND'
? `Domain ${record.domain} not found`
: code === 'ENODATA'
? `No TXT records found for ${record.domain}`
: `Could not resolve DNS for ${record.domain}`;
return { verified: false, error: userMsg };
}
}