Update module imports

This commit is contained in:
Cohee 2024-10-11 00:41:08 +03:00
parent a0e6030836
commit 0c8ccf1765
5 changed files with 58 additions and 39 deletions

View File

@ -1,7 +1,12 @@
import fs from 'node:fs'; import fs from 'node:fs';
import yaml from 'yaml'; import yaml from 'yaml';
import storage from 'node-persist'; import storage from 'node-persist';
import * as users from './src/users.js'; import {
initUserStorage,
getPasswordSalt,
getPasswordHash,
toKey,
} from './src/users.js';
const userAccount = process.argv[2]; const userAccount = process.argv[2];
const userPassword = process.argv[3]; const userPassword = process.argv[3];
@ -22,7 +27,7 @@ async function initStorage() {
process.exit(1); process.exit(1);
} }
await users.initUserStorage(dataRoot); await initUserStorage(dataRoot);
} }
async function main() { async function main() {
@ -31,22 +36,22 @@ async function main() {
/** /**
* @type {import('./src/users').User} * @type {import('./src/users').User}
*/ */
const user = await storage.get(users.toKey(userAccount)); const user = await storage.get(toKey(userAccount));
if (!user) { if (!user) {
console.error(`User "${userAccount}" not found.`); console.error(`User "${userAccount}" not found.`);
process.exit(1); process.exit(1);
} }
if (!user.enabled) { if (!user.enabled) {
console.log('User is disabled. Enabling...'); console.log('User is disabled. Enabling...');
user.enabled = true; user.enabled = true;
} }
if (userPassword) { if (userPassword) {
console.log('Setting new password...'); console.log('Setting new password...');
const salt = users.getPasswordSalt(); const salt = getPasswordSalt();
const passwordHash = users.getPasswordHash(userPassword, salt); const passwordHash = getPasswordHash(userPassword, salt);
user.password = passwordHash; user.password = passwordHash;
user.salt = salt; user.salt = salt;
} else { } else {
@ -55,7 +60,7 @@ async function main() {
user.salt = ''; user.salt = '';
} }
await storage.setItem(users.toKey(userAccount), user); await storage.setItem(toKey(userAccount), user);
console.log('User recovered. A program will exit now.'); console.log('User recovered. A program will exit now.');
} }

View File

@ -36,13 +36,27 @@ util.inspect.defaultOptions.maxStringLength = null;
util.inspect.defaultOptions.depth = 4; util.inspect.defaultOptions.depth = 4;
// local library imports // local library imports
import * as loader from './src/plugin-loader.js'; import{ loadPlugins } from './src/plugin-loader.js';
import * as userModule from './src/users.js'; import {
initUserStorage,
getCsrfSecret,
getCookieSecret,
getCookieSessionName,
getAllEnabledUsers,
ensurePublicDirectoriesExist,
getUserDirectoriesList,
migrateSystemPrompts,
migrateUserData,
requireLoginMiddleware,
setUserDataMiddleware,
shouldRedirectToLogin,
tryAutoLogin,
router as userDataRouter,
} from './src/users.js';
import basicAuthMiddleware from './src/middleware/basicAuth.js'; import basicAuthMiddleware from './src/middleware/basicAuth.js';
import whitelistMiddleware from './src/middleware/whitelist.js'; import whitelistMiddleware from './src/middleware/whitelist.js';
import multerMonkeyPatch from './src/middleware/multerMonkeyPatch.js'; import multerMonkeyPatch from './src/middleware/multerMonkeyPatch.js';
import initRequestProxy from './src/request-proxy.js'; import initRequestProxy from './src/request-proxy.js';
import * as contentManager from './src/endpoints/content-manager.js';
import { import {
getVersion, getVersion,
getConfigValue, getConfigValue,
@ -81,7 +95,7 @@ import { router as worldInfoRouter } from './src/endpoints/worldinfo.js';
import { router as statsRouter, init as statsInit, onExit as statsOnExit } from './src/endpoints/stats.js'; import { router as statsRouter, init as statsInit, onExit as statsOnExit } from './src/endpoints/stats.js';
import { router as backgroundsRouter } from './src/endpoints/backgrounds.js'; import { router as backgroundsRouter } from './src/endpoints/backgrounds.js';
import { router as spritesRouter } from './src/endpoints/sprites.js'; import { router as spritesRouter } from './src/endpoints/sprites.js';
import { router as contentManagerRouter } from './src/endpoints/content-manager.js'; import { router as contentManagerRouter, checkForNewContent } from './src/endpoints/content-manager.js';
import { router as settingsRouter, init as settingsInit } from './src/endpoints/settings.js'; import { router as settingsRouter, init as settingsInit } from './src/endpoints/settings.js';
import { router as stableDiffusionRouter } from './src/endpoints/stable-diffusion.js'; import { router as stableDiffusionRouter } from './src/endpoints/stable-diffusion.js';
import { router as hordeRouter } from './src/endpoints/horde.js'; import { router as hordeRouter } from './src/endpoints/horde.js';
@ -349,21 +363,21 @@ function getSessionCookieAge() {
} }
app.use(cookieSession({ app.use(cookieSession({
name: userModule.getCookieSessionName(), name: getCookieSessionName(),
sameSite: 'strict', sameSite: 'strict',
httpOnly: true, httpOnly: true,
maxAge: getSessionCookieAge(), maxAge: getSessionCookieAge(),
secret: userModule.getCookieSecret(), secret: getCookieSecret(),
})); }));
app.use(userModule.setUserDataMiddleware); app.use(setUserDataMiddleware);
// CSRF Protection // // CSRF Protection //
if (!disableCsrf) { if (!disableCsrf) {
const COOKIES_SECRET = userModule.getCookieSecret(); const COOKIES_SECRET = getCookieSecret();
const { generateToken, doubleCsrfProtection } = doubleCsrf({ const { generateToken, doubleCsrfProtection } = doubleCsrf({
getSecret: userModule.getCsrfSecret, getSecret: getCsrfSecret,
cookieName: 'X-CSRF-Token', cookieName: 'X-CSRF-Token',
cookieOptions: { cookieOptions: {
httpOnly: true, httpOnly: true,
@ -394,7 +408,7 @@ if (!disableCsrf) {
// Static files // Static files
// Host index page // Host index page
app.get('/', (request, response) => { app.get('/', (request, response) => {
if (userModule.shouldRedirectToLogin(request)) { if (shouldRedirectToLogin(request)) {
const query = request.url.split('?')[1]; const query = request.url.split('?')[1];
const redirectUrl = query ? `/login?${query}` : '/login'; const redirectUrl = query ? `/login?${query}` : '/login';
return response.redirect(redirectUrl); return response.redirect(redirectUrl);
@ -411,7 +425,7 @@ app.get('/login', async (request, response) => {
} }
try { try {
const autoLogin = await userModule.tryAutoLogin(request, basicAuthMode); const autoLogin = await tryAutoLogin(request, basicAuthMode);
if (autoLogin) { if (autoLogin) {
return response.redirect('/'); return response.redirect('/');
@ -430,7 +444,7 @@ app.use(express.static(process.cwd() + '/public', {}));
app.use('/api/users', usersPublicRouter); app.use('/api/users', usersPublicRouter);
// Everything below this line requires authentication // Everything below this line requires authentication
app.use(userModule.requireLoginMiddleware); app.use(requireLoginMiddleware);
app.get('/api/ping', (_, response) => response.sendStatus(204)); app.get('/api/ping', (_, response) => response.sendStatus(204));
// File uploads // File uploads
@ -438,7 +452,7 @@ app.use(multer({ dest: uploadsPath, limits: { fieldSize: 10 * 1024 * 1024 } }).s
app.use(multerMonkeyPatch); app.use(multerMonkeyPatch);
// User data mount // User data mount
app.use('/', userModule.router); app.use('/', userDataRouter);
// Private endpoints // Private endpoints
app.use('/api/users', usersPrivateRouter); app.use('/api/users', usersPrivateRouter);
// Admin endpoints // Admin endpoints
@ -625,15 +639,15 @@ const preSetupTasks = async function () {
} }
console.log(); console.log();
const directories = await userModule.getUserDirectoriesList(); const directories = await getUserDirectoriesList();
await contentManager.checkForNewContent(directories); await checkForNewContent(directories);
await ensureThumbnailCache(); await ensureThumbnailCache();
cleanUploads(); cleanUploads();
await settingsInit(); await settingsInit();
await statsInit(); await statsInit();
const cleanupPlugins = await loadPlugins(); const cleanupPlugins = await initializePlugins();
const consoleTitle = process.title; const consoleTitle = process.title;
let isExiting = false; let isExiting = false;
@ -740,10 +754,10 @@ const postSetupTasks = async function (v6Failed, v4Failed) {
* Loads server plugins from a directory. * Loads server plugins from a directory.
* @returns {Promise<Function>} Function to be run on server exit * @returns {Promise<Function>} Function to be run on server exit
*/ */
async function loadPlugins() { async function initializePlugins() {
try { try {
const pluginDirectory = path.join(serverDirectory, 'plugins'); const pluginDirectory = path.join(serverDirectory, 'plugins');
const cleanupPlugins = await loader.loadPlugins(app, pluginDirectory); const cleanupPlugins = await loadPlugins(app, pluginDirectory);
return cleanupPlugins; return cleanupPlugins;
} catch { } catch {
console.log('Plugin loading failed.'); console.log('Plugin loading failed.');
@ -883,7 +897,7 @@ async function verifySecuritySettings() {
logSecurityAlert('Your SillyTavern is currently insecurely open to the public. Enable whitelisting, basic authentication or user accounts.'); logSecurityAlert('Your SillyTavern is currently insecurely open to the public. Enable whitelisting, basic authentication or user accounts.');
} }
const users = await userModule.getAllEnabledUsers(); const users = await getAllEnabledUsers();
const unprotectedUsers = users.filter(x => !x.password); const unprotectedUsers = users.filter(x => !x.password);
const unprotectedAdminUsers = unprotectedUsers.filter(x => x.admin); const unprotectedAdminUsers = unprotectedUsers.filter(x => x.admin);
@ -901,10 +915,10 @@ async function verifySecuritySettings() {
} }
// User storage module needs to be initialized before starting the server // User storage module needs to be initialized before starting the server
userModule.initUserStorage(dataRoot) initUserStorage(dataRoot)
.then(userModule.ensurePublicDirectoriesExist) .then(ensurePublicDirectoriesExist)
.then(userModule.migrateUserData) .then(migrateUserData)
.then(userModule.migrateSystemPrompts) .then(migrateSystemPrompts)
.then(verifySecuritySettings) .then(verifySecuritySettings)
.then(preSetupTasks) .then(preSetupTasks)
.finally(startServer); .finally(startServer);

View File

@ -16,7 +16,7 @@ import { AVATAR_WIDTH, AVATAR_HEIGHT } from '../constants.js';
import { jsonParser, urlencodedParser } from '../express-common.js'; import { jsonParser, urlencodedParser } from '../express-common.js';
import { deepMerge, humanizedISO8601DateTime, tryParse, extractFileFromZipBuffer } from '../util.js'; import { deepMerge, humanizedISO8601DateTime, tryParse, extractFileFromZipBuffer } from '../util.js';
import { TavernCardValidator } from '../validator/TavernCardValidator.js'; import { TavernCardValidator } from '../validator/TavernCardValidator.js';
import * as characterCardParser from '../character-card-parser.js'; import { parse, write } from '../character-card-parser.js';
import { readWorldInfoFile } from './worldinfo.js'; import { readWorldInfoFile } from './worldinfo.js';
import { invalidateThumbnail } from './thumbnails.js'; import { invalidateThumbnail } from './thumbnails.js';
import { importRisuSprites } from './sprites.js'; import { importRisuSprites } from './sprites.js';
@ -38,7 +38,7 @@ async function readCharacterData(inputFile, inputFormat = 'png') {
return characterDataCache.get(cacheKey); return characterDataCache.get(cacheKey);
} }
const result = characterCardParser.parse(inputFile, inputFormat); const result = parse(inputFile, inputFormat);
characterDataCache.set(cacheKey, result); characterDataCache.set(cacheKey, result);
return result; return result;
} }
@ -77,7 +77,7 @@ async function writeCharacterData(inputFile, data, outputFile, request, crop = u
const inputImage = await getInputImage(); const inputImage = await getInputImage();
// Get the chunks // Get the chunks
const outputImage = characterCardParser.write(inputImage, data); const outputImage = write(inputImage, data);
const outputImagePath = path.join(request.user.directories.characters, `${outputFile}.png`); const outputImagePath = path.join(request.user.directories.characters, `${outputFile}.png`);
writeFileAtomicSync(outputImagePath, outputImage); writeFileAtomicSync(outputImagePath, outputImage);

View File

@ -5,15 +5,16 @@ import { Buffer } from 'node:buffer';
import express from 'express'; import express from 'express';
import fetch from 'node-fetch'; import fetch from 'node-fetch';
import sanitize from 'sanitize-filename'; import sanitize from 'sanitize-filename';
import { sync as writeFileAtomicSync } from 'write-file-atomic';
import { getConfigValue, color } from '../util.js'; import { getConfigValue, color } from '../util.js';
import { jsonParser } from '../express-common.js'; import { jsonParser } from '../express-common.js';
import { sync as writeFileAtomicSync } from 'write-file-atomic'; import { write } from '../character-card-parser.js';
const contentDirectory = path.join(process.cwd(), 'default/content'); const contentDirectory = path.join(process.cwd(), 'default/content');
const scaffoldDirectory = path.join(process.cwd(), 'default/scaffold'); const scaffoldDirectory = path.join(process.cwd(), 'default/scaffold');
const contentIndexPath = path.join(contentDirectory, 'index.json'); const contentIndexPath = path.join(contentDirectory, 'index.json');
const scaffoldIndexPath = path.join(scaffoldDirectory, 'index.json'); const scaffoldIndexPath = path.join(scaffoldDirectory, 'index.json');
import * as characterCardParser from '../character-card-parser.js';
const WHITELIST_GENERIC_URL_DOWNLOAD_SOURCES = getConfigValue('whitelistImportDomains', []); const WHITELIST_GENERIC_URL_DOWNLOAD_SOURCES = getConfigValue('whitelistImportDomains', []);
@ -397,7 +398,7 @@ async function downloadPygmalionCharacter(id) {
const avatarResult = await fetch(avatarUrl); const avatarResult = await fetch(avatarUrl);
const avatarBuffer = await avatarResult.buffer(); const avatarBuffer = await avatarResult.buffer();
const cardBuffer = characterCardParser.write(avatarBuffer, JSON.stringify(characterData)); const cardBuffer = write(avatarBuffer, JSON.stringify(characterData));
return { return {
buffer: cardBuffer, buffer: cardBuffer,

View File

@ -8,9 +8,8 @@ import express from 'express';
import { jsonParser } from '../express-common.js'; import { jsonParser } from '../express-common.js';
import { getUserAvatar, toKey, getPasswordHash, getPasswordSalt, createBackupArchive, ensurePublicDirectoriesExist, toAvatarKey } from '../users.js'; import { getUserAvatar, toKey, getPasswordHash, getPasswordSalt, createBackupArchive, ensurePublicDirectoriesExist, toAvatarKey } from '../users.js';
import { SETTINGS_FILE } from '../constants.js'; import { SETTINGS_FILE } from '../constants.js';
import * as contentManager from './content-manager.js'; import { checkForNewContent, CONTENT_TYPES } from './content-manager.js';
import { color, Cache } from '../util.js'; import { color, Cache } from '../util.js';
import { checkForNewContent } from './content-manager.js';
const RESET_CACHE = new Cache(5 * 60 * 1000); const RESET_CACHE = new Cache(5 * 60 * 1000);
@ -168,7 +167,7 @@ router.post('/reset-settings', jsonParser, async (request, response) => {
const pathToFile = path.join(request.user.directories.root, SETTINGS_FILE); const pathToFile = path.join(request.user.directories.root, SETTINGS_FILE);
await fsPromises.rm(pathToFile, { force: true }); await fsPromises.rm(pathToFile, { force: true });
await contentManager.checkForNewContent([request.user.directories], [contentManager.CONTENT_TYPES.SETTINGS]); await checkForNewContent([request.user.directories], [CONTENT_TYPES.SETTINGS]);
return response.sendStatus(204); return response.sendStatus(204);
} catch (error) { } catch (error) {