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 { Bright, Green, Red } from "./modules/sub/consoleText.js";
|
||||||
import { getCurrentBranch, shortCommit } from "./modules/sub/currentCommit.js";
|
import { getCurrentBranch, shortCommit } from "./modules/sub/currentCommit.js";
|
||||||
import { loadLoc } from "./localization/manager.js";
|
import { loadLoc } from "./localization/manager.js";
|
||||||
|
import { mode } from "./modules/config.js"
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
@ -22,13 +23,10 @@ app.disable('x-powered-by');
|
||||||
|
|
||||||
await loadLoc();
|
await loadLoc();
|
||||||
|
|
||||||
const apiMode = process.env.API_URL && !process.env.WEB_URL;
|
if (mode === 'API') {
|
||||||
const webMode = process.env.WEB_URL && process.env.API_URL;
|
|
||||||
|
|
||||||
if (apiMode) {
|
|
||||||
const { runAPI } = await import('./core/api.js');
|
const { runAPI } = await import('./core/api.js');
|
||||||
runAPI(express, app, gitCommit, gitBranch, __dirname)
|
runAPI(express, app, gitCommit, gitBranch, __dirname)
|
||||||
} else if (webMode) {
|
} else if (mode === 'WEB') {
|
||||||
const { runWeb } = await import('./core/web.js');
|
const { runWeb } = await import('./core/web.js');
|
||||||
await runWeb(express, app, gitCommit, gitBranch, __dirname)
|
await runWeb(express, app, gitCommit, gitBranch, __dirname)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { randomBytes } from "crypto";
|
||||||
|
|
||||||
const ipSalt = randomBytes(64).toString('hex');
|
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 { getJSON } from "../modules/api.js";
|
||||||
import { apiJSON, checkJSONPost, getIP, languageCode } from "../modules/sub/utils.js";
|
import { apiJSON, checkJSONPost, getIP, languageCode } from "../modules/sub/utils.js";
|
||||||
import { Bright, Cyan } from "../modules/sub/consoleText.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";
|
import { verifyStream, getInternalStream } from "../modules/stream/manage.js";
|
||||||
|
|
||||||
export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
||||||
const corsConfig = process.env.CORS_WILDCARD === '0' ? {
|
const corsConfig = !env.corsWildcard ? {
|
||||||
origin: process.env.CORS_URL,
|
origin: env.corsURL,
|
||||||
optionsSuccessStatus: 200
|
optionsSuccessStatus: 200
|
||||||
} : {};
|
} : {};
|
||||||
|
|
||||||
|
@ -163,9 +163,9 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
||||||
version: version,
|
version: version,
|
||||||
commit: gitCommit,
|
commit: gitCommit,
|
||||||
branch: gitBranch,
|
branch: gitBranch,
|
||||||
name: process.env.API_NAME || "unknown",
|
name: env.apiName,
|
||||||
url: process.env.API_URL,
|
url: env.apiURL,
|
||||||
cors: process.env?.CORS_WILDCARD === "0" ? 0 : 1,
|
cors: Number(env.corsWildcard),
|
||||||
startTime: `${startTimestamp}`
|
startTime: `${startTimestamp}`
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
|
@ -194,12 +194,12 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
||||||
res.redirect('/api/json')
|
res.redirect('/api/json')
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(process.env.API_PORT || 9000, () => {
|
app.listen(env.apiPort, () => {
|
||||||
console.log(`\n` +
|
console.log(`\n` +
|
||||||
`${Cyan("cobalt")} API ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` +
|
`${Cyan("cobalt")} API ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` +
|
||||||
`Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` +
|
`Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` +
|
||||||
`URL: ${Cyan(`${process.env.API_URL}`)}\n` +
|
`URL: ${Cyan(`${env.apiURL}`)}\n` +
|
||||||
`Port: ${process.env.API_PORT || 9000}\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 { apiJSON, languageCode } from "../modules/sub/utils.js";
|
||||||
import { Bright, Cyan } from "../modules/sub/consoleText.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('/')
|
return res.redirect('/')
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(process.env.WEB_PORT || 9001, () => {
|
app.listen(env.webPort, () => {
|
||||||
console.log(`\n` +
|
console.log(`\n` +
|
||||||
`${Cyan("cobalt")} WEB ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` +
|
`${Cyan("cobalt")} WEB ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` +
|
||||||
`Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` +
|
`Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` +
|
||||||
`URL: ${Cyan(`${process.env.WEB_URL}`)}\n` +
|
`URL: ${Cyan(`${env.webURL}`)}\n` +
|
||||||
`Port: ${process.env.WEB_PORT || 9001}\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
|
export const
|
||||||
services = servicesConfigJson.config,
|
services = servicesConfigJson.config,
|
||||||
audioIgnore = servicesConfigJson.audioIgnore,
|
audioIgnore = servicesConfigJson.audioIgnore,
|
||||||
|
@ -26,4 +51,7 @@ export const
|
||||||
supportedAudio = config.supportedAudio,
|
supportedAudio = config.supportedAudio,
|
||||||
celebrations = config.celebrations,
|
celebrations = config.celebrations,
|
||||||
links = config.links,
|
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 emoji from "../emoji.js";
|
||||||
import { loadFile } from "../sub/loadFromFs.js";
|
import { loadFile } from "../sub/loadFromFs.js";
|
||||||
|
|
||||||
|
@ -266,5 +266,5 @@ export function sponsoredList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function betaTag() {
|
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 { 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 { getCommitInfo } from "../sub/currentCommit.js";
|
||||||
import loc from "../../localization/manager.js";
|
import loc from "../../localization/manager.js";
|
||||||
import emoji from "../emoji.js";
|
import emoji from "../emoji.js";
|
||||||
|
@ -48,10 +48,10 @@ export default function(obj) {
|
||||||
|
|
||||||
<title>${t("AppTitleCobalt")}</title>
|
<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:title" content="${t("AppTitleCobalt")}">
|
||||||
<meta property="og:description" content="${t('EmbedBriefDescription')}">
|
<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="title" content="${t("AppTitleCobalt")}">
|
||||||
<meta name="description" content="${t('AboutSummary')}">
|
<meta name="description" content="${t('AboutSummary')}">
|
||||||
<meta name="theme-color" content="#000000">
|
<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/error.png" as="image">
|
||||||
<link rel="preload" href="assets/meowbalt/question.png" as="image">
|
<link rel="preload" href="assets/meowbalt/question.png" as="image">
|
||||||
|
|
||||||
${process.env.PLAUSIBLE_HOSTNAME ?
|
${env.plausibleHostname ?
|
||||||
`<script
|
`<script
|
||||||
defer
|
defer
|
||||||
data-domain="${new URL(process.env.WEB_URL).hostname}"
|
data-domain="${new URL(env.webURL).hostname}"
|
||||||
src="https://${process.env.PLAUSIBLE_HOSTNAME}/js/script.js"
|
src="https://${env.plausibleHostname}/js/script.js"
|
||||||
></script>`
|
></script>`
|
||||||
: ''}
|
: ''}
|
||||||
</head>
|
</head>
|
||||||
|
@ -169,7 +169,7 @@ export default function(obj) {
|
||||||
name: "privacy",
|
name: "privacy",
|
||||||
title: `${emoji("🔒")} ${t("CollapsePrivacy")}`,
|
title: `${emoji("🔒")} ${t("CollapsePrivacy")}`,
|
||||||
body: t("PrivacyPolicy") + `${
|
body: t("PrivacyPolicy") + `${
|
||||||
process.env.PLAUSIBLE_HOSTNAME ? `<br><br>${t("AnalyticsDescription")}` : ''
|
env.plausibleHostname ? `<br><br>${t("AnalyticsDescription")}` : ''
|
||||||
}`
|
}`
|
||||||
}, {
|
}, {
|
||||||
name: "legal",
|
name: "legal",
|
||||||
|
@ -177,7 +177,7 @@ export default function(obj) {
|
||||||
body: t("FairUse")
|
body: t("FairUse")
|
||||||
}])
|
}])
|
||||||
},
|
},
|
||||||
...(process.env.SHOW_SPONSORS ?
|
...(env.showSponsors ?
|
||||||
[{
|
[{
|
||||||
text: t("SponsoredBy"),
|
text: t("SponsoredBy"),
|
||||||
classes: ["sponsored-by-text"],
|
classes: ["sponsored-by-text"],
|
||||||
|
@ -499,7 +499,7 @@ export default function(obj) {
|
||||||
}])
|
}])
|
||||||
})
|
})
|
||||||
+ (() => {
|
+ (() => {
|
||||||
if (process.env.PLAUSIBLE_HOSTNAME) {
|
if (env.plausibleHostname) {
|
||||||
return settingsCategory({
|
return settingsCategory({
|
||||||
name: "privacy",
|
name: "privacy",
|
||||||
title: t('PrivateAnalytics'),
|
title: t('PrivateAnalytics'),
|
||||||
|
@ -629,7 +629,7 @@ export default function(obj) {
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
let defaultApiUrl = '${process.env.API_URL || ''}';
|
let defaultApiUrl = '${env.apiURL}';
|
||||||
const loc = ${webLoc(t,
|
const loc = ${webLoc(t,
|
||||||
[
|
[
|
||||||
'ErrorNoInternet',
|
'ErrorNoInternet',
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import Cookie from './cookie.js';
|
import Cookie from './cookie.js';
|
||||||
import { readFile, writeFile } from 'fs/promises';
|
import { readFile, writeFile } from 'fs/promises';
|
||||||
import { parse as parseSetCookie, splitCookiesString } from 'set-cookie-parser';
|
import { parse as parseSetCookie, splitCookiesString } from 'set-cookie-parser';
|
||||||
|
import { env } from '../../../modules/config.js'
|
||||||
|
|
||||||
const WRITE_INTERVAL = 60000,
|
const WRITE_INTERVAL = 60000,
|
||||||
cookiePath = process.env.COOKIE_PATH,
|
cookiePath = env.cookiePath,
|
||||||
COUNTER = Symbol('counter');
|
COUNTER = Symbol('counter');
|
||||||
|
|
||||||
let cookies = {}, dirty = false, intervalId;
|
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 shortDomain = "https://vt.tiktok.com/";
|
||||||
const apiPath = "https://api22-normal-c-alisg.tiktokv.com/aweme/v1/feed/?region=US&carrier_region=US";
|
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) {
|
export default async function(obj) {
|
||||||
let postId = obj.postId ? obj.postId : false;
|
let postId = obj.postId ? obj.postId : false;
|
||||||
|
|
||||||
if (!process.env.TIKTOK_DEVICE_INFO) return { error: 'ErrorCouldntFetch' };
|
if (!env.tiktokDeviceInfo) return { error: 'ErrorCouldntFetch' };
|
||||||
|
|
||||||
if (!postId) {
|
if (!postId) {
|
||||||
let html = await fetch(`${shortDomain}${obj.id}`, {
|
let html = await fetch(`${shortDomain}${obj.id}`, {
|
||||||
|
@ -27,8 +27,7 @@ export default async function(obj) {
|
||||||
}
|
}
|
||||||
if (!postId) return { error: 'ErrorCantGetID' };
|
if (!postId) return { error: 'ErrorCantGetID' };
|
||||||
|
|
||||||
let deviceInfo = JSON.parse(process.env.TIKTOK_DEVICE_INFO);
|
let deviceInfo = new URLSearchParams(env.tiktokDeviceInfo).toString();
|
||||||
deviceInfo = new URLSearchParams(deviceInfo).toString();
|
|
||||||
|
|
||||||
let apiURL = new URL(apiPath);
|
let apiURL = new URL(apiPath);
|
||||||
apiURL.searchParams.append("aweme_id", postId);
|
apiURL.searchParams.append("aweme_id", postId);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { randomBytes } from "crypto";
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
|
|
||||||
import { decryptStream, encryptStream, generateHmac } from "../sub/crypto.js";
|
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";
|
import { strict as assert } from "assert";
|
||||||
|
|
||||||
const M3U_SERVICES = ['dailymotion', 'vimeo', 'rutube'];
|
const M3U_SERVICES = ['dailymotion', 'vimeo', 'rutube'];
|
||||||
|
@ -54,7 +54,7 @@ export function createStream(obj) {
|
||||||
encryptStream(streamData, iv, secret)
|
encryptStream(streamData, iv, secret)
|
||||||
)
|
)
|
||||||
|
|
||||||
let streamLink = new URL('/api/stream', process.env.API_URL);
|
let streamLink = new URL('/api/stream', env.apiURL);
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
't': streamID,
|
't': streamID,
|
||||||
|
@ -85,7 +85,7 @@ export function createInternalStream(url, obj = {}) {
|
||||||
controller: new AbortController()
|
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);
|
streamLink.searchParams.set('t', streamID);
|
||||||
return streamLink.toString();
|
return streamLink.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { create as contentDisposition } from "content-disposition-header";
|
||||||
|
|
||||||
import { metadataManager } from "../sub/utils.js";
|
import { metadataManager } from "../sub/utils.js";
|
||||||
import { destroyInternalStream } from "./manage.js";
|
import { destroyInternalStream } from "./manage.js";
|
||||||
import { ffmpegArgs } from "../config.js";
|
import { env, ffmpegArgs } from "../config.js";
|
||||||
import { getHeaders } from "./shared.js";
|
import { getHeaders } from "./shared.js";
|
||||||
|
|
||||||
function toRawHeaders(headers) {
|
function toRawHeaders(headers) {
|
||||||
|
@ -44,8 +44,8 @@ function pipe(from, to, done) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCommand(args) {
|
function getCommand(args) {
|
||||||
if (process.env.PROCESSING_PRIORITY && process.platform !== "win32") {
|
if (!isNaN(env.processingPriority) && process.platform !== "win32") {
|
||||||
return ['nice', ['-n', process.env.PROCESSING_PRIORITY, ffmpeg, ...args]]
|
return ['nice', ['-n', env.processingPriority.toString(), ffmpeg, ...args]]
|
||||||
}
|
}
|
||||||
return [ffmpeg, args]
|
return [ffmpeg, args]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue