diff --git a/packages/core/src/app/init.ts b/packages/core/src/app/init.ts index 5276cd58d..1370d7cb7 100644 --- a/packages/core/src/app/init.ts +++ b/packages/core/src/app/init.ts @@ -17,15 +17,11 @@ const logListening = (type: 'core' | 'admin' = 'core') => { }; const getTenantId = () => { - if (!EnvSet.values.isMultiTenancy) { - return defaultTenant; + if (!EnvSet.values.isDomainBasedMultiTenancy) { + return (!EnvSet.values.isProduction && EnvSet.values.developmentTenantId) || defaultTenant; } - if (EnvSet.values.multiTenancyMode === 'domain') { - throw new Error('Not implemented'); - } - - return !EnvSet.values.isProduction && EnvSet.values.developmentTenantId; + throw new Error('Not implemented'); }; export default async function initApp(app: Koa): Promise { diff --git a/packages/core/src/env-set/GlobalValues.ts b/packages/core/src/env-set/GlobalValues.ts index 8a1e1ec96..a3aa0b9a3 100644 --- a/packages/core/src/env-set/GlobalValues.ts +++ b/packages/core/src/env-set/GlobalValues.ts @@ -1,5 +1,3 @@ -import net from 'net'; - import { tryThat } from '@logto/shared'; import { assertEnv, getEnv, getEnvAsStringArray } from '@silverhand/essentials'; @@ -7,7 +5,6 @@ import UrlSet from './UrlSet.js'; import { isTrue } from './parameters.js'; import { throwErrorWithDsnMessage } from './throw-errors.js'; -const enableMultiTenancyKey = 'ENABLE_MULTI_TENANCY'; const developmentTenantIdKey = 'DEVELOPMENT_TENANT_ID'; type MultiTenancyMode = 'domain' | 'env'; @@ -21,11 +18,11 @@ export default class GlobalValues { public readonly httpsKey = process.env.HTTPS_KEY_PATH; public readonly isHttpsEnabled = Boolean(this.httpsCert && this.httpsKey); - public readonly isMultiTenancy = isTrue(getEnv(enableMultiTenancyKey)); - public readonly urlSet = new UrlSet(this.isHttpsEnabled, 3001); public readonly adminUrlSet = new UrlSet(this.isHttpsEnabled, 3002, 'ADMIN_'); + public readonly isDomainBasedMultiTenancy = this.urlSet.endpoint.includes('*'); + // eslint-disable-next-line unicorn/consistent-function-scoping public readonly databaseUrl = tryThat(() => assertEnv('DB_URL'), throwErrorWithDsnMessage); public readonly developmentTenantId = getEnv(developmentTenantIdKey); @@ -41,12 +38,4 @@ export default class GlobalValues { public get endpoint(): string { return this.urlSet.endpoint; } - - public get multiTenancyMode(): MultiTenancyMode { - const { hostname } = new URL(this.endpoint); - - return this.isMultiTenancy && !net.isIP(hostname) && hostname !== 'localhost' - ? 'domain' - : 'env'; - } } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d42e2a169..78a36aa86 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -17,10 +17,7 @@ try { }); await initI18n(); await loadConnectorFactories(); - - if (EnvSet.values.isMultiTenancy) { - await checkRowLevelSecurity(EnvSet.default.queryClient); - } + await checkRowLevelSecurity(EnvSet.default.queryClient); // Import last until init completed const { default: initApp } = await import('./app/init.js'); diff --git a/packages/core/src/middleware/koa-console-redirect-proxy.ts b/packages/core/src/middleware/koa-console-redirect-proxy.ts index c931378e9..a6fb817ed 100644 --- a/packages/core/src/middleware/koa-console-redirect-proxy.ts +++ b/packages/core/src/middleware/koa-console-redirect-proxy.ts @@ -19,7 +19,7 @@ export default function koaConsoleRedirectProxy< return; } - if (ctx.path === '/console/welcome' && hasUser) { + if ((ctx.path === '/' || ctx.path === '/console/welcome') && hasUser) { ctx.redirect('/console'); return; diff --git a/packages/core/src/tenants/Tenant.ts b/packages/core/src/tenants/Tenant.ts index 2228e33b4..18c9dff12 100644 --- a/packages/core/src/tenants/Tenant.ts +++ b/packages/core/src/tenants/Tenant.ts @@ -23,18 +23,11 @@ import initRouter from '#src/routes/init.js'; import Libraries from './Libraries.js'; import Queries from './Queries.js'; import type TenantContext from './TenantContext.js'; -import { defaultTenant } from './consts.js'; import { getTenantDatabaseDsn } from './utils.js'; export default class Tenant implements TenantContext { static async create(id: string): Promise { - if (!EnvSet.values.isMultiTenancy) { - if (id !== defaultTenant) { - throw new Error( - `Trying to create a tenant instance with ID ${id} in single-tenancy mode. This is a no-op.` - ); - } - + if (!EnvSet.values.isDomainBasedMultiTenancy) { return new Tenant(EnvSet.default, id); } @@ -56,7 +49,7 @@ export default class Tenant implements TenantContext { 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 queries = new Queries(envSet.pool); const libraries = new Libraries(queries, modelRouters);