Browse Source

integration of more old "DTP Base" configuration and service

develop
Rob Colbert 1 year ago
parent
commit
40578fb53a
  1. 5
      app/controllers/home.js
  2. 49
      app/models/image.js
  3. 35
      app/models/log.js
  4. 69
      app/models/user.js
  5. 36
      config/tripwire.js
  6. 197
      dtp-chat.js
  7. 39
      lib/site-async.js
  8. 66
      lib/site-common.js
  9. 65
      lib/site-controller.js
  10. 17
      lib/site-error.js
  11. 13
      lib/site-lib.js
  12. 128
      lib/site-log.js
  13. 26
      lib/site-service.js
  14. 32
      lib/site-tripwire.js
  15. 11
      package.json
  16. 7
      webpack.config.js
  17. 294
      yarn.lock

5
app/controllers/home.js

@ -6,13 +6,16 @@
import express from 'express';
export default class HomeController {
import { SiteController } from '../../lib/site-controller.js';
export default class HomeController extends SiteController {
static get isHome ( ) { return true; }
static get slug ( ) { return 'home'; }
static get className ( ) { return 'HomeController'; }
constructor (dtp) {
super(dtp, HomeController.slug);
this.dtp = dtp;
}

49
app/models/image.js

@ -0,0 +1,49 @@
// image.js
// Copyright (C) 2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
const ImageSchema = new Schema({
created: { type: Date, default: Date.now, required: true, index: -1 },
owner: { type: Schema.ObjectId, required: true, index: 1, ref: 'User' },
caption: { type: String, maxLength: 300 },
flags: {
isSensitive: { type: Boolean, default: false, required: true },
isPendingAttachment: { type: Boolean, default: false, required: true },
},
type: { type: String, required: true },
size: { type: Number, required: true },
file: {
bucket: { type: String, required: true },
key: { type: String, required: true },
etag: { type: String, required: true, index: true },
},
metadata: {
format: { type: String },
size: { type: Number },
width: { type: Number },
height: { type: Number },
space: { type: String },
channels: { type: Number },
depth: { type: String },
density: { type: Number },
hasAlpha: { type: Boolean },
orientation: { type: Number },
},
});
ImageSchema.index({
'flags.isPendingAttachment': 1,
created: -1,
}, {
partialFilterExpression: {
'flags.isPendingAttachment': true,
},
name: 'img_pendattach_idx',
});
export default mongoose.model('Image', ImageSchema);

35
app/models/log.js

@ -0,0 +1,35 @@
// log.js
// Copyright (C) 2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
const LOG_LEVEL_LIST = [
'debug',
'info',
'warn',
'alert',
'error',
'crit',
'fatal',
];
const LogSchema = new Schema({
created: { type: Date, default: Date.now, required: true, index: -1, expires: '7d' },
componentName: { type: String, required: true, index: 1 },
level: { type: String, enum: LOG_LEVEL_LIST, required: true, index: true },
message: { type: String },
metadata: { type: Schema.Types.Mixed },
});
LogSchema.index({
level: 1,
componentName: 1,
}, {
name: 'log_level_component_idx',
});
export default mongoose.model('Log', LogSchema);

69
app/models/user.js

@ -0,0 +1,69 @@
// user.js
// Copyright (C) 2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
import mongoose from "mongoose";
const Schema = mongoose.Schema;
const UserFlagsSchema = new Schema({
isAdmin: { type: Boolean, default: false, required: true },
isModerator: { type: Boolean, default: false, required: true },
isEmailVerified: { type: Boolean, default: false, required: true },
isCloaked: { type: Boolean, default: false, required: true, select: false },
hasPublicProfile: { type: Boolean, default: true, required: true },
hasPublicNetwork: { type: Boolean, default: true, required: true },
requireFollowRequest: { type: Boolean, default: false, required: true },
});
const UserPermissionsSchema = new Schema({
canLogin: { type: Boolean, default: true, required: true },
canChat: { type: Boolean, default: true, required: true },
canComment: { type: Boolean, default: true, required: true },
canReport: { type: Boolean, default: true, required: true },
canPostStatus: { type: Boolean, default: true, required: true },
canShareLinks: { type: Boolean, default: true, required: true },
canEnablePublicProfile: { type: Boolean, default: true, required: true },
});
const UserOptInSchema = new Schema({
system: { type: Boolean, default: true, required: true },
marketing: { type: Boolean, default: true, required: true },
});
const UserSchema = new Schema({
created: { type: Date, default: Date.now, required: true, index: -1 },
email: { type: String, required: true, lowercase: true, unique: true },
username: { type: String, maxLength: 40, required: true },
username_lc: { type: String, maxLength: 40, required: true, lowercase: true, unique: true, index: 1 },
passwordSalt: { type: String, required: true },
password: { type: String, required: true },
displayName: { type: String, maxLength: 60 },
picture: {
large: { type: Schema.ObjectId, ref: 'Image' },
small: { type: Schema.ObjectId, ref: 'Image' },
},
bio: { type: String },
flags: { type: UserFlagsSchema, default: { }, required: true, select: false },
permissions: { type: UserPermissionsSchema, default: { }, required: true, select: false },
optIn: { type: UserOptInSchema, default: { }, required: true, select: false },
lastAnnouncement: { type: Date },
membership: { type: Schema.ObjectId, index: 1, ref: 'Membership' },
paymentTokens: {
handcash: { type: String, select: false },
stripe: { type: String, select: false },
},
balances: {
tokens: { type: Number, default: 0, min: 0, max: 500, required: true },
},
blockedUsers: { type: [Schema.ObjectId], select: false, ref: 'User' },
notes: { type: String, select: false },
history: {
username: { type: [String] },
displayName: { type: [String] },
bio: { type: [String] },
},
});
export default mongoose.model('User', UserSchema);

36
config/tripwire.js

@ -0,0 +1,36 @@
// tripwire.js
// Copyright (C) 2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
export default [
'/.env',
'/.well-known',
'/?a=fetch&content=<php>die(@md5(HelloThinkCMF))</php>',
'/?XDEBUG_SESSION_START',
'/actuator/health',
'/api/v1',
'/base',
'/api/pleroma',
'/backend',
'/cgi-bin',
'/conf',
'/core',
'/database',
'/kind-u',
'/laravel',
'/newsite',
'/old-index.php',
'/protected',
'/shell',
'/sites',
'/src',
'/storage',
'/vendor/php',
'/web',
'/wp-admin',
'/wp-login',
'/wp-load',
'/www',
];

197
dtp-chat.js

@ -14,13 +14,23 @@ import { createRequire } from 'module';
const require = createRequire(import.meta.url); // jshint ignore:line
import * as glob from 'glob';
import * as rfs from 'rotating-file-stream';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import WEBPACK_CONFIG from './webpack.config.js';
import mongoose from 'mongoose';
import { Redis } from 'ioredis';
import { SiteLog } from './lib/site-lib.js';
import { SiteTripwire } from './lib/site-tripwire.js';
import express from 'express';
import morgan from 'morgan';
import { Emitter } from '@socket.io/redis-emitter';
const APP_CONFIG = {
pkg: require('./package.json'),
@ -32,9 +42,139 @@ class Harness {
this.config = {
root: __dirname,
};
this.log = new SiteLog(this, 'Harness');
this.models = [ ];
}
async start ( ) {
this.log.info('loading SiteTripwire (known-malicious request protection)');
this.tripwire = new SiteTripwire(this);
await this.tripwire.start();
await this.startMongoDB();
await this.loadModels();
await this.connectRedis();
await this.startExpressJS();
}
async startMongoDB ( ) {
try {
this.log.info('starting MongoDB');
/*
* For some time, strictQuery=true was the Mongoose default. It's being
* changed. The option has to be set manually now.
*/
mongoose.set('strictQuery', true);
this.log.info('connecting to MongoDB database', {
pid: process.pid,
host: process.env.MONGODB_HOST,
database: process.env.MONGODB_DATABASE,
});
const mongoConnectUri = `mongodb://${process.env.DTP_MONGODB_HOST}/${process.env.DTP_MONGODB_DATABASE}`;
await mongoose.connect(mongoConnectUri, {
socketTimeoutMS: 0,
dbName: process.env.MONGODB_DATABASE,
});
this.db = mongoose.connection;
this.log.info('connected to MongoDB');
} catch (error) {
this.log.error('failed to connect to database', { error });
throw error;
}
}
async loadModels ( ) {
const modelScripts = glob.sync(path.join(this.config.root, 'app', 'models', '*.js'));
this.log.info('loading models', { count: modelScripts.length });
for (const modelScript of modelScripts) {
const model = (await import(modelScript)).default;
if (this.models[model.modelName]) {
this.log.error('model name collision', { name: model.modelName });
process.exit(-1);
}
this.models.push(model);
this.log.info('model loaded', { name: model.modelName});
}
}
async resetIndexes (target) {
if (target === 'all') {
for (const model of this.models) {
await this.resetIndex(model);
}
return;
}
const model = this.models.find((model) => model.modelName === target);
if (!model) {
throw new Error(`requested Mongoose model does not exist: ${target}`);
}
return this.resetIndex(model);
}
async resetIndex (model) {
return new Promise(async (resolve, reject) => {
this.log.info('dropping model indexes', { model: model.modelName });
model.collection.dropIndexes((err) => {
if (err) {
return reject(err);
}
this.log.info('creating model indexes', { model: model.modelName });
model.ensureIndexes((err) => {
if (err) {
return reject(err);
}
return resolve(model);
});
});
});
}
async connectRedis ( ) {
try {
const options = {
host: process.env.DTP_REDIS_HOST,
port: parseInt(process.env.DTP_REDIS_PORT || '6379', 10),
password: process.env.DTP_REDIS_PASSWORD,
keyPrefix: process.env.DTP_REDIS_KEY_PREFIX,
lazyConnect: false,
};
this.log.info('connecting to Redis', {
host: options.host,
port: options.port,
prefix: options.keyPrefix || 'dtp',
});
this.redis = new Redis(options);
this.redis.setMaxListeners(64); // prevents warnings/errors with Bull Queue
this.log.info('creating Socket.io Emitter');
this.emitter = new Emitter(this.redis);
this.log.info('Redis connected');
} catch (error) {
this.log.error('failed to connect to Redis', error);
throw new Error('failed to connect to Redis', { cause: error });
}
}
async getRedisKeys (pattern) {
return new Promise((resolve, reject) => {
return this.redis.keys(pattern, (err, response) => {
if (err) {
return reject(err);
}
return resolve(response);
});
});
}
async startExpressJS ( ) {
this.app = express();
this.app.locals.config = APP_CONFIG;
@ -43,13 +183,47 @@ class Harness {
this.app.set('view engine', 'pug');
this.app.set('views', path.join(__dirname, 'app', 'views'));
this.app.use('/static', express.static(path.join(__dirname, 'client', 'static')));
this.app.use('/fontawesome', express.static(path.join(__dirname, 'node_modules', '@fortawesome', 'fontawesome-free')));
this.app.use('/uikit', express.static(path.join(__dirname, 'node_modules', 'uikit')));
this.app.use('/pretty-checkbox', express.static(path.join(__dirname, 'node_modules', 'pretty-checkbox', 'dist')));
this.app.set('x-powered-by', false);
this.app.use(this.tripwire.guard.bind(this.tripwire));
/*
* HTTP request logging
*/
if (process.env.DTP_LOG_FILE === 'enabled') {
const httpLogStream = rfs.createStream(process.env.DTP_LOG_FILE_NAME_HTTP || 'dtp-sites-access.log', {
interval: '1d',
path: process.env.DTP_LOG_FILE_PATH || '/tmp',
compress: 'gzip',
});
this.app.use(morgan(process.env.DTP_LOG_HTTP_FORMAT || 'combined', { stream: httpLogStream }));
}
this.app.use('/dist', express.static(path.join(__dirname, 'dist')));
function cacheOneDay (req, res, next) {
res.set('Cache-Control', 'public, maxage=86400, s-maxage=86400, immutable');
return next();
}
function serviceWorkerAllowed (req, res, next) {
res.set('Service-Worker-Allowed', '/');
return next();
}
/*
* Static content and file services
*/
const staticOptions = {
cacheControl: true,
immutable: true,
maxAge: '4h',
dotfiles: 'ignore',
};
this.app.use('/fontawesome', cacheOneDay, express.static(path.join(__dirname, 'node_modules', '@fortawesome', 'fontawesome-free')));
this.app.use('/uikit', cacheOneDay, express.static(path.join(__dirname, 'node_modules', 'uikit')));
this.app.use('/pretty-checkbox', cacheOneDay, express.static(path.join(__dirname, 'node_modules', 'pretty-checkbox', 'dist')));
this.app.use('/dist', cacheOneDay, serviceWorkerAllowed, express.static(path.join(__dirname, 'dist')));
this.app.use('/static', cacheOneDay, serviceWorkerAllowed, express.static(path.join(__dirname, 'client', 'static'), staticOptions));
/*
* Webpack integration
@ -77,9 +251,9 @@ class Harness {
*/
const host = process.env.DTP_HTTP_HOST || '127.0.0.1';
const port = parseInt(process.env.DTP_HTTP_PORT || '3000', 10);
console.log('Starting application server', { host, port });
this.log.info('Starting application server', { host, port });
this.app.listen(port, host, ( ) => {
console.log(`${APP_CONFIG.pkg.name} online.`);
this.log.info(`${APP_CONFIG.pkg.name} online.`);
});
}
@ -92,7 +266,7 @@ class Harness {
for await (const script of scripts) {
try {
const file = path.parse(script);
console.log('loading controller', { name: file.base });
this.log.info('loading controller', { name: file.base });
let controller = await import(script);
controller = controller.default;
@ -101,7 +275,7 @@ class Harness {
this.controllers[controller.slug] = controller;
inits.push(controller);
} catch (error) {
console.error('failed to load controller', { error });
this.log.error('failed to load controller', { error });
throw new Error('failed to load controller', { cause: error });
}
}
@ -118,6 +292,7 @@ class Harness {
*/
await this.controllers.home.instance.start();
}
}
(async ( ) => {
@ -126,7 +301,7 @@ class Harness {
const harness = new Harness();
await harness.start();
} catch (error) {
console.log('failed to start application harness', error);
console.error('failed to start application harness', error);
}
})();

39
lib/site-async.js

@ -0,0 +1,39 @@
// site-async.js
// Copyright (C) 2022,2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
export class SiteAsync {
static each (sourceItems, callback, concurrent = 1) {
if (!Array.isArray(sourceItems)) {
throw new Error('each requires an array of objects to be processed');
}
if (sourceItems.length === 0) {
return Promise.resolve();
}
var items = sourceItems.slice();
var running = 0;
return new Promise((resolve, reject) => {
function next ( ) {
let item = items.shift();
if (!item) {
return;
}
++running;
callback(item).then(next).catch(reject).finally(( ) => {
if (--running === 0) {
resolve();
}
});
}
while (concurrent && items.length) {
next();
--concurrent;
}
});
}
}

66
lib/site-common.js

@ -0,0 +1,66 @@
// site-common.js
// Copyright (C) 2022,2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
import path from 'path';
import pug from 'pug';
import EventEmitter from 'events';
export class SiteCommon extends EventEmitter {
constructor (dtp) {
super();
this.dtp = dtp;
this.appTemplateRoot = path.join(this.dtp.config.root, 'app', 'templates');
}
saveSession (req) {
return new Promise((resolve, reject) => {
req.session.save((err) => {
if (err) {
return reject(err);
}
resolve();
});
});
}
isValidString (text) {
return text && (typeof text === 'string') && (text.length > 0);
}
loadAppTemplate (type, name) {
return pug.compileFile(path.join(this.appTemplateRoot, type, name));
}
loadViewTemplate (filename) {
const scriptFile = path.join(this.dtp.config.root, 'app', 'views', filename);
this.log.debug('loading view template', { filename });
return pug.compileFile(scriptFile);
}
async renderTemplate (templateFn, templateModel) {
const { cache: cacheService } = this.dtp.services;
const { config, pkg } = this.dtp;
const settingsKey = `settings:${config.site.domainKey}:site`;
const adminSettings = await cacheService.getObject(settingsKey);
if (this.dtp.app && this.dtp.app.locals) {
templateModel = Object.assign(templateModel, this.dtp.app.locals); // global app objects
}
templateModel.pkg = pkg;
templateModel.site = Object.assign(templateModel.site || { }, config.site); // defaults and .env
templateModel.site = Object.assign(templateModel.site, adminSettings); // admin overrides
return templateFn(templateModel);
}
createDisplayList (name) {
const { displayEngine: displayEngineService } = this.dtp.services;
return displayEngineService.createDisplayList(name);
}
}

65
lib/site-controller.js

@ -0,0 +1,65 @@
// site-controller.js
// Copyright (C) 2022,2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
import multer from 'multer';
import * as slugTool from 'slug';
import { SiteCommon } from './site-common.js';
import { SiteLog } from './site-log.js';
export class SiteController extends SiteCommon {
constructor (dtp, name) {
super(dtp);
this.name = name;
this.log = new SiteLog(dtp, `ctrl:${name}`);
this.children = { };
}
async loadChild (filename) {
let child = await require(filename);
this.children[child.slug] = child;
let instance = child.create(this.dtp);
return await instance.start();
}
getPaginationParameters (req, maxPerPage, pageParamName = 'p', cppParamName = 'cpp') {
const pagination = {
p: parseInt(req.query[pageParamName] || '1', 10),
cpp: parseInt(req.query[cppParamName] || maxPerPage.toString(), 10),
};
if (pagination.p < 1) {
pagination.p = 1;
}
if (pagination.cpp > maxPerPage) {
pagination.cpp = maxPerPage;
}
pagination.skip = (pagination.p - 1) * pagination.cpp;
return pagination;
}
createMulter (slug, options) {
if (!!slug && (typeof slug === 'object')) {
options = slug;
slug = this.name;
} else {
slug = slug || this.name;
}
slug = slugTool(slug).toLowerCase();
options = Object.assign({
dest: `/tmp/${this.dtp.config.site.domainKey}/${slug}`,
}, options || { });
return multer(options);
}
async createCsrfToken (req, name) {
const { csrfToken } = this.dtp.platform.services;
return csrfToken.create(req, { name });
}
}

17
lib/site-error.js

@ -0,0 +1,17 @@
// site-error.js
// Copyright (C) 2022,2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
export class SiteError extends Error {
constructor (statusCode, message, options) {
super(message, options);
this.name = 'SiteError';
if (!this.code) {
this.code = statusCode;
}
this.statusCode = statusCode;
}
}

13
lib/site-lib.js

@ -0,0 +1,13 @@
// site-lib.js
// Copyright (C) 2022,2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
export { SiteCommon } from './site-common.js';
// export * from './site-platform.js';
export { SiteAsync } from './site-async.js';
export { SiteError } from './site-error.js';
export { SiteLog } from './site-log.js';
export { SiteController } from './site-controller.js';
export { SiteService } from './site-service.js';

128
lib/site-log.js

@ -0,0 +1,128 @@
// site-log.js
// Copyright (C) 2022,2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
import * as util from 'node:util';
import moment from 'moment';
import * as rfs from 'rotating-file-stream';
import color from 'ansicolor';
var LogModel, LogStream;
if (process.env.DTP_LOG_FILE === 'enabled') {
LogStream = rfs.createStream(process.env.DTP_LOG_FILE_NAME_APP || 'site-app.log', {
path: process.env.DTP_LOG_FILE_PATH || '/tmp',
size: '10M',
interval: '1d',
compress: 'gzip',
});
}
export class SiteLog {
/**
* Sets the Mongoose model to be used for writing log entries to the database.
* This is managed like this so we don't have to connect to the database and
* load the db models *before* we can write log entries to the console.
* @param {Model} model the Mongoose model to be used for writing logs.
*/
static setModel (model) { LogModel = model; }
constructor (dtp, componentName) {
this.dtp = dtp;
this.componentName = componentName;
}
async debug (message, metadata) {
if (process.env.DTP_LOG_DEBUG !== 'enabled') {
return;
}
return this.writeLog('debug', message, metadata);
}
async info (message, metadata) {
if (process.env.DTP_LOG_INFO !== 'enabled') {
return;
}
return this.writeLog('info', message, metadata);
}
async warn (message, metadata) {
if (process.env.DTP_LOG_WARN !== 'enabled') {
return;
}
return this.writeLog('warn', message, metadata);
}
async alert (message, metadata) {
return this.writeLog('alert', message, metadata);
}
async error (message, metadata) {
return this.writeLog('error', message, metadata);
}
async crit (message, metadata) {
return this.writeLog('crit', message, metadata);
}
async fatal (message, metadata) {
this.writeLog('fatal', message, metadata);
}
async writeLog (level, message, metadata) {
const NOW = new Date();
const { componentName } = this;
if (process.env.DTP_LOG_CONSOLE === 'enabled') {
let clevel = level.padEnd(5);
switch (level) {
case 'debug':
clevel = color.darkGray(clevel);
break;
case 'info':
clevel = color.green(clevel);
break;
case 'warn':
clevel = color.yellow(clevel);
break;
case 'alert':
clevel = color.red(clevel);
break;
case 'error':
clevel = color.bgRed.white(clevel);
break;
case 'crit':
clevel = color.bgRed.yellow(clevel);
break;
case 'fatal':
clevel = color.bgRed.darkGray(clevel);
break;
}
const ctimestamp = color.darkGray(moment(NOW).format('YYYY-MM-DD HH:mm:ss.SSS'));
const ccomponentName = color.cyan(componentName);
const cmessage = color.darkGray(message);
if (metadata) {
console.log(`${ctimestamp} ${clevel} ${ccomponentName} ${cmessage}`, util.inspect(metadata, false, Infinity, true));
} else {
console.log(`${ctimestamp} ${clevel} ${ccomponentName} ${cmessage}`);
}
}
if (LogModel && (process.env.DTP_LOG_MONGODB === 'enabled')) {
await LogModel.create({ created: NOW, level, componentName, message, metadata });
}
if (LogStream && (process.env.DTP_LOG_FILE === 'enabled')) {
const logEntry = {
t: NOW, c: componentName, l: level, m: message, d: metadata,
};
LogStream.write(`${JSON.stringify(logEntry)}\n`);
}
}
}

26
lib/site-service.js

@ -0,0 +1,26 @@
// site-service.js
// Copyright (C) 2022,2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
import { SiteCommon } from './site-common.js';
import { SiteLog } from './site-log.js';
export class SiteService extends SiteCommon {
constructor (dtp, definition) {
super(dtp);
this.slug = definition.slug;
this.name = definition.name;
this.log = new SiteLog(dtp, `svc:${this.slug}`);
}
async start ( ) {
this.log.debug(`starting ${this.name} service`);
}
async stop ( ) {
this.log.debug(`stopping ${this.name} service`);
}
}

32
lib/site-tripwire.js

@ -0,0 +1,32 @@
// site-tripwire.js
// Copyright (C) 2024 DTP Technologies, LLC
// All Rights Reserved
'use strict';
import path from 'node:path';
import { SiteLog } from './site-log.js';
export class SiteTripwire {
constructor (dtp) {
this.dtp = dtp;
this.log = new SiteLog(this, 'Harness');
}
async start ( ) {
this.blockedPaths = (await import(path.join(this.dtp.config.root, 'config', 'tripwire.js'))).default;
}
async guard (req, res, next) {
// Tripwire looks for known-bad URLs, malicious URLs, and requests that indicate
// the client is "snooping" and shuts them down.
const path = this.blockedPaths.find((path) => req.path.startsWith(path));
if (!path) {
return next();
}
this.log.alert('tripwire path requested', { path, ip: req.ip });
return res.status(403).end();
}
}

11
package.json

@ -18,15 +18,24 @@
"private": true,
"dependencies": {
"@fortawesome/fontawesome-free": "^6.5.1",
"@socket.io/redis-adapter": "^8.3.0",
"@socket.io/redis-emitter": "^5.1.0",
"ansicolor": "^2.0.3",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"glob": "^10.3.10",
"ioredis": "^5.3.2",
"marked": "^12.0.1",
"mongoose": "^8.2.3",
"mediasoup": "^3.13.24",
"moment": "^2.30.1",
"mongoose": "^8.2.4",
"morgan": "^1.10.0",
"multer": "^1.4.5-lts.1",
"numeral": "^2.0.6",
"pretty-checkbox": "^3.0.3",
"pug": "^3.0.2",
"rotating-file-stream": "^3.2.1",
"slug": "^9.0.0",
"socket.io": "^4.7.5",
"striptags": "^3.2.0"
},

7
webpack.config.js

@ -12,11 +12,10 @@ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import BrowserSyncPlugin from 'browser-sync-webpack-plugin';
const webpackMode = (process.env.NODE_ENV === 'production') ? 'production' : 'development';
console.log('Webpack mode:', webpackMode);
const plugins = [ ];
plugins.push(new MiniCssExtractPlugin());
const plugins = [
new MiniCssExtractPlugin(),
];
if (webpackMode === 'development') {
plugins.push(

294
yarn.lock

@ -961,6 +961,11 @@
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz#55cc8410abf1003b726324661ce5b0d1c10de258"
integrity sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw==
"@ioredis/commands@^1.1.1":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11"
integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==
"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
@ -1067,6 +1072,24 @@
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
"@socket.io/redis-adapter@^8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@socket.io/redis-adapter/-/redis-adapter-8.3.0.tgz#bdce1e8f34c07df4a8baf98170bf24dc84eaed4a"
integrity sha512-ly0cra+48hDmChxmIpnESKrc94LjRL80TEmZVscuQ/WWkRP81nNj8W8cCGMqbI4L6NCuAaPRSzZF1a9GlAxxnA==
dependencies:
debug "~4.3.1"
notepack.io "~3.0.1"
uid2 "1.0.0"
"@socket.io/redis-emitter@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@socket.io/redis-emitter/-/redis-emitter-5.1.0.tgz#faab6dc363135e44a5a37b5ef5d4f723c80e0db1"
integrity sha512-QQUFPBq6JX7JIuM/X1811ymKlAfwufnQ8w6G2/59Jaqp09hdF1GJ/+e8eo/XdcmT0TqkvcSa2TT98ggTXa5QYw==
dependencies:
debug "~4.3.1"
notepack.io "~3.0.1"
socket.io-parser "~4.2.1"
"@surma/rollup-plugin-off-main-thread@^2.2.3":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz#ee34985952ca21558ab0d952f00298ad2190c053"
@ -1089,6 +1112,13 @@
dependencies:
"@types/node" "*"
"@types/debug@^4.1.12":
version "4.1.12"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917"
integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==
dependencies:
"@types/ms" "*"
"@types/eslint-scope@^3.7.3":
version "3.7.7"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5"
@ -1115,11 +1145,21 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
"@types/ini@^4.1.0":
version "4.1.0"
resolved "https://registry.yarnpkg.com/@types/ini/-/ini-4.1.0.tgz#20e7327b3133627f84304210670d6406cceaba25"
integrity sha512-mTehMtc+xtnWBBvqizcqYCktKDBH2WChvx1GU3Sfe4PysFDXiNe+1YwtpVX1MDtCa4NQrSPw2+3HmvXHY3gt1w==
"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
"@types/ms@*":
version "0.7.34"
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
"@types/node@*", "@types/node@>=10.0.0":
version "20.11.30"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.30.tgz#9c33467fc23167a347e73834f788f4b9f399d66f"
@ -1419,6 +1459,11 @@ [email protected], ansi-wrap@^0.1.0:
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==
ansicolor@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/ansicolor/-/ansicolor-2.0.3.tgz#ec4448ae5baf8c2d62bf2dad52eac06ba0b5ea21"
integrity sha512-pzusTqk9VHrjgMCcTPDTTvfJfx6Q3+L5tQ6yKC8Diexmoit4YROTFIkxFvRTNL9y5s0Q8HrSrgerCD5bIC+Kiw==
anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
@ -1554,6 +1599,13 @@ [email protected], base64id@~2.0.0:
resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
basic-auth@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a"
integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==
dependencies:
safe-buffer "5.1.2"
[email protected]:
version "0.6.1"
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
@ -1764,6 +1816,11 @@ chokidar@^3.5.1, chokidar@^3.5.2:
optionalDependencies:
fsevents "~2.3.2"
chownr@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
chrome-trace-event@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
@ -1819,6 +1876,11 @@ cloneable-readable@^1.0.0:
process-nextick-args "^2.0.0"
readable-stream "^2.3.5"
cluster-key-slot@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@ -2005,6 +2067,11 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
data-uri-to-buffer@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e"
integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==
data-view-buffer@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2"
@ -2044,7 +2111,7 @@ [email protected], debug@^2.2.0:
dependencies:
ms "2.0.0"
[email protected], debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4:
[email protected], debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -2081,7 +2148,12 @@ define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
[email protected]:
denque@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1"
integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==
[email protected], depd@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
@ -2496,6 +2568,14 @@ fastest-levenshtein@^1.0.12:
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5"
integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
fetch-blob@^3.1.2, fetch-blob@^3.1.4:
version "3.2.0"
resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9"
integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==
dependencies:
node-domexception "^1.0.0"
web-streams-polyfill "^3.0.3"
filelist@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
@ -2549,6 +2629,11 @@ flat@^5.0.2:
resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
flatbuffers@^24.3.7:
version "24.3.25"
resolved "https://registry.yarnpkg.com/flatbuffers/-/flatbuffers-24.3.25.tgz#e2f92259ba8aa53acd0af7844afb7c7eb95e7089"
integrity sha512-3HDgPbgiwWMI9zVB7VYBHaMrbOO7Gm0v+yD2FV/sCKj+9NDeVL7BOBYUuhWAQGKWOzBo8S9WdMvV0eixO233XQ==
follow-redirects@^1.0.0:
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
@ -2569,6 +2654,13 @@ foreground-child@^3.1.0:
cross-spawn "^7.0.0"
signal-exit "^4.0.1"
formdata-polyfill@^4.0.10:
version "4.0.10"
resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423"
integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==
dependencies:
fetch-blob "^3.1.2"
[email protected]:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@ -2598,6 +2690,13 @@ fs-extra@^9.0.1:
jsonfile "^6.0.1"
universalify "^2.0.0"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
dependencies:
minipass "^3.0.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -2722,6 +2821,14 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11,
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
h264-profile-level-id@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/h264-profile-level-id/-/h264-profile-level-id-2.0.0.tgz#b7ea45badbac8f5dbb9583d34b06db09764f2535"
integrity sha512-X4CLryVbVA0CtjTExS4G5U1gb2Z4wa32AF8ukVmFuLdw2JRq2aHisor7SY5SYTUUrUSqq0KdPIO18sql6IWIQw==
dependencies:
"@types/debug" "^4.1.12"
debug "^4.3.4"
has-bigints@^1.0.1, has-bigints@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
@ -2874,6 +2981,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
ini@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.2.tgz#7f646dbd9caea595e61f88ef60bfff8b01f8130a"
integrity sha512-AMB1mvwR1pyBFY/nSevUX6y8nJWS63/SzUKD3JyQn97s4xgIdgQPT75IRouIiBAN4yLQBUShNYVW0+UG25daCw==
internal-slot@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802"
@ -2888,6 +3000,21 @@ interpret@^3.1.1:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
ioredis@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7"
integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==
dependencies:
"@ioredis/commands" "^1.1.1"
cluster-key-slot "^1.1.0"
debug "^4.3.4"
denque "^2.1.0"
lodash.defaults "^4.2.0"
lodash.isarguments "^3.1.0"
redis-errors "^1.2.0"
redis-parser "^3.0.0"
standard-as-callback "^2.1.0"
[email protected]:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
@ -3303,6 +3430,16 @@ lodash.debounce@^4.0.8:
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==
lodash.isarguments@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==
lodash.isfinite@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3"
@ -3367,6 +3504,20 @@ [email protected]:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
mediasoup@^3.13.24:
version "3.13.24"
resolved "https://registry.yarnpkg.com/mediasoup/-/mediasoup-3.13.24.tgz#c18e327263529a7992eb75a8b16b35b66e38c19a"
integrity sha512-7kAJP/4YIoK+UaioekQfyLEzJF7ngcVgog4TI3E08QOYS3WPR8Njx0Xsde7bkQZ/NoAy+6diTFN1vuC3GztCnQ==
dependencies:
"@types/ini" "^4.1.0"
debug "^4.3.4"
flatbuffers "^24.3.7"
h264-profile-level-id "^2.0.0"
ini "^4.1.2"
node-fetch "^3.3.2"
supports-color "^9.4.0"
tar "^6.2.0"
memfs@^4.6.0:
version "4.8.0"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.8.0.tgz#0ea1ecb137219883c2e7c5139f4fa109935f7e39"
@ -3473,11 +3624,31 @@ minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
minipass@^3.0.0:
version "3.3.6"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a"
integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==
dependencies:
yallist "^4.0.0"
minipass@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0":
version "7.0.4"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c"
integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==
minizlib@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
dependencies:
minipass "^3.0.0"
yallist "^4.0.0"
mitt@^1.1.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d"
@ -3490,6 +3661,16 @@ mkdirp@^0.5.4:
dependencies:
minimist "^1.2.6"
mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment@^2.30.1:
version "2.30.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
mongodb-connection-string-url@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz#b4f87f92fd8593f3b9365f592515a06d304a1e9c"
@ -3507,10 +3688,10 @@ [email protected]:
bson "^6.2.0"
mongodb-connection-string-url "^3.0.0"
mongoose@^8.2.3:
version "8.2.3"
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.2.3.tgz#26c2074b0d65fa83fa2fd899d3327a2a820fd4c8"
integrity sha512-ZB8K8AgbVgLCcqjtmZMxaQBEztwEEZCtAIPMx2Q56Uo4WWKmwf5Nu/EEIFo8d/17P946X0z6xzxwIqCxUMKxrA==
mongoose@^8.2.4:
version "8.2.4"
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.2.4.tgz#785234f928aeabc1b1859b555c97fc18adc6ff8c"
integrity sha512-da/r6zpG+2eAXuhBGUnL6jcBd03zlytoCc5/wq+LyTsmrY9hhPQmSpnugwnfqldtBmUOhB6iMLoV4hNtHRq+ww==
dependencies:
bson "^6.2.0"
kareem "2.5.1"
@ -3520,6 +3701,17 @@ mongoose@^8.2.3:
ms "2.1.3"
sift "16.0.1"
morgan@^1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7"
integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==
dependencies:
basic-auth "~2.0.1"
debug "2.6.9"
depd "~2.0.0"
on-finished "~2.3.0"
on-headers "~1.0.2"
[email protected]:
version "0.9.0"
resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904"
@ -3583,6 +3775,20 @@ neo-async@^2.6.2:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
node-domexception@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
node-fetch@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b"
integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==
dependencies:
data-uri-to-buffer "^4.0.0"
fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10"
node-releases@^2.0.14:
version "2.0.14"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
@ -3624,6 +3830,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
notepack.io@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/notepack.io/-/notepack.io-3.0.1.tgz#2c2c9de1bd4e64a79d34e33c413081302a0d4019"
integrity sha512-TKC/8zH5pXIAMVQio2TvVDTtPRX+DJPHDqjRbxogtFiByHyzKmy96RA0JtCQJ+WouyyL4A10xomQzgbUT+1jCg==
numeral@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506"
@ -3668,6 +3879,11 @@ on-finished@~2.3.0:
dependencies:
ee-first "1.1.1"
on-headers@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@ -4053,6 +4269,18 @@ rechoir@^0.8.0:
dependencies:
resolve "^1.20.0"
redis-errors@^1.0.0, redis-errors@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==
redis-parser@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==
dependencies:
redis-errors "^1.0.0"
regenerate-unicode-properties@^10.1.0:
version "10.1.1"
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480"
@ -4177,6 +4405,11 @@ rollup@^2.43.1:
optionalDependencies:
fsevents "~2.3.2"
rotating-file-stream@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/rotating-file-stream/-/rotating-file-stream-3.2.1.tgz#1d0a536d75884eedc3a677f5b0871fdc69f97d22"
integrity sha512-n2B18CJb+n2VA5Tdle+1NP2toEcRv68CjAOBjHmwcyswNwMVsrN3gVRZ9ymH3sapaiGY8jc9OhhV5b6I5rAeiA==
[email protected]:
version "4.1.0"
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
@ -4192,16 +4425,16 @@ safe-array-concat@^1.1.2:
has-symbols "^1.0.3"
isarray "^2.0.5"
[email protected], safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
[email protected], safe-buffer@^5.1.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-regex-test@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377"
@ -4425,6 +4658,11 @@ simple-update-notifier@^2.0.0:
dependencies:
semver "^7.5.3"
slug@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/slug/-/slug-9.0.0.tgz#68f968a79ce5156c6606b7b2e233ed0ffab94bdf"
integrity sha512-ixytnHlpHPWM56heaGgYe/M8tDAcpJcsg/zBuyElbFDOORzMGOeP3Te6iJBRVYu3WQEiWLQPb70Gh9ig/sZgGQ==
socket.io-adapter@~2.5.2:
version "2.5.4"
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz#4fdb1358667f6d68f25343353bd99bd11ee41006"
@ -4443,7 +4681,7 @@ socket.io-client@^4.4.1:
engine.io-client "~6.5.2"
socket.io-parser "~4.2.4"
socket.io-parser@~4.2.4:
socket.io-parser@~4.2.1, socket.io-parser@~4.2.4:
version "4.2.4"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83"
integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==
@ -4506,6 +4744,11 @@ sparse-bitfield@^3.0.3:
dependencies:
memory-pager "^1.0.2"
standard-as-callback@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45"
integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==
[email protected]:
version "2.0.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
@ -4681,6 +4924,11 @@ supports-color@^8.0.0, supports-color@^8.1.1:
dependencies:
has-flag "^4.0.0"
supports-color@^9.4.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.4.0.tgz#17bfcf686288f531db3dea3215510621ccb55954"
integrity sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
@ -4691,6 +4939,18 @@ tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
tar@^6.2.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a"
integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
minipass "^5.0.0"
minizlib "^2.1.1"
mkdirp "^1.0.3"
yallist "^4.0.0"
temp-dir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e"
@ -4852,6 +5112,11 @@ ua-parser-js@^1.0.33:
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.37.tgz#b5dc7b163a5c1f0c510b08446aed4da92c46373f"
integrity sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==
[email protected]:
version "1.0.0"
resolved "https://registry.yarnpkg.com/uid2/-/uid2-1.0.0.tgz#ef8d95a128d7c5c44defa1a3d052eecc17a06bfb"
integrity sha512-+I6aJUv63YAcY9n4mQreLUt0d4lvwkkopDNmpomkAUz0fAkEMV9pRWxN0EjhW1YfRhcuyHg2v3mwddCDW1+LFQ==
uikit@^3.19.2:
version "3.19.2"
resolved "https://registry.yarnpkg.com/uikit/-/uikit-3.19.2.tgz#e2b7c3af3124835db38804a8e1e07f93eb97a015"
@ -4982,6 +5247,11 @@ watchpack@^2.4.1:
glob-to-regexp "^0.4.1"
graceful-fs "^4.1.2"
web-streams-polyfill@^3.0.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b"
integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==
webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"

Loading…
Cancel
Save