mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(core): init domain-based multi-tenancy env
This commit is contained in:
parent
d3e786ec80
commit
1e8c00c014
5 changed files with 9 additions and 34 deletions
|
@ -17,15 +17,11 @@ const logListening = (type: 'core' | 'admin' = 'core') => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTenantId = () => {
|
const getTenantId = () => {
|
||||||
if (!EnvSet.values.isMultiTenancy) {
|
if (!EnvSet.values.isDomainBasedMultiTenancy) {
|
||||||
return defaultTenant;
|
return (!EnvSet.values.isProduction && EnvSet.values.developmentTenantId) || defaultTenant;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EnvSet.values.multiTenancyMode === 'domain') {
|
throw new Error('Not implemented');
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
return !EnvSet.values.isProduction && EnvSet.values.developmentTenantId;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function initApp(app: Koa): Promise<void> {
|
export default async function initApp(app: Koa): Promise<void> {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import net from 'net';
|
|
||||||
|
|
||||||
import { tryThat } from '@logto/shared';
|
import { tryThat } from '@logto/shared';
|
||||||
import { assertEnv, getEnv, getEnvAsStringArray } from '@silverhand/essentials';
|
import { assertEnv, getEnv, getEnvAsStringArray } from '@silverhand/essentials';
|
||||||
|
|
||||||
|
@ -7,7 +5,6 @@ import UrlSet from './UrlSet.js';
|
||||||
import { isTrue } from './parameters.js';
|
import { isTrue } from './parameters.js';
|
||||||
import { throwErrorWithDsnMessage } from './throw-errors.js';
|
import { throwErrorWithDsnMessage } from './throw-errors.js';
|
||||||
|
|
||||||
const enableMultiTenancyKey = 'ENABLE_MULTI_TENANCY';
|
|
||||||
const developmentTenantIdKey = 'DEVELOPMENT_TENANT_ID';
|
const developmentTenantIdKey = 'DEVELOPMENT_TENANT_ID';
|
||||||
|
|
||||||
type MultiTenancyMode = 'domain' | 'env';
|
type MultiTenancyMode = 'domain' | 'env';
|
||||||
|
@ -21,11 +18,11 @@ export default class GlobalValues {
|
||||||
public readonly httpsKey = process.env.HTTPS_KEY_PATH;
|
public readonly httpsKey = process.env.HTTPS_KEY_PATH;
|
||||||
public readonly isHttpsEnabled = Boolean(this.httpsCert && this.httpsKey);
|
public readonly isHttpsEnabled = Boolean(this.httpsCert && this.httpsKey);
|
||||||
|
|
||||||
public readonly isMultiTenancy = isTrue(getEnv(enableMultiTenancyKey));
|
|
||||||
|
|
||||||
public readonly urlSet = new UrlSet(this.isHttpsEnabled, 3001);
|
public readonly urlSet = new UrlSet(this.isHttpsEnabled, 3001);
|
||||||
public readonly adminUrlSet = new UrlSet(this.isHttpsEnabled, 3002, 'ADMIN_');
|
public readonly adminUrlSet = new UrlSet(this.isHttpsEnabled, 3002, 'ADMIN_');
|
||||||
|
|
||||||
|
public readonly isDomainBasedMultiTenancy = this.urlSet.endpoint.includes('*');
|
||||||
|
|
||||||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||||
public readonly databaseUrl = tryThat(() => assertEnv('DB_URL'), throwErrorWithDsnMessage);
|
public readonly databaseUrl = tryThat(() => assertEnv('DB_URL'), throwErrorWithDsnMessage);
|
||||||
public readonly developmentTenantId = getEnv(developmentTenantIdKey);
|
public readonly developmentTenantId = getEnv(developmentTenantIdKey);
|
||||||
|
@ -41,12 +38,4 @@ export default class GlobalValues {
|
||||||
public get endpoint(): string {
|
public get endpoint(): string {
|
||||||
return this.urlSet.endpoint;
|
return this.urlSet.endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get multiTenancyMode(): MultiTenancyMode {
|
|
||||||
const { hostname } = new URL(this.endpoint);
|
|
||||||
|
|
||||||
return this.isMultiTenancy && !net.isIP(hostname) && hostname !== 'localhost'
|
|
||||||
? 'domain'
|
|
||||||
: 'env';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,7 @@ try {
|
||||||
});
|
});
|
||||||
await initI18n();
|
await initI18n();
|
||||||
await loadConnectorFactories();
|
await loadConnectorFactories();
|
||||||
|
await checkRowLevelSecurity(EnvSet.default.queryClient);
|
||||||
if (EnvSet.values.isMultiTenancy) {
|
|
||||||
await checkRowLevelSecurity(EnvSet.default.queryClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Import last until init completed
|
// Import last until init completed
|
||||||
const { default: initApp } = await import('./app/init.js');
|
const { default: initApp } = await import('./app/init.js');
|
||||||
|
|
|
@ -19,7 +19,7 @@ export default function koaConsoleRedirectProxy<
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.path === '/console/welcome' && hasUser) {
|
if ((ctx.path === '/' || ctx.path === '/console/welcome') && hasUser) {
|
||||||
ctx.redirect('/console');
|
ctx.redirect('/console');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -23,18 +23,11 @@ import initRouter from '#src/routes/init.js';
|
||||||
import Libraries from './Libraries.js';
|
import Libraries from './Libraries.js';
|
||||||
import Queries from './Queries.js';
|
import Queries from './Queries.js';
|
||||||
import type TenantContext from './TenantContext.js';
|
import type TenantContext from './TenantContext.js';
|
||||||
import { defaultTenant } from './consts.js';
|
|
||||||
import { getTenantDatabaseDsn } from './utils.js';
|
import { getTenantDatabaseDsn } from './utils.js';
|
||||||
|
|
||||||
export default class Tenant implements TenantContext {
|
export default class Tenant implements TenantContext {
|
||||||
static async create(id: string): Promise<Tenant> {
|
static async create(id: string): Promise<Tenant> {
|
||||||
if (!EnvSet.values.isMultiTenancy) {
|
if (!EnvSet.values.isDomainBasedMultiTenancy) {
|
||||||
if (id !== defaultTenant) {
|
|
||||||
throw new Error(
|
|
||||||
`Trying to create a tenant instance with ID ${id} in single-tenancy mode. This is a no-op.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Tenant(EnvSet.default, id);
|
return new Tenant(EnvSet.default, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +49,7 @@ export default class Tenant implements TenantContext {
|
||||||
return mount(this.app);
|
return mount(this.app);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(public readonly envSet: EnvSet, public readonly id: string) {
|
private constructor(public readonly envSet: EnvSet, public readonly id: string) {
|
||||||
const modelRouters = createModelRouters(envSet.queryClient);
|
const modelRouters = createModelRouters(envSet.queryClient);
|
||||||
const queries = new Queries(envSet.pool);
|
const queries = new Queries(envSet.pool);
|
||||||
const libraries = new Libraries(queries, modelRouters);
|
const libraries = new Libraries(queries, modelRouters);
|
||||||
|
|
Loading…
Reference in a new issue