2020-12-28 13:48:47 +02:00
|
|
|
import { rtrimSlashes } from '@joplin/lib/path-utils';
|
2023-11-08 17:38:01 +02:00
|
|
|
import { Config, DatabaseConfig, DatabaseConfigClient, Env, MailerConfig, LdapConfig, RouteType, StripeConfig } from './utils/types';
|
2021-01-18 12:13:26 +02:00
|
|
|
import * as pathUtils from 'path';
|
2021-07-31 15:42:56 +02:00
|
|
|
import { loadStripeConfig, StripePublicConfig } from '@joplin/lib/utils/joplinCloud';
|
2021-11-02 14:51:59 +02:00
|
|
|
import { EnvVariables } from './env';
|
2021-11-11 15:59:05 +02:00
|
|
|
import parseStorageDriverConnectionString from './models/items/storage/parseStorageConnectionString';
|
2020-12-28 13:48:47 +02:00
|
|
|
|
2021-10-09 16:30:39 +02:00
|
|
|
interface PackageJson {
|
|
|
|
version: string;
|
2023-05-17 19:16:29 +02:00
|
|
|
joplinServer: {
|
|
|
|
forkVersion: string;
|
|
|
|
};
|
2021-10-09 16:30:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const packageJson: PackageJson = require(`${__dirname}/packageInfo.js`);
|
|
|
|
|
2023-02-05 13:32:28 +02:00
|
|
|
let runningInDocker_ = false;
|
2021-01-18 12:13:26 +02:00
|
|
|
|
|
|
|
export function runningInDocker(): boolean {
|
|
|
|
return runningInDocker_;
|
2020-12-28 13:48:47 +02:00
|
|
|
}
|
|
|
|
|
2024-05-11 17:12:54 +02:00
|
|
|
function databaseHostFromEnv(runningInDocker: boolean, env: EnvVariables, slave: boolean): string {
|
|
|
|
const postgresHost = slave ? env.SLAVE_POSTGRES_HOST : env.POSTGRES_HOST;
|
|
|
|
|
|
|
|
if (postgresHost) {
|
2021-01-18 12:13:26 +02:00
|
|
|
// When running within Docker, the app localhost is different from the
|
|
|
|
// host's localhost. To access the latter, Docker defines a special host
|
|
|
|
// called "host.docker.internal", so here we swap the values if necessary.
|
2024-05-11 17:12:54 +02:00
|
|
|
if (runningInDocker && ['localhost', '127.0.0.1'].includes(postgresHost)) {
|
2021-01-18 12:13:26 +02:00
|
|
|
return 'host.docker.internal';
|
|
|
|
} else {
|
2024-05-11 17:12:54 +02:00
|
|
|
return postgresHost;
|
2021-01-18 12:13:26 +02:00
|
|
|
}
|
|
|
|
}
|
2020-12-28 13:48:47 +02:00
|
|
|
|
2021-01-18 12:13:26 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2023-05-17 19:16:29 +02:00
|
|
|
export const fullVersionString = (config: Config) => {
|
|
|
|
const output: string[] = [];
|
|
|
|
output.push(`v${config.appVersion}`);
|
|
|
|
if (config.appVersion !== config.joplinServerVersion) output.push(`(Based on Joplin Server v${config.joplinServerVersion})`);
|
|
|
|
return output.join(' ');
|
|
|
|
};
|
|
|
|
|
2024-05-11 17:12:54 +02:00
|
|
|
function databaseConfigFromEnv(runningInDocker: boolean, env: EnvVariables, slave: boolean): DatabaseConfig {
|
2021-09-16 00:14:14 +02:00
|
|
|
const baseConfig: DatabaseConfig = {
|
|
|
|
client: DatabaseConfigClient.Null,
|
|
|
|
name: '',
|
2021-11-02 14:51:59 +02:00
|
|
|
slowQueryLogEnabled: env.DB_SLOW_QUERY_LOG_ENABLED,
|
|
|
|
slowQueryLogMinDuration: env.DB_SLOW_QUERY_LOG_MIN_DURATION,
|
|
|
|
autoMigration: env.DB_AUTO_MIGRATION,
|
2021-09-16 00:14:14 +02:00
|
|
|
};
|
|
|
|
|
2021-01-18 12:13:26 +02:00
|
|
|
if (env.DB_CLIENT === 'pg') {
|
2022-12-28 16:38:30 +02:00
|
|
|
const databaseConfig: DatabaseConfig = {
|
2021-09-16 00:14:14 +02:00
|
|
|
...baseConfig,
|
2021-01-18 12:13:26 +02:00
|
|
|
client: DatabaseConfigClient.PostgreSQL,
|
|
|
|
};
|
2022-12-28 16:38:30 +02:00
|
|
|
if (env.POSTGRES_CONNECTION_STRING) {
|
|
|
|
return {
|
|
|
|
...databaseConfig,
|
2024-05-11 17:12:54 +02:00
|
|
|
connectionString: slave ? env.SLAVE_POSTGRES_CONNECTION_STRING : env.POSTGRES_CONNECTION_STRING,
|
2022-12-28 16:38:30 +02:00
|
|
|
};
|
|
|
|
} else {
|
|
|
|
return {
|
|
|
|
...databaseConfig,
|
2024-05-11 17:12:54 +02:00
|
|
|
name: slave ? env.SLAVE_POSTGRES_DATABASE : env.POSTGRES_DATABASE,
|
|
|
|
user: slave ? env.SLAVE_POSTGRES_USER : env.POSTGRES_USER,
|
|
|
|
password: slave ? env.SLAVE_POSTGRES_PASSWORD : env.POSTGRES_PASSWORD,
|
|
|
|
port: slave ? env.SLAVE_POSTGRES_PORT : env.POSTGRES_PORT,
|
|
|
|
host: databaseHostFromEnv(runningInDocker, env, slave) || 'localhost',
|
2022-12-28 16:38:30 +02:00
|
|
|
};
|
|
|
|
}
|
2021-01-18 12:13:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
2021-09-16 00:14:14 +02:00
|
|
|
...baseConfig,
|
2021-01-18 12:13:26 +02:00
|
|
|
client: DatabaseConfigClient.SQLite,
|
2024-05-11 17:12:54 +02:00
|
|
|
name: slave ? env.SLAVE_SQLITE_DATABASE : env.SQLITE_DATABASE,
|
2021-01-18 12:13:26 +02:00
|
|
|
asyncStackTraces: true,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-05-25 11:49:47 +02:00
|
|
|
function mailerConfigFromEnv(env: EnvVariables): MailerConfig {
|
|
|
|
return {
|
2021-11-02 14:51:59 +02:00
|
|
|
enabled: env.MAILER_ENABLED,
|
|
|
|
host: env.MAILER_HOST,
|
|
|
|
port: env.MAILER_PORT,
|
2022-01-09 13:13:48 +02:00
|
|
|
security: env.MAILER_SECURITY,
|
2021-11-02 14:51:59 +02:00
|
|
|
authUser: env.MAILER_AUTH_USER,
|
|
|
|
authPassword: env.MAILER_AUTH_PASSWORD,
|
|
|
|
noReplyName: env.MAILER_NOREPLY_NAME,
|
|
|
|
noReplyEmail: env.MAILER_NOREPLY_EMAIL,
|
2021-05-25 11:49:47 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-07-10 12:16:13 +02:00
|
|
|
function stripeConfigFromEnv(publicConfig: StripePublicConfig, env: EnvVariables): StripeConfig {
|
2021-06-03 15:21:02 +02:00
|
|
|
return {
|
2021-07-10 12:16:13 +02:00
|
|
|
...publicConfig,
|
2021-08-02 18:43:18 +02:00
|
|
|
enabled: !!env.STRIPE_SECRET_KEY,
|
2021-11-02 14:51:59 +02:00
|
|
|
secretKey: env.STRIPE_SECRET_KEY,
|
|
|
|
webhookSecret: env.STRIPE_WEBHOOK_SECRET,
|
2021-06-03 15:21:02 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-11-02 14:51:59 +02:00
|
|
|
function baseUrlFromEnv(env: EnvVariables, appPort: number): string {
|
2021-01-18 12:13:26 +02:00
|
|
|
if (env.APP_BASE_URL) {
|
|
|
|
return rtrimSlashes(env.APP_BASE_URL);
|
2020-12-28 13:48:47 +02:00
|
|
|
} else {
|
2021-01-18 12:13:26 +02:00
|
|
|
return `http://localhost:${appPort}`;
|
2020-12-28 13:48:47 +02:00
|
|
|
}
|
2021-01-18 12:13:26 +02:00
|
|
|
}
|
|
|
|
|
2023-11-08 17:38:01 +02:00
|
|
|
function ldapConfigFromEnv(env: EnvVariables): LdapConfig[] {
|
|
|
|
const ldapConfig = [];
|
|
|
|
if (env.LDAP_1_ENABLED) {
|
|
|
|
ldapConfig.push({
|
|
|
|
enabled: env.LDAP_1_ENABLED,
|
|
|
|
userCreation: env.LDAP_1_USER_AUTO_CREATION,
|
|
|
|
host: env.LDAP_1_HOST,
|
|
|
|
mailAttribute: env.LDAP_1_MAIL_ATTRIBUTE,
|
|
|
|
fullNameAttribute: env.LDAP_1_FULLNAME_ATTRIBUTE,
|
|
|
|
baseDN: env.LDAP_1_BASE_DN,
|
|
|
|
bindDN: env.LDAP_1_BIND_DN,
|
|
|
|
bindPW: env.LDAP_1_BIND_PW,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (env.LDAP_2_ENABLED) {
|
|
|
|
ldapConfig.push({
|
|
|
|
enabled: env.LDAP_2_ENABLED,
|
|
|
|
userCreation: env.LDAP_2_USER_AUTO_CREATION,
|
|
|
|
host: env.LDAP_2_HOST,
|
|
|
|
mailAttribute: env.LDAP_2_MAIL_ATTRIBUTE,
|
|
|
|
fullNameAttribute: env.LDAP_2_FULLNAME_ATTRIBUTE,
|
|
|
|
baseDN: env.LDAP_2_BASE_DN,
|
|
|
|
bindDN: env.LDAP_2_BIND_DN,
|
|
|
|
bindPW: env.LDAP_2_BIND_PW,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return ldapConfig;
|
|
|
|
}
|
|
|
|
|
2021-01-18 12:13:26 +02:00
|
|
|
let config_: Config = null;
|
|
|
|
|
2024-04-05 13:16:49 +02:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
2021-06-03 15:21:02 +02:00
|
|
|
export async function initConfig(envType: Env, env: EnvVariables, overrides: any = null) {
|
2021-01-18 12:13:26 +02:00
|
|
|
runningInDocker_ = !!env.RUNNING_IN_DOCKER;
|
2020-12-28 13:48:47 +02:00
|
|
|
|
2021-01-18 12:13:26 +02:00
|
|
|
const rootDir = pathUtils.dirname(__dirname);
|
2021-07-31 15:42:56 +02:00
|
|
|
const stripePublicConfig = loadStripeConfig(envType === Env.BuildTypes ? Env.Dev : envType, `${rootDir}/stripeConfig.json`);
|
2021-11-02 14:51:59 +02:00
|
|
|
const appName = env.APP_NAME;
|
2021-05-26 15:53:27 +02:00
|
|
|
const viewDir = `${rootDir}/src/views`;
|
2021-11-02 14:51:59 +02:00
|
|
|
const appPort = env.APP_PORT;
|
2021-05-25 16:42:21 +02:00
|
|
|
const baseUrl = baseUrlFromEnv(env, appPort);
|
2021-07-25 15:21:41 +02:00
|
|
|
const apiBaseUrl = env.API_BASE_URL ? env.API_BASE_URL : baseUrl;
|
2021-11-02 14:51:59 +02:00
|
|
|
const supportEmail = env.SUPPORT_EMAIL;
|
2023-05-17 19:16:29 +02:00
|
|
|
const forkVersion = packageJson.joplinServer?.forkVersion;
|
2024-05-11 17:12:54 +02:00
|
|
|
const dbConfig = databaseConfigFromEnv(runningInDocker_, env, false);
|
2021-01-18 12:13:26 +02:00
|
|
|
|
|
|
|
config_ = {
|
2022-02-01 19:55:14 +02:00
|
|
|
...env,
|
2023-05-17 19:16:29 +02:00
|
|
|
appVersion: forkVersion ? forkVersion : packageJson.version,
|
|
|
|
joplinServerVersion: packageJson.version,
|
2021-08-03 20:47:18 +02:00
|
|
|
appName,
|
2021-08-31 14:46:46 +02:00
|
|
|
isJoplinCloud: apiBaseUrl.includes('.joplincloud.com') || apiBaseUrl.includes('.joplincloud.local'),
|
2021-06-03 15:21:02 +02:00
|
|
|
env: envType,
|
2021-01-18 12:13:26 +02:00
|
|
|
rootDir: rootDir,
|
|
|
|
viewDir: viewDir,
|
|
|
|
layoutDir: `${viewDir}/layouts`,
|
2021-01-29 20:45:11 +02:00
|
|
|
tempDir: `${rootDir}/temp`,
|
2021-01-18 12:13:26 +02:00
|
|
|
logDir: `${rootDir}/logs`,
|
2024-05-11 17:12:54 +02:00
|
|
|
database: dbConfig,
|
|
|
|
databaseSlave: env.DB_USE_SLAVE ? databaseConfigFromEnv(runningInDocker_, env, true) : dbConfig,
|
2021-05-25 11:49:47 +02:00
|
|
|
mailer: mailerConfigFromEnv(env),
|
2021-07-10 12:16:13 +02:00
|
|
|
stripe: stripeConfigFromEnv(stripePublicConfig, env),
|
2021-01-18 12:13:26 +02:00
|
|
|
port: appPort,
|
2021-05-25 16:42:21 +02:00
|
|
|
baseUrl,
|
2022-01-14 12:14:43 +02:00
|
|
|
adminBaseUrl: `${baseUrl}/admin`,
|
2021-11-02 14:51:59 +02:00
|
|
|
showErrorStackTraces: env.ERROR_STACK_TRACES,
|
2021-07-25 15:21:41 +02:00
|
|
|
apiBaseUrl,
|
2021-05-25 16:42:21 +02:00
|
|
|
userContentBaseUrl: env.USER_CONTENT_BASE_URL ? env.USER_CONTENT_BASE_URL : baseUrl,
|
2021-11-02 14:51:59 +02:00
|
|
|
joplinAppBaseUrl: env.JOPLINAPP_BASE_URL,
|
|
|
|
signupEnabled: env.SIGNUP_ENABLED,
|
|
|
|
termsEnabled: env.TERMS_ENABLED,
|
|
|
|
accountTypesEnabled: env.ACCOUNT_TYPES_ENABLED,
|
2021-07-11 12:35:49 +02:00
|
|
|
supportEmail,
|
2021-08-03 20:47:18 +02:00
|
|
|
supportName: env.SUPPORT_NAME || appName,
|
2021-07-11 12:35:49 +02:00
|
|
|
businessEmail: env.BUSINESS_EMAIL || supportEmail,
|
2021-11-02 14:51:59 +02:00
|
|
|
cookieSecure: env.COOKIES_SECURE,
|
2021-11-09 18:05:42 +02:00
|
|
|
storageDriver: parseStorageDriverConnectionString(env.STORAGE_DRIVER),
|
|
|
|
storageDriverFallback: parseStorageDriverConnectionString(env.STORAGE_DRIVER_FALLBACK),
|
2021-11-14 18:47:16 +02:00
|
|
|
itemSizeHardLimit: 250000000, // Beyond this the Postgres driver will crash the app
|
2021-11-17 14:54:34 +02:00
|
|
|
maxTimeDrift: env.MAX_TIME_DRIFT,
|
2023-11-08 17:38:01 +02:00
|
|
|
ldap: ldapConfigFromEnv(env),
|
2021-05-13 18:57:37 +02:00
|
|
|
...overrides,
|
2021-01-18 12:13:26 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-05-25 16:42:21 +02:00
|
|
|
export function baseUrl(type: RouteType): string {
|
|
|
|
if (type === RouteType.Web) return config().baseUrl;
|
|
|
|
if (type === RouteType.Api) return config().apiBaseUrl;
|
|
|
|
if (type === RouteType.UserContent) return config().userContentBaseUrl;
|
|
|
|
throw new Error(`Unknown type: ${type}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
// User content URL is not supported for now so only show the URL if the
|
|
|
|
// user content is hosted on the same domain. Needs to get cookie working
|
|
|
|
// across domains to get user content url working.
|
|
|
|
export function showItemUrls(config: Config): boolean {
|
|
|
|
return config.userContentBaseUrl === config.baseUrl;
|
|
|
|
}
|
|
|
|
|
2021-01-18 12:13:26 +02:00
|
|
|
function config(): Config {
|
|
|
|
if (!config_) throw new Error('Config has not been initialized!');
|
|
|
|
return config_;
|
2020-12-28 13:48:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export default config;
|