Update module imports

0c8ccf176511a33fb84e1528af57e17027fa733c

Cohee <18619528+Cohee1207@users.noreply.github.com>

5 files changed, +57 -38Showing whitespace changes
recover.js+11 -6
@@ -1,7 +1,12 @@
1import fs from 'node:fs';1import fs from 'node:fs';
2import yaml from 'yaml';2import yaml from 'yaml';
3import storage from 'node-persist';3import storage from 'node-persist';
4import * as users from './src/users.js';4import {
5 initUserStorage,
6 getPasswordSalt,
7 getPasswordHash,
8 toKey,
9} from './src/users.js';
510
6const userAccount = process.argv[2];11const userAccount = process.argv[2];
7const userPassword = process.argv[3];12const userPassword = process.argv[3];
@@ -22,7 +27,7 @@ async function initStorage() {
22 process.exit(1);27 process.exit(1);
23 }28 }
2429
25 await users.initUserStorage(dataRoot);30 await initUserStorage(dataRoot);
26}31}
2732
28async function main() {33async function main() {
@@ -31,7 +36,7 @@ async function main() {
31 /**36 /**
32 * @type {import('./src/users').User}37 * @type {import('./src/users').User}
33 */38 */
34 const user = await storage.get(users.toKey(userAccount));39 const user = await storage.get(toKey(userAccount));
3540
36 if (!user) {41 if (!user) {
37 console.error(`User "${userAccount}" not found.`);42 console.error(`User "${userAccount}" not found.`);
@@ -45,8 +50,8 @@ async function main() {
4550
46 if (userPassword) {51 if (userPassword) {
47 console.log('Setting new password...');52 console.log('Setting new password...');
48 const salt = users.getPasswordSalt();53 const salt = getPasswordSalt();
49 const passwordHash = users.getPasswordHash(userPassword, salt);54 const passwordHash = getPasswordHash(userPassword, salt);
50 user.password = passwordHash;55 user.password = passwordHash;
51 user.salt = salt;56 user.salt = salt;
52 } else {57 } else {
@@ -55,7 +60,7 @@ async function main() {
55 user.salt = '';60 user.salt = '';
56 }61 }
5762
58 await storage.setItem(users.toKey(userAccount), user);63 await storage.setItem(toKey(userAccount), user);
59 console.log('User recovered. A program will exit now.');64 console.log('User recovered. A program will exit now.');
60}65}
6166
server.js+37 -23
@@ -36,13 +36,27 @@ util.inspect.defaultOptions.maxStringLength = null;
36util.inspect.defaultOptions.depth = 4;36util.inspect.defaultOptions.depth = 4;
3737
38// local library imports38// local library imports
39import * as loader from './src/plugin-loader.js';39import{ loadPlugins } from './src/plugin-loader.js';
40import * as userModule from './src/users.js';40import {
41 initUserStorage,
42 getCsrfSecret,
43 getCookieSecret,
44 getCookieSessionName,
45 getAllEnabledUsers,
46 ensurePublicDirectoriesExist,
47 getUserDirectoriesList,
48 migrateSystemPrompts,
49 migrateUserData,
50 requireLoginMiddleware,
51 setUserDataMiddleware,
52 shouldRedirectToLogin,
53 tryAutoLogin,
54 router as userDataRouter,
55} from './src/users.js';
41import basicAuthMiddleware from './src/middleware/basicAuth.js';56import basicAuthMiddleware from './src/middleware/basicAuth.js';
42import whitelistMiddleware from './src/middleware/whitelist.js';57import whitelistMiddleware from './src/middleware/whitelist.js';
43import multerMonkeyPatch from './src/middleware/multerMonkeyPatch.js';58import multerMonkeyPatch from './src/middleware/multerMonkeyPatch.js';
44import initRequestProxy from './src/request-proxy.js';59import initRequestProxy from './src/request-proxy.js';
45import * as contentManager from './src/endpoints/content-manager.js';
46import {60import {
47 getVersion,61 getVersion,
48 getConfigValue,62 getConfigValue,
@@ -81,7 +95,7 @@ import { router as worldInfoRouter } from './src/endpoints/worldinfo.js';
81import { router as statsRouter, init as statsInit, onExit as statsOnExit } from './src/endpoints/stats.js';95import { router as statsRouter, init as statsInit, onExit as statsOnExit } from './src/endpoints/stats.js';
82import { router as backgroundsRouter } from './src/endpoints/backgrounds.js';96import { router as backgroundsRouter } from './src/endpoints/backgrounds.js';
83import { router as spritesRouter } from './src/endpoints/sprites.js';97import { router as spritesRouter } from './src/endpoints/sprites.js';
84import { router as contentManagerRouter } from './src/endpoints/content-manager.js';98import { router as contentManagerRouter, checkForNewContent } from './src/endpoints/content-manager.js';
85import { router as settingsRouter, init as settingsInit } from './src/endpoints/settings.js';99import { router as settingsRouter, init as settingsInit } from './src/endpoints/settings.js';
86import { router as stableDiffusionRouter } from './src/endpoints/stable-diffusion.js';100import { router as stableDiffusionRouter } from './src/endpoints/stable-diffusion.js';
87import { router as hordeRouter } from './src/endpoints/horde.js';101import { router as hordeRouter } from './src/endpoints/horde.js';
@@ -349,21 +363,21 @@ function getSessionCookieAge() {
349}363}
350364
351app.use(cookieSession({365app.use(cookieSession({
352 name: userModule.getCookieSessionName(),366 name: getCookieSessionName(),
353 sameSite: 'strict',367 sameSite: 'strict',
354 httpOnly: true,368 httpOnly: true,
355 maxAge: getSessionCookieAge(),369 maxAge: getSessionCookieAge(),
356 secret: userModule.getCookieSecret(),370 secret: getCookieSecret(),
357}));371}));
358372
359app.use(userModule.setUserDataMiddleware);373app.use(setUserDataMiddleware);
360374
361// CSRF Protection //375// CSRF Protection //
362if (!disableCsrf) {376if (!disableCsrf) {
363 const COOKIES_SECRET = userModule.getCookieSecret();377 const COOKIES_SECRET = getCookieSecret();
364378
365 const { generateToken, doubleCsrfProtection } = doubleCsrf({379 const { generateToken, doubleCsrfProtection } = doubleCsrf({
366 getSecret: userModule.getCsrfSecret,380 getSecret: getCsrfSecret,
367 cookieName: 'X-CSRF-Token',381 cookieName: 'X-CSRF-Token',
368 cookieOptions: {382 cookieOptions: {
369 httpOnly: true,383 httpOnly: true,
@@ -394,7 +408,7 @@ if (!disableCsrf) {
394// Static files408// Static files
395// Host index page409// Host index page
396app.get('/', (request, response) => {410app.get('/', (request, response) => {
397 if (userModule.shouldRedirectToLogin(request)) {411 if (shouldRedirectToLogin(request)) {
398 const query = request.url.split('?')[1];412 const query = request.url.split('?')[1];
399 const redirectUrl = query ? `/login?${query}` : '/login';413 const redirectUrl = query ? `/login?${query}` : '/login';
400 return response.redirect(redirectUrl);414 return response.redirect(redirectUrl);
@@ -411,7 +425,7 @@ app.get('/login', async (request, response) => {
411 }425 }
412426
413 try {427 try {
414 const autoLogin = await userModule.tryAutoLogin(request, basicAuthMode);428 const autoLogin = await tryAutoLogin(request, basicAuthMode);
415429
416 if (autoLogin) {430 if (autoLogin) {
417 return response.redirect('/');431 return response.redirect('/');
@@ -430,7 +444,7 @@ app.use(express.static(process.cwd() + '/public', {}));
430app.use('/api/users', usersPublicRouter);444app.use('/api/users', usersPublicRouter);
431445
432// Everything below this line requires authentication446// Everything below this line requires authentication
433app.use(userModule.requireLoginMiddleware);447app.use(requireLoginMiddleware);
434app.get('/api/ping', (_, response) => response.sendStatus(204));448app.get('/api/ping', (_, response) => response.sendStatus(204));
435449
436// File uploads450// File uploads
@@ -438,7 +452,7 @@ app.use(multer({ dest: uploadsPath, limits: { fieldSize: 10 * 1024 * 1024 } }).s
438app.use(multerMonkeyPatch);452app.use(multerMonkeyPatch);
439453
440// User data mount454// User data mount
441app.use('/', userModule.router);455app.use('/', userDataRouter);
442// Private endpoints456// Private endpoints
443app.use('/api/users', usersPrivateRouter);457app.use('/api/users', usersPrivateRouter);
444// Admin endpoints458// Admin endpoints
@@ -625,15 +639,15 @@ const preSetupTasks = async function () {
625 }639 }
626 console.log();640 console.log();
627641
628 const directories = await userModule.getUserDirectoriesList();642 const directories = await getUserDirectoriesList();
629 await contentManager.checkForNewContent(directories);643 await checkForNewContent(directories);
630 await ensureThumbnailCache();644 await ensureThumbnailCache();
631 cleanUploads();645 cleanUploads();
632646
633 await settingsInit();647 await settingsInit();
634 await statsInit();648 await statsInit();
635649
636 const cleanupPlugins = await loadPlugins();650 const cleanupPlugins = await initializePlugins();
637 const consoleTitle = process.title;651 const consoleTitle = process.title;
638652
639 let isExiting = false;653 let isExiting = false;
@@ -740,10 +754,10 @@ const postSetupTasks = async function (v6Failed, v4Failed) {
740 * Loads server plugins from a directory.754 * Loads server plugins from a directory.
741 * @returns {Promise<Function>} Function to be run on server exit755 * @returns {Promise<Function>} Function to be run on server exit
742 */756 */
743async function loadPlugins() {757async function initializePlugins() {
744 try {758 try {
745 const pluginDirectory = path.join(serverDirectory, 'plugins');759 const pluginDirectory = path.join(serverDirectory, 'plugins');
746 const cleanupPlugins = await loader.loadPlugins(app, pluginDirectory);760 const cleanupPlugins = await loadPlugins(app, pluginDirectory);
747 return cleanupPlugins;761 return cleanupPlugins;
748 } catch {762 } catch {
749 console.log('Plugin loading failed.');763 console.log('Plugin loading failed.');
@@ -883,7 +897,7 @@ async function verifySecuritySettings() {
883 logSecurityAlert('Your SillyTavern is currently insecurely open to the public. Enable whitelisting, basic authentication or user accounts.');897 logSecurityAlert('Your SillyTavern is currently insecurely open to the public. Enable whitelisting, basic authentication or user accounts.');
884 }898 }
885899
886 const users = await userModule.getAllEnabledUsers();900 const users = await getAllEnabledUsers();
887 const unprotectedUsers = users.filter(x => !x.password);901 const unprotectedUsers = users.filter(x => !x.password);
888 const unprotectedAdminUsers = unprotectedUsers.filter(x => x.admin);902 const unprotectedAdminUsers = unprotectedUsers.filter(x => x.admin);
889903
@@ -901,10 +915,10 @@ async function verifySecuritySettings() {
901}915}
902916
903// User storage module needs to be initialized before starting the server917// User storage module needs to be initialized before starting the server
904userModule.initUserStorage(dataRoot)918initUserStorage(dataRoot)
905 .then(userModule.ensurePublicDirectoriesExist)919 .then(ensurePublicDirectoriesExist)
906 .then(userModule.migrateUserData)920 .then(migrateUserData)
907 .then(userModule.migrateSystemPrompts)921 .then(migrateSystemPrompts)
908 .then(verifySecuritySettings)922 .then(verifySecuritySettings)
909 .then(preSetupTasks)923 .then(preSetupTasks)
910 .finally(startServer);924 .finally(startServer);
src/endpoints/characters.js+3 -3
@@ -16,7 +16,7 @@ import { AVATAR_WIDTH, AVATAR_HEIGHT } from '../constants.js';
16import { jsonParser, urlencodedParser } from '../express-common.js';16import { jsonParser, urlencodedParser } from '../express-common.js';
17import { deepMerge, humanizedISO8601DateTime, tryParse, extractFileFromZipBuffer } from '../util.js';17import { deepMerge, humanizedISO8601DateTime, tryParse, extractFileFromZipBuffer } from '../util.js';
18import { TavernCardValidator } from '../validator/TavernCardValidator.js';18import { TavernCardValidator } from '../validator/TavernCardValidator.js';
19import * as characterCardParser from '../character-card-parser.js';19import { parse, write } from '../character-card-parser.js';
20import { readWorldInfoFile } from './worldinfo.js';20import { readWorldInfoFile } from './worldinfo.js';
21import { invalidateThumbnail } from './thumbnails.js';21import { invalidateThumbnail } from './thumbnails.js';
22import { importRisuSprites } from './sprites.js';22import { importRisuSprites } from './sprites.js';
@@ -38,7 +38,7 @@ async function readCharacterData(inputFile, inputFormat = 'png') {
38 return characterDataCache.get(cacheKey);38 return characterDataCache.get(cacheKey);
39 }39 }
4040
41 const result = characterCardParser.parse(inputFile, inputFormat);41 const result = parse(inputFile, inputFormat);
42 characterDataCache.set(cacheKey, result);42 characterDataCache.set(cacheKey, result);
43 return result;43 return result;
44}44}
@@ -77,7 +77,7 @@ async function writeCharacterData(inputFile, data, outputFile, request, crop = u
77 const inputImage = await getInputImage();77 const inputImage = await getInputImage();
7878
79 // Get the chunks79 // Get the chunks
80 const outputImage = characterCardParser.write(inputImage, data);80 const outputImage = write(inputImage, data);
81 const outputImagePath = path.join(request.user.directories.characters, `${outputFile}.png`);81 const outputImagePath = path.join(request.user.directories.characters, `${outputFile}.png`);
8282
83 writeFileAtomicSync(outputImagePath, outputImage);83 writeFileAtomicSync(outputImagePath, outputImage);
src/endpoints/content-manager.js+4 -3
@@ -5,15 +5,16 @@ import { Buffer } from 'node:buffer';
5import express from 'express';5import express from 'express';
6import fetch from 'node-fetch';6import fetch from 'node-fetch';
7import sanitize from 'sanitize-filename';7import sanitize from 'sanitize-filename';
8import { sync as writeFileAtomicSync } from 'write-file-atomic';
89
9import { getConfigValue, color } from '../util.js';10import { getConfigValue, color } from '../util.js';
10import { jsonParser } from '../express-common.js';11import { jsonParser } from '../express-common.js';
11import { sync as writeFileAtomicSync } from 'write-file-atomic';12import { write } from '../character-card-parser.js';
13
12const contentDirectory = path.join(process.cwd(), 'default/content');14const contentDirectory = path.join(process.cwd(), 'default/content');
13const scaffoldDirectory = path.join(process.cwd(), 'default/scaffold');15const scaffoldDirectory = path.join(process.cwd(), 'default/scaffold');
14const contentIndexPath = path.join(contentDirectory, 'index.json');16const contentIndexPath = path.join(contentDirectory, 'index.json');
15const scaffoldIndexPath = path.join(scaffoldDirectory, 'index.json');17const scaffoldIndexPath = path.join(scaffoldDirectory, 'index.json');
16import * as characterCardParser from '../character-card-parser.js';
1718
18const WHITELIST_GENERIC_URL_DOWNLOAD_SOURCES = getConfigValue('whitelistImportDomains', []);19const WHITELIST_GENERIC_URL_DOWNLOAD_SOURCES = getConfigValue('whitelistImportDomains', []);
1920
@@ -397,7 +398,7 @@ async function downloadPygmalionCharacter(id) {
397 const avatarResult = await fetch(avatarUrl);398 const avatarResult = await fetch(avatarUrl);
398 const avatarBuffer = await avatarResult.buffer();399 const avatarBuffer = await avatarResult.buffer();
399400
400 const cardBuffer = characterCardParser.write(avatarBuffer, JSON.stringify(characterData));401 const cardBuffer = write(avatarBuffer, JSON.stringify(characterData));
401402
402 return {403 return {
403 buffer: cardBuffer,404 buffer: cardBuffer,
src/endpoints/users-private.js+2 -3
@@ -8,9 +8,8 @@ import express from 'express';
8import { jsonParser } from '../express-common.js';8import { jsonParser } from '../express-common.js';
9import { getUserAvatar, toKey, getPasswordHash, getPasswordSalt, createBackupArchive, ensurePublicDirectoriesExist, toAvatarKey } from '../users.js';9import { getUserAvatar, toKey, getPasswordHash, getPasswordSalt, createBackupArchive, ensurePublicDirectoriesExist, toAvatarKey } from '../users.js';
10import { SETTINGS_FILE } from '../constants.js';10import { SETTINGS_FILE } from '../constants.js';
11import * as contentManager from './content-manager.js';11import { checkForNewContent, CONTENT_TYPES } from './content-manager.js';
12import { color, Cache } from '../util.js';12import { color, Cache } from '../util.js';
13import { checkForNewContent } from './content-manager.js';
1413
15const RESET_CACHE = new Cache(5 * 60 * 1000);14const RESET_CACHE = new Cache(5 * 60 * 1000);
1615
@@ -168,7 +167,7 @@ router.post('/reset-settings', jsonParser, async (request, response) => {
168167
169 const pathToFile = path.join(request.user.directories.root, SETTINGS_FILE);168 const pathToFile = path.join(request.user.directories.root, SETTINGS_FILE);
170 await fsPromises.rm(pathToFile, { force: true });169 await fsPromises.rm(pathToFile, { force: true });
171 await contentManager.checkForNewContent([request.user.directories], [contentManager.CONTENT_TYPES.SETTINGS]);170 await checkForNewContent([request.user.directories], [CONTENT_TYPES.SETTINGS]);
172171
173 return response.sendStatus(204);172 return response.sendStatus(204);
174 } catch (error) {173 } catch (error) {