/* * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import type { BaseUrls } from '../components/common/base-url/base-url-context-provider' import { Logger } from './logger' import { isTestMode, isBuildTime } from './test-modes' import { NoSubdirectoryAllowedError, parseUrl } from '@hedgedoc/commons' import { Optional } from '@mrdrogdrog/optional' /** * Extracts and caches the editor and renderer base urls from the environment variables. */ export class BaseUrlFromEnvExtractor { private baseUrls: BaseUrls | undefined private readonly logger = new Logger('Base URL Configuration') private extractUrlFromEnvVar(envVarName: string, envVarValue: string | undefined): Optional { try { return parseUrl(envVarValue) } catch (error) { if (error instanceof NoSubdirectoryAllowedError) { this.logger.error(error.message) return Optional.empty() } else { throw error } } } private extractEditorBaseUrlFromEnv(): Optional { const envValue = this.extractUrlFromEnvVar('HD_BASE_URL', process.env.HD_BASE_URL) if (envValue.isEmpty()) { this.logger.error("HD_BASE_URL isn't a valid URL!") } return envValue } private extractRendererBaseUrlFromEnv(editorBaseUrl: URL): Optional { if (isTestMode) { this.logger.info('Test mode activated. Using editor base url for renderer.') return Optional.of(editorBaseUrl) } if (!process.env.HD_RENDERER_BASE_URL) { this.logger.info('HD_RENDERER_BASE_URL is unset. Using editor base url for renderer.') return Optional.of(editorBaseUrl) } return this.extractUrlFromEnvVar('HD_RENDERER_BASE_URL', process.env.HD_RENDERER_BASE_URL) } private renewBaseUrls(): BaseUrls { return this.extractEditorBaseUrlFromEnv() .flatMap((editorBaseUrl) => this.extractRendererBaseUrlFromEnv(editorBaseUrl).map((rendererBaseUrl) => { return { editor: editorBaseUrl.toString(), renderer: rendererBaseUrl.toString() } }) ) .orElseThrow(() => new Error('couldnt parse env vars')) } /** * Extracts the editor and renderer base urls from the environment variables. * * @return An {@link Optional} with the base urls. */ public extractBaseUrls(): BaseUrls { if (isBuildTime) { return { editor: 'https://example.org/', renderer: 'https://example.org/' } } if (this.baseUrls === undefined) { this.baseUrls = this.renewBaseUrls() this.logBaseUrls() } return this.baseUrls } private logBaseUrls() { if (this.baseUrls === undefined) { return } this.logger.info('Editor base URL', this.baseUrls.editor.toString()) this.logger.info('Renderer base URL', this.baseUrls.renderer.toString()) } } export const baseUrlFromEnvExtractor = new BaseUrlFromEnvExtractor()