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

fix(core): update domain cache (#4017)

This commit is contained in:
wangsijie 2023-06-19 15:45:42 +09:00 committed by GitHub
parent 8f78515976
commit ad44f0875a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 8 deletions

View file

@ -25,6 +25,10 @@ const { getCustomHostname, createCustomHostname, deleteCustomHostname } = mockEs
})
);
const { clearCustomDomainCache } = mockEsm('#src/utils/tenant.js', () => ({
clearCustomDomainCache: jest.fn(),
}));
const { MockQueries } = await import('#src/test-utils/tenant.js');
const { createDomainLibrary } = await import('./domain.js');
@ -49,11 +53,16 @@ afterAll(() => {
SystemContext.shared.hostnameProviderConfig = undefined;
});
afterEach(() => {
clearCustomDomainCache.mockClear();
});
describe('addDomain()', () => {
it('should call createCustomHostname and return cloudflare data', async () => {
const response = await addDomain(mockDomain.domain);
expect(createCustomHostname).toBeCalledTimes(1);
expect(insertDomain).toBeCalledTimes(1);
expect(clearCustomDomainCache).toBeCalledTimes(1);
expect(response.cloudflareData).toMatchObject(mockCloudflareData);
expect(response.dnsRecords).toContainEqual({
type: 'CNAME',
@ -76,6 +85,7 @@ describe('syncDomainStatus()', () => {
cloudflareData: mockCloudflareDataPendingSSL,
});
expect(getCustomHostname).toBeCalledTimes(1);
expect(clearCustomDomainCache).toBeCalledTimes(1);
expect(response.cloudflareData).toMatchObject(mockCloudflareData);
});
@ -128,6 +138,7 @@ describe('deleteDomain()', () => {
findDomainById.mockResolvedValueOnce(mockDomainWithCloudflareData);
await deleteDomain(mockDomain.id);
expect(deleteCustomHostname).toBeCalledTimes(1);
expect(clearCustomDomainCache).toBeCalledTimes(1);
expect(deleteDomainById).toBeCalledTimes(1);
});
@ -135,6 +146,7 @@ describe('deleteDomain()', () => {
findDomainById.mockResolvedValueOnce(mockDomain);
await deleteDomain(mockDomain.id);
expect(deleteCustomHostname).not.toBeCalled();
expect(clearCustomDomainCache).toBeCalledTimes(1);
expect(deleteDomainById).toBeCalledTimes(1);
});
});

View file

@ -10,6 +10,7 @@ import {
deleteCustomHostname,
getFallbackOrigin,
} from '#src/utils/cloudflare/index.js';
import { clearCustomDomainCache } from '#src/utils/tenant.js';
export type DomainLibrary = ReturnType<typeof createDomainLibrary>;
@ -60,7 +61,9 @@ export const createDomainLibrary = (queries: Queries) => {
domain.cloudflareData.id
);
return syncDomainStatusFromCloudflareData(domain, cloudflareData);
const updatedDomain = await syncDomainStatusFromCloudflareData(domain, cloudflareData);
await clearCustomDomainCache(domain.domain);
return updatedDomain;
};
const addDomain = async (hostname: string): Promise<Domain> => {
@ -72,7 +75,7 @@ export const createDomainLibrary = (queries: Queries) => {
createCustomHostname(hostnameProviderConfig, hostname),
]);
return insertDomain({
const insertedDomain = await insertDomain({
domain: hostname,
id: generateStandardId(),
cloudflareData,
@ -85,6 +88,8 @@ export const createDomainLibrary = (queries: Queries) => {
},
],
});
await clearCustomDomainCache(hostname);
return insertedDomain;
};
const deleteDomain = async (id: string) => {
@ -98,6 +103,7 @@ export const createDomainLibrary = (queries: Queries) => {
}
await deleteDomainById(id);
await clearCustomDomainCache(domain.domain);
};
return {

View file

@ -46,8 +46,12 @@ const matchPathBasedTenantId = (urlSet: UrlSet, url: URL) => {
};
const cacheKey = 'custom-domain';
const notFoundValue = 'not-found';
const getDomainCacheKey = (url: URL) => `${cacheKey}:${url.hostname}`;
const getDomainCacheKey = (url: URL | string) =>
`${cacheKey}:${typeof url === 'string' ? url : url.hostname}`;
export const clearCustomDomainCache = async (url: URL | string) => {
await trySafe(async () => redisCache.delete(getDomainCacheKey(url)));
};
const getTenantIdFromCustomDomain = async (
url: URL,
@ -56,16 +60,16 @@ const getTenantIdFromCustomDomain = async (
const cachedValue = await trySafe(async () => redisCache.get(getDomainCacheKey(url)));
if (cachedValue) {
return cachedValue === notFoundValue ? undefined : cachedValue;
return cachedValue;
}
const { findActiveDomain } = createDomainsQueries(pool);
const domain = await findActiveDomain(url.hostname);
await trySafe(async () =>
redisCache.set(getDomainCacheKey(url), domain?.tenantId ?? notFoundValue, 60)
);
if (domain?.tenantId) {
await trySafe(async () => redisCache.set(getDomainCacheKey(url), domain.tenantId));
}
return domain?.tenantId;
};