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:
parent
8f78515976
commit
ad44f0875a
3 changed files with 30 additions and 8 deletions
|
@ -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 { MockQueries } = await import('#src/test-utils/tenant.js');
|
||||||
const { createDomainLibrary } = await import('./domain.js');
|
const { createDomainLibrary } = await import('./domain.js');
|
||||||
|
|
||||||
|
@ -49,11 +53,16 @@ afterAll(() => {
|
||||||
SystemContext.shared.hostnameProviderConfig = undefined;
|
SystemContext.shared.hostnameProviderConfig = undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
clearCustomDomainCache.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
describe('addDomain()', () => {
|
describe('addDomain()', () => {
|
||||||
it('should call createCustomHostname and return cloudflare data', async () => {
|
it('should call createCustomHostname and return cloudflare data', async () => {
|
||||||
const response = await addDomain(mockDomain.domain);
|
const response = await addDomain(mockDomain.domain);
|
||||||
expect(createCustomHostname).toBeCalledTimes(1);
|
expect(createCustomHostname).toBeCalledTimes(1);
|
||||||
expect(insertDomain).toBeCalledTimes(1);
|
expect(insertDomain).toBeCalledTimes(1);
|
||||||
|
expect(clearCustomDomainCache).toBeCalledTimes(1);
|
||||||
expect(response.cloudflareData).toMatchObject(mockCloudflareData);
|
expect(response.cloudflareData).toMatchObject(mockCloudflareData);
|
||||||
expect(response.dnsRecords).toContainEqual({
|
expect(response.dnsRecords).toContainEqual({
|
||||||
type: 'CNAME',
|
type: 'CNAME',
|
||||||
|
@ -76,6 +85,7 @@ describe('syncDomainStatus()', () => {
|
||||||
cloudflareData: mockCloudflareDataPendingSSL,
|
cloudflareData: mockCloudflareDataPendingSSL,
|
||||||
});
|
});
|
||||||
expect(getCustomHostname).toBeCalledTimes(1);
|
expect(getCustomHostname).toBeCalledTimes(1);
|
||||||
|
expect(clearCustomDomainCache).toBeCalledTimes(1);
|
||||||
expect(response.cloudflareData).toMatchObject(mockCloudflareData);
|
expect(response.cloudflareData).toMatchObject(mockCloudflareData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -128,6 +138,7 @@ describe('deleteDomain()', () => {
|
||||||
findDomainById.mockResolvedValueOnce(mockDomainWithCloudflareData);
|
findDomainById.mockResolvedValueOnce(mockDomainWithCloudflareData);
|
||||||
await deleteDomain(mockDomain.id);
|
await deleteDomain(mockDomain.id);
|
||||||
expect(deleteCustomHostname).toBeCalledTimes(1);
|
expect(deleteCustomHostname).toBeCalledTimes(1);
|
||||||
|
expect(clearCustomDomainCache).toBeCalledTimes(1);
|
||||||
expect(deleteDomainById).toBeCalledTimes(1);
|
expect(deleteDomainById).toBeCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -135,6 +146,7 @@ describe('deleteDomain()', () => {
|
||||||
findDomainById.mockResolvedValueOnce(mockDomain);
|
findDomainById.mockResolvedValueOnce(mockDomain);
|
||||||
await deleteDomain(mockDomain.id);
|
await deleteDomain(mockDomain.id);
|
||||||
expect(deleteCustomHostname).not.toBeCalled();
|
expect(deleteCustomHostname).not.toBeCalled();
|
||||||
|
expect(clearCustomDomainCache).toBeCalledTimes(1);
|
||||||
expect(deleteDomainById).toBeCalledTimes(1);
|
expect(deleteDomainById).toBeCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
deleteCustomHostname,
|
deleteCustomHostname,
|
||||||
getFallbackOrigin,
|
getFallbackOrigin,
|
||||||
} from '#src/utils/cloudflare/index.js';
|
} from '#src/utils/cloudflare/index.js';
|
||||||
|
import { clearCustomDomainCache } from '#src/utils/tenant.js';
|
||||||
|
|
||||||
export type DomainLibrary = ReturnType<typeof createDomainLibrary>;
|
export type DomainLibrary = ReturnType<typeof createDomainLibrary>;
|
||||||
|
|
||||||
|
@ -60,7 +61,9 @@ export const createDomainLibrary = (queries: Queries) => {
|
||||||
domain.cloudflareData.id
|
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> => {
|
const addDomain = async (hostname: string): Promise<Domain> => {
|
||||||
|
@ -72,7 +75,7 @@ export const createDomainLibrary = (queries: Queries) => {
|
||||||
createCustomHostname(hostnameProviderConfig, hostname),
|
createCustomHostname(hostnameProviderConfig, hostname),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return insertDomain({
|
const insertedDomain = await insertDomain({
|
||||||
domain: hostname,
|
domain: hostname,
|
||||||
id: generateStandardId(),
|
id: generateStandardId(),
|
||||||
cloudflareData,
|
cloudflareData,
|
||||||
|
@ -85,6 +88,8 @@ export const createDomainLibrary = (queries: Queries) => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
await clearCustomDomainCache(hostname);
|
||||||
|
return insertedDomain;
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteDomain = async (id: string) => {
|
const deleteDomain = async (id: string) => {
|
||||||
|
@ -98,6 +103,7 @@ export const createDomainLibrary = (queries: Queries) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
await deleteDomainById(id);
|
await deleteDomainById(id);
|
||||||
|
await clearCustomDomainCache(domain.domain);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -46,8 +46,12 @@ const matchPathBasedTenantId = (urlSet: UrlSet, url: URL) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const cacheKey = 'custom-domain';
|
const cacheKey = 'custom-domain';
|
||||||
const notFoundValue = 'not-found';
|
const getDomainCacheKey = (url: URL | string) =>
|
||||||
const getDomainCacheKey = (url: URL) => `${cacheKey}:${url.hostname}`;
|
`${cacheKey}:${typeof url === 'string' ? url : url.hostname}`;
|
||||||
|
|
||||||
|
export const clearCustomDomainCache = async (url: URL | string) => {
|
||||||
|
await trySafe(async () => redisCache.delete(getDomainCacheKey(url)));
|
||||||
|
};
|
||||||
|
|
||||||
const getTenantIdFromCustomDomain = async (
|
const getTenantIdFromCustomDomain = async (
|
||||||
url: URL,
|
url: URL,
|
||||||
|
@ -56,16 +60,16 @@ const getTenantIdFromCustomDomain = async (
|
||||||
const cachedValue = await trySafe(async () => redisCache.get(getDomainCacheKey(url)));
|
const cachedValue = await trySafe(async () => redisCache.get(getDomainCacheKey(url)));
|
||||||
|
|
||||||
if (cachedValue) {
|
if (cachedValue) {
|
||||||
return cachedValue === notFoundValue ? undefined : cachedValue;
|
return cachedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { findActiveDomain } = createDomainsQueries(pool);
|
const { findActiveDomain } = createDomainsQueries(pool);
|
||||||
|
|
||||||
const domain = await findActiveDomain(url.hostname);
|
const domain = await findActiveDomain(url.hostname);
|
||||||
|
|
||||||
await trySafe(async () =>
|
if (domain?.tenantId) {
|
||||||
redisCache.set(getDomainCacheKey(url), domain?.tenantId ?? notFoundValue, 60)
|
await trySafe(async () => redisCache.set(getDomainCacheKey(url), domain.tenantId));
|
||||||
);
|
}
|
||||||
|
|
||||||
return domain?.tenantId;
|
return domain?.tenantId;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue