0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(core): persist dns records to database (#3950)

This commit is contained in:
wangsijie 2023-06-02 14:22:58 +08:00 committed by GitHub
parent 64af2dc88e
commit 8178d61eca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 36 deletions

View file

@ -99,16 +99,6 @@ describe('syncDomainStatus()', () => {
getCustomHostname.mockResolvedValueOnce(mockCloudflareDataPendingSSL); getCustomHostname.mockResolvedValueOnce(mockCloudflareDataPendingSSL);
const response = await syncDomainStatus(mockDomainWithCloudflareData); const response = await syncDomainStatus(mockDomainWithCloudflareData);
expect(response.status).toBe(DomainStatus.PendingSsl); expect(response.status).toBe(DomainStatus.PendingSsl);
expect(response.dnsRecords).not.toContainEqual({
type: 'CNAME',
name: mockDomainWithCloudflareData.domain,
value: fallbackOrigin,
});
expect(response.dnsRecords).not.toContainEqual({
type: 'TXT',
name: mockTxtName,
value: mockTxtValue,
});
expect(response.dnsRecords).toContainEqual({ expect(response.dnsRecords).toContainEqual({
type: 'TXT', type: 'TXT',
name: mockSslTxtName, name: mockSslTxtName,
@ -120,21 +110,6 @@ describe('syncDomainStatus()', () => {
getCustomHostname.mockResolvedValueOnce(mockCloudflareDataActive); getCustomHostname.mockResolvedValueOnce(mockCloudflareDataActive);
const response = await syncDomainStatus(mockDomainWithCloudflareData); const response = await syncDomainStatus(mockDomainWithCloudflareData);
expect(response.status).toBe(DomainStatus.Active); expect(response.status).toBe(DomainStatus.Active);
expect(response.dnsRecords).not.toContainEqual({
type: 'CNAME',
name: mockDomainWithCloudflareData.domain,
value: fallbackOrigin,
});
expect(response.dnsRecords).not.toContainEqual({
type: 'TXT',
name: mockTxtName,
value: mockTxtValue,
});
expect(response.dnsRecords).not.toContainEqual({
type: 'TXT',
name: mockSslTxtName,
value: mockSslTxtValue,
});
}); });
it('should sync and get verification error', async () => { it('should sync and get verification error', async () => {

View file

@ -5,12 +5,12 @@ import {
DomainStatus, DomainStatus,
} from '@logto/schemas'; } from '@logto/schemas';
import { generateStandardId } from '@logto/shared'; import { generateStandardId } from '@logto/shared';
import { conditional } from '@silverhand/essentials';
import type Queries from '#src/tenants/Queries.js'; import type Queries from '#src/tenants/Queries.js';
import SystemContext from '#src/tenants/SystemContext.js'; import SystemContext from '#src/tenants/SystemContext.js';
import assertThat from '#src/utils/assert-that.js'; import assertThat from '#src/utils/assert-that.js';
import { getCustomHostname, createCustomHostname } from '#src/utils/cloudflare/index.js'; import { getCustomHostname, createCustomHostname } from '#src/utils/cloudflare/index.js';
import { findSslTxtRecord, findVerificationTxtRecord } from '#src/utils/cloudflare/utils.js';
export type DomainLibrary = ReturnType<typeof createDomainLibrary>; export type DomainLibrary = ReturnType<typeof createDomainLibrary>;
@ -49,19 +49,20 @@ export const createDomainLibrary = (queries: Queries) => {
.filter(Boolean) .filter(Boolean)
.join('\n'); .join('\n');
const sslRecord = conditional( const dnsRecords: DomainDnsRecords = [
txtName && txtValue && { type: 'TXT', name: txtName, value: txtValue } // Verification CNAME, fixed value, generated by us
); {
const cnameRecord = conditional(
(status === DomainStatus.PendingVerification || status === DomainStatus.Error) && {
type: 'CNAME', type: 'CNAME',
name: domain.domain, name: domain.domain,
value: origin, value: origin,
} },
); // SSL TXT, generated by Cloudflare
const dnsRecords: DomainDnsRecords = [cnameRecord, ownershipVerification, sslRecord].filter( txtName && txtValue
Boolean ? { type: 'TXT', name: txtName, value: txtValue }
); : findSslTxtRecord(domain.dnsRecords),
// Ownership TXT, generated by Cloudflare
ownershipVerification ?? findVerificationTxtRecord(domain.dnsRecords),
].filter(Boolean);
return updateDomainById( return updateDomainById(
domain.id, domain.id,

View file

@ -1,4 +1,5 @@
import { parseJson } from '@logto/connector-kit'; import { parseJson } from '@logto/connector-kit';
import { type DomainDnsRecords } from '@logto/schemas';
import assertThat from '../assert-that.js'; import assertThat from '../assert-that.js';
@ -11,3 +12,13 @@ export const parseCloudflareResponse = (body: string) => {
return result.data.result; return result.data.result;
}; };
export const findVerificationTxtRecord = (records: DomainDnsRecords) =>
records.find(
({ type, name }) => type.toUpperCase() === 'TXT' && name.includes('_cf-custom-hostname')
);
export const findSslTxtRecord = (records: DomainDnsRecords) =>
records.find(
({ type, name }) => type.toUpperCase() === 'TXT' && name.includes('_acme-challenge')
);