SillyTavern/server.js

370 lines
12 KiB
JavaScript
Raw Normal View History

2023-07-20 20:32:15 +03:00
#!/usr/bin/env node
2023-08-29 14:05:18 -07:00
// native node modules
2024-10-11 00:28:17 +03:00
import path from 'node:path';
import util from 'node:util';
import net from 'node:net';
import dns from 'node:dns';
2024-10-11 10:43:29 +03:00
import process from 'node:process';
2024-10-11 00:06:02 +03:00
import { fileURLToPath } from 'node:url';
2023-08-29 14:05:18 -07:00
2024-10-10 22:37:22 +03:00
import cors from 'cors';
2025-01-25 16:56:11 +02:00
import { csrfSync } from 'csrf-sync';
2024-10-10 22:37:22 +03:00
import express from 'express';
import compression from 'compression';
import cookieSession from 'cookie-session';
import multer from 'multer';
import responseTime from 'response-time';
import helmet from 'helmet';
import bodyParser from 'body-parser';
2025-02-26 14:46:54 +00:00
import open from 'open';
2023-09-10 04:12:14 +03:00
2023-08-29 14:26:59 -07:00
// local library imports
2025-02-26 14:46:54 +00:00
import { CommandLineParser } from './src/command-line.js';
import { loadPlugins } from './src/plugin-loader.js';
2024-10-11 00:41:08 +03:00
import {
initUserStorage,
getCookieSecret,
getCookieSessionName,
ensurePublicDirectoriesExist,
getUserDirectoriesList,
migrateSystemPrompts,
migrateUserData,
requireLoginMiddleware,
setUserDataMiddleware,
shouldRedirectToLogin,
2025-02-26 14:46:54 +00:00
cleanUploads,
getSessionCookieAge,
2025-02-27 21:27:39 +02:00
verifySecuritySettings,
loginPageMiddleware,
2024-10-11 00:41:08 +03:00
} from './src/users.js';
import getWebpackServeMiddleware from './src/middleware/webpack-serve.js';
2024-10-10 22:37:22 +03:00
import basicAuthMiddleware from './src/middleware/basicAuth.js';
import whitelistMiddleware from './src/middleware/whitelist.js';
import accessLoggerMiddleware, { getAccessLogPath, migrateAccessLog } from './src/middleware/accessLogWriter.js';
2024-10-10 22:37:22 +03:00
import multerMonkeyPatch from './src/middleware/multerMonkeyPatch.js';
import initRequestProxy from './src/request-proxy.js';
import getCacheBusterMiddleware from './src/middleware/cacheBuster.js';
2025-02-26 14:46:54 +00:00
import corsProxyMiddleware from './src/middleware/corsProxy.js';
2024-10-10 22:37:22 +03:00
import {
getVersion,
color,
2024-08-15 20:29:17 +03:00
removeColorFormatting,
getSeparator,
safeReadFileSync,
2025-01-15 10:02:32 -05:00
setupLogLevel,
2025-02-26 14:46:54 +00:00
setWindowTitle,
2024-10-10 22:37:22 +03:00
} from './src/util.js';
import { UPLOADS_DIRECTORY } from './src/constants.js';
import { ensureThumbnailCache } from './src/endpoints/thumbnails.js';
// Routers
import { router as usersPublicRouter } from './src/endpoints/users-public.js';
2025-02-26 14:46:54 +00:00
import { init as statsInit, onExit as statsOnExit } from './src/endpoints/stats.js';
import { checkForNewContent } from './src/endpoints/content-manager.js';
import { init as settingsInit } from './src/endpoints/settings.js';
import { redirectDeprecatedEndpoints, ServerStartup, setupPrivateEndpoints } from './src/server-startup.js';
// Unrestrict console logs display limit
util.inspect.defaultOptions.maxArrayLength = null;
util.inspect.defaultOptions.maxStringLength = null;
util.inspect.defaultOptions.depth = 4;
2023-08-29 14:12:47 -07:00
2025-02-27 21:27:39 +02:00
// Set a working directory for the server
const serverDirectory = import.meta.dirname ?? path.dirname(fileURLToPath(import.meta.url));
console.log(`Node version: ${process.version}. Running in ${process.env.NODE_ENV} environment. Server directory: ${serverDirectory}`);
process.chdir(serverDirectory);
2023-09-10 18:22:39 +03:00
// Work around a node v20.0.0, v20.1.0, and v20.2.0 bug. The issue was fixed in v20.3.0.
// https://github.com/nodejs/node/issues/47822#issuecomment-1564708870
// Safe to remove once support for Node v20 is dropped.
if (process.versions && process.versions.node && process.versions.node.match(/20\.[0-2]\.0/)) {
// @ts-ignore
if (net.setDefaultAutoSelectFamily) net.setDefaultAutoSelectFamily(false);
}
2023-07-20 20:32:15 +03:00
2025-02-27 21:27:39 +02:00
const cliArgs = new CommandLineParser().parse(process.argv);
2025-02-26 14:46:54 +00:00
globalThis.DATA_ROOT = cliArgs.dataRoot;
2025-02-27 21:27:39 +02:00
globalThis.COMMAND_LINE_ARGS = cliArgs;
2025-02-26 14:46:54 +00:00
if (!cliArgs.enableIPv6 && !cliArgs.enableIPv4) {
console.error('error: You can\'t disable all internet protocols: at least IPv6 or IPv4 must be enabled.');
process.exit(1);
}
2023-07-20 20:32:15 +03:00
2025-02-27 21:27:39 +02:00
try {
if (cliArgs.dnsPreferIPv6) {
dns.setDefaultResultOrder('ipv6first');
console.log('Preferring IPv6 for DNS resolution');
} else {
dns.setDefaultResultOrder('ipv4first');
console.log('Preferring IPv4 for DNS resolution');
}
} catch (error) {
console.warn('Failed to set DNS resolution order. Possibly unsupported in this Node version.');
}
2023-07-20 20:32:15 +03:00
const app = express();
app.use(helmet({
contentSecurityPolicy: false,
}));
2023-07-20 20:32:15 +03:00
app.use(compression());
app.use(responseTime());
// CORS Settings //
const CORS = cors({
origin: 'null',
2023-12-02 22:06:57 +02:00
methods: ['OPTIONS'],
2023-07-20 20:32:15 +03:00
});
app.use(CORS);
2025-02-26 14:46:54 +00:00
if (cliArgs.listen && cliArgs.basicAuthMode) {
app.use(basicAuthMiddleware);
}
2023-07-20 20:32:15 +03:00
2025-02-26 14:46:54 +00:00
if (cliArgs.whitelistMode) {
app.use(whitelistMiddleware());
}
2023-07-20 20:32:15 +03:00
2025-02-26 14:46:54 +00:00
if (cliArgs.listen) {
app.use(accessLoggerMiddleware());
}
2025-02-26 14:46:54 +00:00
if (cliArgs.enableCorsProxy) {
app.use(bodyParser.json({
limit: '200mb',
}));
2025-02-26 14:46:54 +00:00
app.use('/proxy/:url(*)', corsProxyMiddleware);
2023-12-02 16:04:30 +02:00
} else {
app.use('/proxy/:url(*)', async (_, res) => {
const message = 'CORS proxy is disabled. Enable it in config.yaml or use the --corsProxy flag.';
console.log(message);
res.status(404).send(message);
});
2023-11-25 21:56:57 +02:00
}
2023-07-20 20:32:15 +03:00
2024-04-07 23:08:19 +03:00
app.use(cookieSession({
2024-10-11 00:41:08 +03:00
name: getCookieSessionName(),
2024-04-07 23:08:19 +03:00
sameSite: 'strict',
httpOnly: true,
2024-07-06 14:50:36 +03:00
maxAge: getSessionCookieAge(),
secret: getCookieSecret(globalThis.DATA_ROOT),
2024-04-07 23:08:19 +03:00
}));
2023-07-20 20:32:15 +03:00
2024-10-11 00:41:08 +03:00
app.use(setUserDataMiddleware);
2024-04-07 23:08:19 +03:00
// CSRF Protection //
2025-02-26 14:46:54 +00:00
if (!cliArgs.disableCsrf) {
2025-01-25 16:56:11 +02:00
const csrfSyncProtection = csrfSync({
getTokenFromState: (req) => {
if (!req.session) {
console.error('(CSRF error) getTokenFromState: Session object not initialized');
return;
}
return req.session.csrfToken;
2024-04-07 23:08:19 +03:00
},
2025-01-25 16:56:11 +02:00
getTokenFromRequest: (req) => {
return req.headers['x-csrf-token']?.toString();
},
storeTokenInState: (req, token) => {
if (!req.session) {
console.error('(CSRF error) storeTokenInState: Session object not initialized');
return;
}
req.session.csrfToken = token;
2024-04-07 23:08:19 +03:00
},
2025-01-25 16:56:11 +02:00
size: 32,
2024-04-07 23:08:19 +03:00
});
app.get('/csrf-token', (req, res) => {
res.json({
2025-01-25 16:56:11 +02:00
'token': csrfSyncProtection.generateToken(req),
2024-04-07 23:08:19 +03:00
});
});
2025-01-25 23:20:26 +02:00
// Customize the error message
csrfSyncProtection.invalidCsrfTokenError.message = color.red('Invalid CSRF token. Please refresh the page and try again.');
csrfSyncProtection.invalidCsrfTokenError.stack = undefined;
2025-01-25 16:56:11 +02:00
app.use(csrfSyncProtection.csrfSynchronisedProtection);
2024-04-07 23:08:19 +03:00
} else {
console.warn('\nCSRF protection is disabled. This will make your server vulnerable to CSRF attacks.\n');
app.get('/csrf-token', (req, res) => {
res.json({
'token': 'disabled',
});
});
}
// Static files
// Host index page
app.get('/', getCacheBusterMiddleware(), (request, response) => {
2024-10-11 00:41:08 +03:00
if (shouldRedirectToLogin(request)) {
const query = request.url.split('?')[1];
const redirectUrl = query ? `/login?${query}` : '/login';
return response.redirect(redirectUrl);
}
return response.sendFile('index.html', { root: path.join(process.cwd(), 'public') });
});
// Host login page
2025-02-27 21:27:39 +02:00
app.get('/login', loginPageMiddleware);
// Host frontend assets
const webpackMiddleware = getWebpackServeMiddleware();
app.use(webpackMiddleware);
app.use(express.static(process.cwd() + '/public', {}));
// Public API
2024-10-10 22:37:22 +03:00
app.use('/api/users', usersPublicRouter);
// Everything below this line requires authentication
2024-10-11 00:41:08 +03:00
app.use(requireLoginMiddleware);
app.get('/api/ping', (request, response) => {
if (request.query.extend && request.session) {
request.session.touch = Date.now();
}
response.sendStatus(204);
});
// File uploads
const uploadsPath = path.join(cliArgs.dataRoot, UPLOADS_DIRECTORY);
2024-06-26 23:22:42 +03:00
app.use(multer({ dest: uploadsPath, limits: { fieldSize: 10 * 1024 * 1024 } }).single('avatar'));
2024-10-10 22:37:22 +03:00
app.use(multerMonkeyPatch);
2023-09-17 14:27:41 +03:00
app.get('/version', async function (_, response) {
const data = await getVersion();
2023-07-20 20:32:15 +03:00
response.send(data);
2023-12-02 21:11:06 +02:00
});
2023-07-20 20:32:15 +03:00
2025-02-26 14:46:54 +00:00
redirectDeprecatedEndpoints(app);
setupPrivateEndpoints(app);
2023-07-20 20:32:15 +03:00
/**
* Tasks that need to be run before the server starts listening.
2025-02-26 14:46:54 +00:00
* @returns {Promise<void>}
*/
2025-02-26 14:46:54 +00:00
async function preSetupTasks() {
2023-09-17 14:27:41 +03:00
const version = await getVersion();
2023-07-20 20:32:15 +03:00
// Print formatted header
console.log();
console.log(`SillyTavern ${version.pkgVersion}`);
console.log(version.gitBranch ? `Running '${version.gitBranch}' (${version.gitRevision}) - ${version.commitDate}` : '');
if (version.gitBranch && !version.isLatest && ['staging', 'release'].includes(version.gitBranch)) {
console.log('INFO: Currently not on the latest commit.');
2024-04-03 01:00:20 +03:00
console.log(' Run \'git pull\' to update. If you have any merge conflicts, run \'git reset --hard\' and \'git pull\' to reset your branch.');
}
console.log();
2023-07-20 20:32:15 +03:00
2024-10-11 00:41:08 +03:00
const directories = await getUserDirectoriesList();
await checkForNewContent(directories);
await ensureThumbnailCache();
2023-08-19 17:43:56 +03:00
cleanUploads();
2025-02-17 22:58:06 +02:00
migrateAccessLog();
2023-07-20 20:32:15 +03:00
2024-10-10 22:37:22 +03:00
await settingsInit();
await statsInit();
2023-12-07 13:01:51 -05:00
2025-02-27 21:27:39 +02:00
const pluginsDirectory = path.join(serverDirectory, 'plugins');
const cleanupPlugins = await loadPlugins(app, pluginsDirectory);
2024-04-13 21:51:36 +03:00
const consoleTitle = process.title;
let isExiting = false;
2023-12-23 19:05:21 +02:00
const exitProcess = async () => {
if (isExiting) return;
isExiting = true;
2024-10-10 22:37:22 +03:00
await statsOnExit();
2023-12-23 19:03:13 +02:00
if (typeof cleanupPlugins === 'function') {
2023-12-23 19:05:21 +02:00
await cleanupPlugins();
2023-12-23 19:03:13 +02:00
}
2024-04-13 21:51:36 +03:00
setWindowTitle(consoleTitle);
2023-12-07 13:01:51 -05:00
process.exit();
};
2023-07-20 20:32:15 +03:00
// Set up event listeners for a graceful shutdown
2023-12-07 13:01:51 -05:00
process.on('SIGINT', exitProcess);
process.on('SIGTERM', exitProcess);
2023-07-20 20:32:15 +03:00
process.on('uncaughtException', (err) => {
console.error('Uncaught exception:', err);
2023-12-07 13:01:51 -05:00
exitProcess();
2023-07-20 20:32:15 +03:00
});
// Add request proxy.
2025-02-26 14:46:54 +00:00
initRequestProxy({ enabled: cliArgs.requestProxyEnabled, url: cliArgs.requestProxyUrl, bypass: cliArgs.requestProxyBypass });
// Wait for frontend libs to compile
2024-11-29 00:13:43 +02:00
await webpackMiddleware.runWebpackCompiler();
support for Ipv6 (#2593) * started adding v6 support * added error checking and change messages to the user * fixed lsp caused issue * fixed formatting error * added error handling to https * fixed formatting errors * brought server starting into different func and added enable v6 and v4 * added error checking for disabling both v6 and v4. added option to prefer v6 for dns. added that stuff to the default config * fixed dumb bug * changed to settings named disable ipvx * fixed failed ips still showing as listening * fixed error handling * changed ip protocol config layout * small const name changes * fixed no error if only available protocol fails, and changed wording of some errors * fixed error handling saying 'non-fatal error' for protocol fail even when it's the only one enabled * moved more logic to listen error handler * fixed eslint issues * added more info on when to prefer ipv6 for dns * in conf changed one 'ipv6' to 'IPv6' for consistency * changed error message and redid how starting the server works * removed unneeded log * removed unneeded log * removed unneeded comments * fixed errors * fixed errors * fixed errors * changed the wording of ip related error messages * removed empty lines * changed to .finally(startServer); * removed some whitespace * disabled ipv6 by default ╯︿╰ and changed some message wording * added auto mode for autorun hostname and changed formatting for listening log and added goto message with autorun url * added autorun port override * removed debug log * changed formatting * added cli args to ipv6 and autorun stuff * moved cli args around * changed formatting * changed colors for ip * added avoidLocalhost cli arg * changed formatting * changed to not print protocol on listening * added config option for avoid localhost and changed formatting of messages * fixed avoid localhost config option * Fix ipv4 color --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2024-08-15 10:12:12 -07:00
}
/**
* Tasks that need to be run after the server starts listening.
2025-02-26 14:46:54 +00:00
* @param {import('./src/server-startup.js').ServerStartupResult} result The result of the server startup
* @returns {Promise<void>}
*/
async function postSetupTasks(result) {
const autorunHostname = await cliArgs.getAutorunHostname(result);
2025-02-26 14:46:54 +00:00
const autorunUrl = cliArgs.getAutorunUrl(autorunHostname);
2023-07-20 20:32:15 +03:00
2025-02-26 14:46:54 +00:00
if (cliArgs.autorun) {
console.log('Launching in a browser...');
await open(autorunUrl.toString());
2025-02-26 14:46:54 +00:00
}
2024-04-14 01:39:28 +08:00
setWindowTitle('SillyTavern WebServer');
2024-04-13 00:51:34 +08:00
support for Ipv6 (#2593) * started adding v6 support * added error checking and change messages to the user * fixed lsp caused issue * fixed formatting error * added error handling to https * fixed formatting errors * brought server starting into different func and added enable v6 and v4 * added error checking for disabling both v6 and v4. added option to prefer v6 for dns. added that stuff to the default config * fixed dumb bug * changed to settings named disable ipvx * fixed failed ips still showing as listening * fixed error handling * changed ip protocol config layout * small const name changes * fixed no error if only available protocol fails, and changed wording of some errors * fixed error handling saying 'non-fatal error' for protocol fail even when it's the only one enabled * moved more logic to listen error handler * fixed eslint issues * added more info on when to prefer ipv6 for dns * in conf changed one 'ipv6' to 'IPv6' for consistency * changed error message and redid how starting the server works * removed unneeded log * removed unneeded log * removed unneeded comments * fixed errors * fixed errors * fixed errors * changed the wording of ip related error messages * removed empty lines * changed to .finally(startServer); * removed some whitespace * disabled ipv6 by default ╯︿╰ and changed some message wording * added auto mode for autorun hostname and changed formatting for listening log and added goto message with autorun url * added autorun port override * removed debug log * changed formatting * added cli args to ipv6 and autorun stuff * moved cli args around * changed formatting * changed colors for ip * added avoidLocalhost cli arg * changed formatting * changed to not print protocol on listening * added config option for avoid localhost and changed formatting of messages * fixed avoid localhost config option * Fix ipv4 color --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2024-08-15 10:12:12 -07:00
let logListen = 'SillyTavern is listening on';
if (result.useIPv6 && !result.v6Failed) {
2025-01-10 03:58:15 -08:00
logListen += color.green(
2025-02-26 14:46:54 +00:00
' IPv6: ' + cliArgs.getIPv6ListenUrl().host,
2025-01-10 03:58:15 -08:00
);
support for Ipv6 (#2593) * started adding v6 support * added error checking and change messages to the user * fixed lsp caused issue * fixed formatting error * added error handling to https * fixed formatting errors * brought server starting into different func and added enable v6 and v4 * added error checking for disabling both v6 and v4. added option to prefer v6 for dns. added that stuff to the default config * fixed dumb bug * changed to settings named disable ipvx * fixed failed ips still showing as listening * fixed error handling * changed ip protocol config layout * small const name changes * fixed no error if only available protocol fails, and changed wording of some errors * fixed error handling saying 'non-fatal error' for protocol fail even when it's the only one enabled * moved more logic to listen error handler * fixed eslint issues * added more info on when to prefer ipv6 for dns * in conf changed one 'ipv6' to 'IPv6' for consistency * changed error message and redid how starting the server works * removed unneeded log * removed unneeded log * removed unneeded comments * fixed errors * fixed errors * fixed errors * changed the wording of ip related error messages * removed empty lines * changed to .finally(startServer); * removed some whitespace * disabled ipv6 by default ╯︿╰ and changed some message wording * added auto mode for autorun hostname and changed formatting for listening log and added goto message with autorun url * added autorun port override * removed debug log * changed formatting * added cli args to ipv6 and autorun stuff * moved cli args around * changed formatting * changed colors for ip * added avoidLocalhost cli arg * changed formatting * changed to not print protocol on listening * added config option for avoid localhost and changed formatting of messages * fixed avoid localhost config option * Fix ipv4 color --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2024-08-15 10:12:12 -07:00
}
if (result.useIPv4 && !result.v4Failed) {
2025-01-10 03:58:15 -08:00
logListen += color.green(
2025-02-26 14:46:54 +00:00
' IPv4: ' + cliArgs.getIPv4ListenUrl().host,
2025-01-10 03:58:15 -08:00
);
support for Ipv6 (#2593) * started adding v6 support * added error checking and change messages to the user * fixed lsp caused issue * fixed formatting error * added error handling to https * fixed formatting errors * brought server starting into different func and added enable v6 and v4 * added error checking for disabling both v6 and v4. added option to prefer v6 for dns. added that stuff to the default config * fixed dumb bug * changed to settings named disable ipvx * fixed failed ips still showing as listening * fixed error handling * changed ip protocol config layout * small const name changes * fixed no error if only available protocol fails, and changed wording of some errors * fixed error handling saying 'non-fatal error' for protocol fail even when it's the only one enabled * moved more logic to listen error handler * fixed eslint issues * added more info on when to prefer ipv6 for dns * in conf changed one 'ipv6' to 'IPv6' for consistency * changed error message and redid how starting the server works * removed unneeded log * removed unneeded log * removed unneeded comments * fixed errors * fixed errors * fixed errors * changed the wording of ip related error messages * removed empty lines * changed to .finally(startServer); * removed some whitespace * disabled ipv6 by default ╯︿╰ and changed some message wording * added auto mode for autorun hostname and changed formatting for listening log and added goto message with autorun url * added autorun port override * removed debug log * changed formatting * added cli args to ipv6 and autorun stuff * moved cli args around * changed formatting * changed colors for ip * added avoidLocalhost cli arg * changed formatting * changed to not print protocol on listening * added config option for avoid localhost and changed formatting of messages * fixed avoid localhost config option * Fix ipv4 color --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2024-08-15 10:12:12 -07:00
}
2024-08-15 20:29:17 +03:00
const goToLog = 'Go to: ' + color.blue(autorunUrl) + ' to open SillyTavern';
const plainGoToLog = removeColorFormatting(goToLog);
support for Ipv6 (#2593) * started adding v6 support * added error checking and change messages to the user * fixed lsp caused issue * fixed formatting error * added error handling to https * fixed formatting errors * brought server starting into different func and added enable v6 and v4 * added error checking for disabling both v6 and v4. added option to prefer v6 for dns. added that stuff to the default config * fixed dumb bug * changed to settings named disable ipvx * fixed failed ips still showing as listening * fixed error handling * changed ip protocol config layout * small const name changes * fixed no error if only available protocol fails, and changed wording of some errors * fixed error handling saying 'non-fatal error' for protocol fail even when it's the only one enabled * moved more logic to listen error handler * fixed eslint issues * added more info on when to prefer ipv6 for dns * in conf changed one 'ipv6' to 'IPv6' for consistency * changed error message and redid how starting the server works * removed unneeded log * removed unneeded log * removed unneeded comments * fixed errors * fixed errors * fixed errors * changed the wording of ip related error messages * removed empty lines * changed to .finally(startServer); * removed some whitespace * disabled ipv6 by default ╯︿╰ and changed some message wording * added auto mode for autorun hostname and changed formatting for listening log and added goto message with autorun url * added autorun port override * removed debug log * changed formatting * added cli args to ipv6 and autorun stuff * moved cli args around * changed formatting * changed colors for ip * added avoidLocalhost cli arg * changed formatting * changed to not print protocol on listening * added config option for avoid localhost and changed formatting of messages * fixed avoid localhost config option * Fix ipv4 color --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2024-08-15 10:12:12 -07:00
console.log(logListen);
2025-02-26 14:46:54 +00:00
if (cliArgs.listen) {
2025-02-14 23:53:31 +02:00
console.log();
console.log('To limit connections to internal localhost only ([::1] or 127.0.0.1), change the setting in config.yaml to "listen: false".');
2025-02-17 22:58:06 +02:00
console.log('Check the "access.log" file in the data directory to inspect incoming connections:', color.green(getAccessLogPath()));
2025-02-14 23:53:31 +02:00
}
support for Ipv6 (#2593) * started adding v6 support * added error checking and change messages to the user * fixed lsp caused issue * fixed formatting error * added error handling to https * fixed formatting errors * brought server starting into different func and added enable v6 and v4 * added error checking for disabling both v6 and v4. added option to prefer v6 for dns. added that stuff to the default config * fixed dumb bug * changed to settings named disable ipvx * fixed failed ips still showing as listening * fixed error handling * changed ip protocol config layout * small const name changes * fixed no error if only available protocol fails, and changed wording of some errors * fixed error handling saying 'non-fatal error' for protocol fail even when it's the only one enabled * moved more logic to listen error handler * fixed eslint issues * added more info on when to prefer ipv6 for dns * in conf changed one 'ipv6' to 'IPv6' for consistency * changed error message and redid how starting the server works * removed unneeded log * removed unneeded log * removed unneeded comments * fixed errors * fixed errors * fixed errors * changed the wording of ip related error messages * removed empty lines * changed to .finally(startServer); * removed some whitespace * disabled ipv6 by default ╯︿╰ and changed some message wording * added auto mode for autorun hostname and changed formatting for listening log and added goto message with autorun url * added autorun port override * removed debug log * changed formatting * added cli args to ipv6 and autorun stuff * moved cli args around * changed formatting * changed colors for ip * added avoidLocalhost cli arg * changed formatting * changed to not print protocol on listening * added config option for avoid localhost and changed formatting of messages * fixed avoid localhost config option * Fix ipv4 color --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2024-08-15 10:12:12 -07:00
console.log('\n' + getSeparator(plainGoToLog.length) + '\n');
console.log(goToLog);
console.log('\n' + getSeparator(plainGoToLog.length) + '\n');
2023-07-20 20:32:15 +03:00
2025-01-15 10:02:32 -05:00
setupLogLevel();
2025-02-26 14:46:54 +00:00
}
2023-07-20 20:32:15 +03:00
/**
* Registers a not-found error response if a not-found error page exists. Should only be called after all other middlewares have been registered.
*/
function apply404Middleware() {
const notFoundWebpage = safeReadFileSync('./public/error/url-not-found.html') ?? '';
app.use((req, res) => {
res.status(404).send(notFoundWebpage);
});
}
// User storage module needs to be initialized before starting the server
initUserStorage(globalThis.DATA_ROOT)
2024-10-11 00:41:08 +03:00
.then(ensurePublicDirectoriesExist)
.then(migrateUserData)
.then(migrateSystemPrompts)
.then(verifySecuritySettings)
.then(preSetupTasks)
.then(apply404Middleware)
.then(() => new ServerStartup(app, cliArgs).start())
2025-02-26 14:46:54 +00:00
.then(postSetupTasks);