refactor: centralize envs and their defaults in modules/config
(#464)
* feat(config): centralized env variables and their default values * fix: fip `corsWildcard` variable check in `corsConfig` * fix(config): use already declared variables and default some strings to undefined * fix: check processingPriority against NaN
This commit is contained in:
parent
d780192ada
commit
5fbf35a8d3
10 changed files with 68 additions and 42 deletions
|
@ -6,6 +6,7 @@ import express from "express";
|
|||
import { Bright, Green, Red } from "./modules/sub/consoleText.js";
|
||||
import { getCurrentBranch, shortCommit } from "./modules/sub/currentCommit.js";
|
||||
import { loadLoc } from "./localization/manager.js";
|
||||
import { mode } from "./modules/config.js"
|
||||
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
@ -22,13 +23,10 @@ app.disable('x-powered-by');
|
|||
|
||||
await loadLoc();
|
||||
|
||||
const apiMode = process.env.API_URL && !process.env.WEB_URL;
|
||||
const webMode = process.env.WEB_URL && process.env.API_URL;
|
||||
|
||||
if (apiMode) {
|
||||
if (mode === 'API') {
|
||||
const { runAPI } = await import('./core/api.js');
|
||||
runAPI(express, app, gitCommit, gitBranch, __dirname)
|
||||
} else if (webMode) {
|
||||
} else if (mode === 'WEB') {
|
||||
const { runWeb } = await import('./core/web.js');
|
||||
await runWeb(express, app, gitCommit, gitBranch, __dirname)
|
||||
} else {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { randomBytes } from "crypto";
|
|||
|
||||
const ipSalt = randomBytes(64).toString('hex');
|
||||
|
||||
import { version } from "../modules/config.js";
|
||||
import { env, version } from "../modules/config.js";
|
||||
import { getJSON } from "../modules/api.js";
|
||||
import { apiJSON, checkJSONPost, getIP, languageCode } from "../modules/sub/utils.js";
|
||||
import { Bright, Cyan } from "../modules/sub/consoleText.js";
|
||||
|
@ -14,8 +14,8 @@ import { generateHmac } from "../modules/sub/crypto.js";
|
|||
import { verifyStream, getInternalStream } from "../modules/stream/manage.js";
|
||||
|
||||
export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
||||
const corsConfig = process.env.CORS_WILDCARD === '0' ? {
|
||||
origin: process.env.CORS_URL,
|
||||
const corsConfig = !env.corsWildcard ? {
|
||||
origin: env.corsURL,
|
||||
optionsSuccessStatus: 200
|
||||
} : {};
|
||||
|
||||
|
@ -163,9 +163,9 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
|||
version: version,
|
||||
commit: gitCommit,
|
||||
branch: gitBranch,
|
||||
name: process.env.API_NAME || "unknown",
|
||||
url: process.env.API_URL,
|
||||
cors: process.env?.CORS_WILDCARD === "0" ? 0 : 1,
|
||||
name: env.apiName,
|
||||
url: env.apiURL,
|
||||
cors: Number(env.corsWildcard),
|
||||
startTime: `${startTimestamp}`
|
||||
});
|
||||
default:
|
||||
|
@ -194,12 +194,12 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
|||
res.redirect('/api/json')
|
||||
});
|
||||
|
||||
app.listen(process.env.API_PORT || 9000, () => {
|
||||
app.listen(env.apiPort, () => {
|
||||
console.log(`\n` +
|
||||
`${Cyan("cobalt")} API ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` +
|
||||
`Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` +
|
||||
`URL: ${Cyan(`${process.env.API_URL}`)}\n` +
|
||||
`Port: ${process.env.API_PORT || 9000}\n`
|
||||
`URL: ${Cyan(`${env.apiURL}`)}\n` +
|
||||
`Port: ${env.apiPort}\n`
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { genericUserAgent, version } from "../modules/config.js";
|
||||
import { genericUserAgent, version, env } from "../modules/config.js";
|
||||
import { apiJSON, languageCode } from "../modules/sub/utils.js";
|
||||
import { Bright, Cyan } from "../modules/sub/consoleText.js";
|
||||
|
||||
|
@ -76,12 +76,12 @@ export async function runWeb(express, app, gitCommit, gitBranch, __dirname) {
|
|||
return res.redirect('/')
|
||||
});
|
||||
|
||||
app.listen(process.env.WEB_PORT || 9001, () => {
|
||||
app.listen(env.webPort, () => {
|
||||
console.log(`\n` +
|
||||
`${Cyan("cobalt")} WEB ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` +
|
||||
`Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` +
|
||||
`URL: ${Cyan(`${process.env.WEB_URL}`)}\n` +
|
||||
`Port: ${process.env.WEB_PORT || 9001}\n`
|
||||
`URL: ${Cyan(`${env.webURL}`)}\n` +
|
||||
`Port: ${env.webPort}\n`
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,6 +12,31 @@ Object.values(servicesConfigJson.config).forEach(service => {
|
|||
)
|
||||
})
|
||||
|
||||
const
|
||||
apiURL = process.env.API_URL || '',
|
||||
|
||||
// WEB mode related environment variables
|
||||
webEnvs = {
|
||||
webPort: process.env.WEB_PORT || 9001,
|
||||
webURL: process.env.WEB_URL || '',
|
||||
showSponsors: !!process.env.SHOW_SPONSORS,
|
||||
isBeta: !!process.env.IS_BETA,
|
||||
plausibleHostname: process.env.PLAUSIBLE_HOSTNAME,
|
||||
apiURL
|
||||
},
|
||||
|
||||
// API mode related environment variables
|
||||
apiEnvs = {
|
||||
apiPort: process.env.API_PORT || 9000,
|
||||
apiName: process.env.API_NAME || 'unknown',
|
||||
corsWildcard: process.env.CORS_WILDCARD !== '0',
|
||||
corsURL: process.env.CORS_URL,
|
||||
cookiePath: process.env.COOKIE_PATH,
|
||||
processingPriority: process.env.PROCESSING_PRIORITY && parseInt(process.env.PROCESSING_PRIORITY),
|
||||
tiktokDeviceInfo: process.env.TIKTOK_DEVICE_INFO && JSON.parse(process.env.TIKTOK_DEVICE_INFO),
|
||||
apiURL
|
||||
}
|
||||
|
||||
export const
|
||||
services = servicesConfigJson.config,
|
||||
audioIgnore = servicesConfigJson.audioIgnore,
|
||||
|
@ -26,4 +51,7 @@ export const
|
|||
supportedAudio = config.supportedAudio,
|
||||
celebrations = config.celebrations,
|
||||
links = config.links,
|
||||
sponsors = config.sponsors
|
||||
sponsors = config.sponsors,
|
||||
mode = (apiURL && !webEnvs.webURL) ? 'API' :
|
||||
(webEnvs.webURL && apiURL) ? 'WEB' : undefined,
|
||||
env = mode === 'API' ? apiEnvs : webEnvs
|
|
@ -1,4 +1,4 @@
|
|||
import { authorInfo, celebrations, sponsors } from "../config.js";
|
||||
import { authorInfo, celebrations, sponsors, env } from "../config.js";
|
||||
import emoji from "../emoji.js";
|
||||
import { loadFile } from "../sub/loadFromFs.js";
|
||||
|
||||
|
@ -266,5 +266,5 @@ export function sponsoredList() {
|
|||
}
|
||||
|
||||
export function betaTag() {
|
||||
return process.env.IS_BETA ? '<span class="logo-sub">β</span>' : ''
|
||||
return env.isBeta ? '<span class="logo-sub">β</span>' : ''
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { checkbox, collapsibleList, explanation, footerButtons, multiPagePopup, popup, popupWithBottomButtons, sep, settingsCategory, switcher, socialLink, socialLinks, urgentNotice, keyboardShortcuts, webLoc, sponsoredList, betaTag, linkSVG } from "./elements.js";
|
||||
import { services as s, authorInfo, version, repo, donations, supportedAudio, links } from "../config.js";
|
||||
import { services as s, authorInfo, version, repo, donations, supportedAudio, links, env } from "../config.js";
|
||||
import { getCommitInfo } from "../sub/currentCommit.js";
|
||||
import loc from "../../localization/manager.js";
|
||||
import emoji from "../emoji.js";
|
||||
|
@ -48,10 +48,10 @@ export default function(obj) {
|
|||
|
||||
<title>${t("AppTitleCobalt")}</title>
|
||||
|
||||
<meta property="og:url" content="${process.env.WEB_URL}">
|
||||
<meta property="og:url" content="${env.webURL}">
|
||||
<meta property="og:title" content="${t("AppTitleCobalt")}">
|
||||
<meta property="og:description" content="${t('EmbedBriefDescription')}">
|
||||
<meta property="og:image" content="${process.env.WEB_URL}icons/generic.png">
|
||||
<meta property="og:image" content="${env.webURL}icons/generic.png">
|
||||
<meta name="title" content="${t("AppTitleCobalt")}">
|
||||
<meta name="description" content="${t('AboutSummary')}">
|
||||
<meta name="theme-color" content="#000000">
|
||||
|
@ -75,11 +75,11 @@ export default function(obj) {
|
|||
<link rel="preload" href="assets/meowbalt/error.png" as="image">
|
||||
<link rel="preload" href="assets/meowbalt/question.png" as="image">
|
||||
|
||||
${process.env.PLAUSIBLE_HOSTNAME ?
|
||||
${env.plausibleHostname ?
|
||||
`<script
|
||||
defer
|
||||
data-domain="${new URL(process.env.WEB_URL).hostname}"
|
||||
src="https://${process.env.PLAUSIBLE_HOSTNAME}/js/script.js"
|
||||
data-domain="${new URL(env.webURL).hostname}"
|
||||
src="https://${env.plausibleHostname}/js/script.js"
|
||||
></script>`
|
||||
: ''}
|
||||
</head>
|
||||
|
@ -169,7 +169,7 @@ export default function(obj) {
|
|||
name: "privacy",
|
||||
title: `${emoji("🔒")} ${t("CollapsePrivacy")}`,
|
||||
body: t("PrivacyPolicy") + `${
|
||||
process.env.PLAUSIBLE_HOSTNAME ? `<br><br>${t("AnalyticsDescription")}` : ''
|
||||
env.plausibleHostname ? `<br><br>${t("AnalyticsDescription")}` : ''
|
||||
}`
|
||||
}, {
|
||||
name: "legal",
|
||||
|
@ -177,7 +177,7 @@ export default function(obj) {
|
|||
body: t("FairUse")
|
||||
}])
|
||||
},
|
||||
...(process.env.SHOW_SPONSORS ?
|
||||
...(env.showSponsors ?
|
||||
[{
|
||||
text: t("SponsoredBy"),
|
||||
classes: ["sponsored-by-text"],
|
||||
|
@ -499,7 +499,7 @@ export default function(obj) {
|
|||
}])
|
||||
})
|
||||
+ (() => {
|
||||
if (process.env.PLAUSIBLE_HOSTNAME) {
|
||||
if (env.plausibleHostname) {
|
||||
return settingsCategory({
|
||||
name: "privacy",
|
||||
title: t('PrivateAnalytics'),
|
||||
|
@ -629,7 +629,7 @@ export default function(obj) {
|
|||
</footer>
|
||||
</div>
|
||||
<script>
|
||||
let defaultApiUrl = '${process.env.API_URL || ''}';
|
||||
let defaultApiUrl = '${env.apiURL}';
|
||||
const loc = ${webLoc(t,
|
||||
[
|
||||
'ErrorNoInternet',
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import Cookie from './cookie.js';
|
||||
import { readFile, writeFile } from 'fs/promises';
|
||||
import { parse as parseSetCookie, splitCookiesString } from 'set-cookie-parser';
|
||||
import { env } from '../../../modules/config.js'
|
||||
|
||||
const WRITE_INTERVAL = 60000,
|
||||
cookiePath = process.env.COOKIE_PATH,
|
||||
cookiePath = env.cookiePath,
|
||||
COUNTER = Symbol('counter');
|
||||
|
||||
let cookies = {}, dirty = false, intervalId;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { genericUserAgent } from "../../config.js";
|
||||
import { genericUserAgent, env } from "../../config.js";
|
||||
|
||||
const shortDomain = "https://vt.tiktok.com/";
|
||||
const apiPath = "https://api22-normal-c-alisg.tiktokv.com/aweme/v1/feed/?region=US&carrier_region=US";
|
||||
|
@ -7,7 +7,7 @@ const apiUserAgent = "TikTok/338014 CFNetwork/1410.1 Darwin/22.6.0";
|
|||
export default async function(obj) {
|
||||
let postId = obj.postId ? obj.postId : false;
|
||||
|
||||
if (!process.env.TIKTOK_DEVICE_INFO) return { error: 'ErrorCouldntFetch' };
|
||||
if (!env.tiktokDeviceInfo) return { error: 'ErrorCouldntFetch' };
|
||||
|
||||
if (!postId) {
|
||||
let html = await fetch(`${shortDomain}${obj.id}`, {
|
||||
|
@ -27,8 +27,7 @@ export default async function(obj) {
|
|||
}
|
||||
if (!postId) return { error: 'ErrorCantGetID' };
|
||||
|
||||
let deviceInfo = JSON.parse(process.env.TIKTOK_DEVICE_INFO);
|
||||
deviceInfo = new URLSearchParams(deviceInfo).toString();
|
||||
let deviceInfo = new URLSearchParams(env.tiktokDeviceInfo).toString();
|
||||
|
||||
let apiURL = new URL(apiPath);
|
||||
apiURL.searchParams.append("aweme_id", postId);
|
||||
|
|
|
@ -3,7 +3,7 @@ import { randomBytes } from "crypto";
|
|||
import { nanoid } from 'nanoid';
|
||||
|
||||
import { decryptStream, encryptStream, generateHmac } from "../sub/crypto.js";
|
||||
import { streamLifespan } from "../config.js";
|
||||
import { streamLifespan, env } from "../config.js";
|
||||
import { strict as assert } from "assert";
|
||||
|
||||
const M3U_SERVICES = ['dailymotion', 'vimeo', 'rutube'];
|
||||
|
@ -54,7 +54,7 @@ export function createStream(obj) {
|
|||
encryptStream(streamData, iv, secret)
|
||||
)
|
||||
|
||||
let streamLink = new URL('/api/stream', process.env.API_URL);
|
||||
let streamLink = new URL('/api/stream', env.apiURL);
|
||||
|
||||
const params = {
|
||||
't': streamID,
|
||||
|
@ -85,7 +85,7 @@ export function createInternalStream(url, obj = {}) {
|
|||
controller: new AbortController()
|
||||
};
|
||||
|
||||
let streamLink = new URL('/api/istream', `http://127.0.0.1:${process.env.API_PORT || 9000}`);
|
||||
let streamLink = new URL('/api/istream', `http://127.0.0.1:${env.apiPort}`);
|
||||
streamLink.searchParams.set('t', streamID);
|
||||
return streamLink.toString();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import { create as contentDisposition } from "content-disposition-header";
|
|||
|
||||
import { metadataManager } from "../sub/utils.js";
|
||||
import { destroyInternalStream } from "./manage.js";
|
||||
import { ffmpegArgs } from "../config.js";
|
||||
import { env, ffmpegArgs } from "../config.js";
|
||||
import { getHeaders } from "./shared.js";
|
||||
|
||||
function toRawHeaders(headers) {
|
||||
|
@ -44,8 +44,8 @@ function pipe(from, to, done) {
|
|||
}
|
||||
|
||||
function getCommand(args) {
|
||||
if (process.env.PROCESSING_PRIORITY && process.platform !== "win32") {
|
||||
return ['nice', ['-n', process.env.PROCESSING_PRIORITY, ffmpeg, ...args]]
|
||||
if (!isNaN(env.processingPriority) && process.platform !== "win32") {
|
||||
return ['nice', ['-n', env.processingPriority.toString(), ffmpeg, ...args]]
|
||||
}
|
||||
return [ffmpeg, args]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue