diff --git a/README.md b/README.md index edca184..605c9a0 100755 --- a/README.md +++ b/README.md @@ -140,17 +140,17 @@ The server doesn't require that much maintenance, but you are advised to: * Watch out for directories that can get big: * `./stats`: server statistics and logs * `./data/dbs/backup`: backup of databases - * `./publicDirs/qminingPublic/backs`: backup of question databases - * `./publicDirs/qminingPublic/userFiles`: files shared by users - * `./publicDirs/qminingPublic/savedQuestions`: unanswered questions saved by the userscript + * `./public/backs`: backup of question databases + * `./public/userFiles`: files shared by users + * `./public/savedQuestions`: unanswered questions saved by the userscript * Make regular backups of important data: * `./data/dbs`: user and messages database * `./data/p2p`: p2p data, and public/private keys - * `./publicDirs/qminingPublic/questionDbs`: question dbs - * `./publicDirs/qminingPublic/questionDbs.json`: information about question db-s - * `./publicDirs/qminingPublic/userFiles`: files shared by users - * `./publicDirs/qminingPublic/forum`: forum entries and comments - * `./publicDirs/qminingPublic/savedQuestions`: unanswered questions saved by the userscript + * `./public/questionDbs`: question dbs + * `./public/questionDbs.json`: information about question db-s + * `./public/userFiles`: files shared by users + * `./public/forum`: forum entries and comments + * `./public/savedQuestions`: unanswered questions saved by the userscript * Most files not tracked by git ## Server maintenance utils @@ -300,19 +300,18 @@ https://gitlab.com/MrFry/moodle-test-userscript │ └── qmining-page qmining frontend ├── testingTools testing tools for the server ├── defaultPublicFiles static public files that the frontends use, like images -└── publicDirs/ public directories of the server, mostly available on the domain root - └── qminingPublic/ qmining module public path (modules: qmining, dataeditor, api) - ├── backs/ question database backups - ├── chatFiles/ files sent on chat - ├── contacts.json contacts displayed on the /contact page - ├── forum/ forum contents - ├── forumFiles/ files uploaded to forums - ├── moodle-test-userscript link to the userscript, it fetches updates from this path - ├── motd motto of the day - ├── questionDbs/ directory of the question db-s - ├── questionDbs.json question db-s information - ├── savedQuestions/ un-answered questions for dataeditor, saved from test pages - └── userFiles/ files shared by users +└── public/ public directories of the server + ├── backs/ question database backups + ├── chatFiles/ files sent on chat + ├── contacts.json contacts displayed on the /contact page + ├── forum/ forum contents + ├── forumFiles/ files uploaded to forums + ├── moodle-test-userscript link to the userscript, it fetches updates from this path + ├── motd motto of the day + ├── questionDbs/ directory of the question db-s + ├── questionDbs.json question db-s information + ├── savedQuestions/ un-answered questions for dataeditor, saved from test pages + └── userFiles/ files shared by users ``` ## Related repositories diff --git a/publicDirs/public/favicon.ico b/defaultPublicFiles/favicon.ico similarity index 100% rename from publicDirs/public/favicon.ico rename to defaultPublicFiles/favicon.ico diff --git a/scripts/setup.sh b/scripts/setup.sh index 7b277c6..e0d114f 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -61,11 +61,11 @@ mkdir -pv stats/logs mkdir -pv stats/vlogs mkdir -pv data mkdir -pv data/dbs -mkdir -p publicDirs/qminingPublic +mkdir -pv public -touch publicDirs/qminingPublic/motd +touch public/motd -cp -vrn ./defaultPublicFiles/* ./publicDirs/qminingPublic/ +cp -vrn ./defaultPublicFiles/* ./public/ # ------------------------------------------------------------------------------------ # Git submodules @@ -98,8 +98,8 @@ makeNextSubmodule "qmining-data-editor" "dataEditorPublic" # ------------------------------------------------------------------------------------ log "Making moodle test userscript" checkFile "$PWD/submodules/moodle-test-userscript/stable.user.js" -mkdir -pv "$PWD/publicDirs/qminingPublic/moodle-test-userscript" -ln -sfv "$PWD/submodules/moodle-test-userscript/stable.user.js" "$PWD/publicDirs/qminingPublic/moodle-test-userscript/" +mkdir -pv "$PWD/public/moodle-test-userscript" +ln -sfv "$PWD/submodules/moodle-test-userscript/stable.user.js" "$PWD/public/moodle-test-userscript/" # ------------------------------------------------------------------------------------ # DB-s diff --git a/src/modules.json b/src/modules.json index 05a9966..f9db447 100644 --- a/src/modules.json +++ b/src/modules.json @@ -1,7 +1,6 @@ { "dataEditor": { "path": "./modules/dataEditor/dataEditor.js", - "publicdirs": ["publicDirs/qminingPublic/"], "nextdir": "nextStatic/dataEditorPublic", "name": "dataeditor", "route": "/dataeditor", @@ -9,7 +8,6 @@ }, "qmining": { "path": "./modules/qmining/qmining.js", - "publicdirs": ["publicDirs/qminingPublic/"], "nextdir": "nextStatic/qminingPagePublic", "name": "qmining", "route": "/", @@ -17,7 +15,6 @@ }, "api": { "path": "./modules/api/api.js", - "publicdirs": ["publicDirs/qminingPublic/"], "name": "api", "route": "/api" } diff --git a/src/modules/api/api.ts b/src/modules/api/api.ts index 7b2ea48..abc36e8 100644 --- a/src/modules/api/api.ts +++ b/src/modules/api/api.ts @@ -39,7 +39,7 @@ import { Submodule, } from '../../types/basicTypes' import { loadJSON } from '../../utils/actions' -import { paths } from '../../utils/files' +import { paths, publicDir } from '../../utils/files' import { initWorkerPool } from '../../worker/workerPool' // other paths @@ -48,18 +48,12 @@ const moduleName = 'API' // stuff gotten from server.js let userDB: Database let url: string -let publicdirs: string[] = [] let httpServer: http.Server let httpsServer: https.Server function GetApp(): ModuleType { const app = express() - const publicDir = publicdirs[0] - if (!publicDir) { - throw new Error(`No public dir! ( API )`) - } - let domain: any = url.split('.') domain.shift() domain = domain.join('.') // "qmining.com" @@ -157,9 +151,7 @@ function GetApp(): ModuleType { // ------------------------------------------------------------------------------------------- - publicdirs.forEach((pdir) => { - app.use(express.static(pdir)) - }) + app.use(express.static(publicDir)) // ------------------------------------------------------------------------------------------- @@ -206,7 +198,6 @@ function setupSubModules( app: parentApp, userDB: userDB, url: url, // only used by userManagement.ts - publicdirs: publicdirs, moduleSpecificData: moduleSpecificData, httpServer: httpServer, httpsServer: httpsServer, @@ -227,7 +218,6 @@ export default { setup: (data: SetupData): void => { userDB = data.userDB url = data.url - publicdirs = data.publicdirs httpServer = data.httpServer httpsServer = data.httpsServer }, diff --git a/src/modules/api/submodules/chat.ts b/src/modules/api/submodules/chat.ts index 3264232..abb6c8a 100644 --- a/src/modules/api/submodules/chat.ts +++ b/src/modules/api/submodules/chat.ts @@ -25,6 +25,7 @@ import dbtools from '../../../utils/dbtools' import logger from '../../../utils/logger' import { Request, SubmoduleData, User } from '../../../types/basicTypes' import socketAuth from '../../../middlewares/socketAuth.middleware' +import { publicDir } from '../../../utils/files' const msgDbPath = './data/dbs/msgs.db' const msgPaginationLimit = 15 @@ -44,10 +45,9 @@ interface Message { } function setup(data: SubmoduleData): void { - const { app, httpServer, httpsServer, userDB, publicdirs } = data + const { app, httpServer, httpsServer, userDB } = data const msgDB = dbtools.GetDB(msgDbPath) - const publicDir = publicdirs[0] const uloadFiles = publicDir + 'chatFiles' logger.Log( `Chat: Starting Socket.io Server on ${httpsServer ? 'https' : 'http'}` diff --git a/src/modules/api/submodules/forum.ts b/src/modules/api/submodules/forum.ts index 2197b11..2f44d40 100644 --- a/src/modules/api/submodules/forum.ts +++ b/src/modules/api/submodules/forum.ts @@ -23,6 +23,7 @@ import { v4 as uuidv4 } from 'uuid' import logger from '../../../utils/logger' import utils from '../../../utils/utils' import { Request, SubmoduleData, User } from '../../../types/basicTypes' +import { publicDir } from '../../../utils/files' interface Comment { date: string @@ -184,9 +185,7 @@ function getPostData( } function setup(data: SubmoduleData): void { - const { app, publicdirs } = data - - const publicDir = publicdirs[0] + const { app } = data const forumDir = publicDir + 'forum' const forumFiles = publicDir + 'forumFiles' diff --git a/src/modules/api/submodules/p2p.ts b/src/modules/api/submodules/p2p.ts index 61d2961..e176448 100644 --- a/src/modules/api/submodules/p2p.ts +++ b/src/modules/api/submodules/p2p.ts @@ -47,7 +47,12 @@ import { getAvailableQdbIndexes, removeCacheFromQuestion, } from '../../../utils/qdbUtils' -import { files, paths, readAndValidateFile } from '../../../utils/files' +import { + files, + paths, + publicDir, + readAndValidateFile, +} from '../../../utils/files' import { GetResult, get } from '../../../utils/networkUtils' import { msgAllWorker, @@ -294,8 +299,7 @@ async function sendNewDataToWorkers( function writeNewData( newQuestionDbs: QuestionDb[], changedQuestionDbs: QuestionDb[], - dbsFilePath: string, - publicDir: string + dbsFilePath: string ) { const qdbsToWrite = [...changedQuestionDbs, ...newQuestionDbs] const existingQdbs = utils.ReadJSON(dbsFilePath) @@ -486,11 +490,9 @@ function setup(data: SubmoduleData): Submodule { const { app, userDB, - publicdirs, moduleSpecificData: { setQuestionDbs, getQuestionDbs, dbsFile }, } = data - const publicDir = publicdirs[0] let syncInProgress = false // --------------------------------------------------------------------------------------- @@ -1063,8 +1065,7 @@ function setup(data: SubmoduleData): Submodule { getQuestionDbs().filter((qdb) => { return changedQdbIndexes.includes(qdb.index) }), - dbsFile, - publicDir + dbsFile ) setQuestionDbs([...mergedQuestionDbs, ...newQuestionDbs]) diff --git a/src/modules/api/submodules/qminingapi.ts b/src/modules/api/submodules/qminingapi.ts index 9671d1e..5bd56ec 100644 --- a/src/modules/api/submodules/qminingapi.ts +++ b/src/modules/api/submodules/qminingapi.ts @@ -55,7 +55,7 @@ import { SearchResultQuestion, subjectToString, } from '../../../utils/qdbUtils' -import { paths } from '../../../utils/files' +import { paths, publicDir } from '../../../utils/files' import constants from '../../../constants' import { isJsonValidAndLogError, @@ -391,7 +391,6 @@ function getNewQdb( location: string, maxIndex: number, dbsFile: string, - publicDir: string, questionDbs: QuestionDb[] ) { logger.Log( @@ -446,11 +445,9 @@ function setup(data: SubmoduleData): Submodule { const { app, userDB, - publicdirs, moduleSpecificData: { getQuestionDbs, setQuestionDbs, dbsFile }, } = data - const publicDir = publicdirs[0] const motdFile = publicDir + 'motd' const savedQuestionsDir = publicDir + 'savedQuestions' @@ -586,13 +583,7 @@ function setup(data: SubmoduleData): Submodule { if (suitedQuestionDbs.length === 0) { if (!dbExists(location, getQuestionDbs())) { suitedQuestionDbs.push( - getNewQdb( - location, - maxIndex, - dbsFile, - publicDir, - getQuestionDbs() - ) + getNewQdb(location, maxIndex, dbsFile, getQuestionDbs()) ) } else { logger.Log( diff --git a/src/modules/api/submodules/todos.ts b/src/modules/api/submodules/todos.ts deleted file mode 100644 index 5170f7d..0000000 --- a/src/modules/api/submodules/todos.ts +++ /dev/null @@ -1,134 +0,0 @@ -/* ---------------------------------------------------------------------------- - - Question Server - GitLab: - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - ------------------------------------------------------------------------- */ - -import { Response } from 'express' - -import logger from '../../../utils/logger' -import utils from '../../../utils/utils' -import { Request, SubmoduleData } from '../../../types/basicTypes' - -interface Categories { - [key: string]: { - name: string - color: string - } -} - -enum CardState { - TODO = 'todo', - INPROGRESS = 'inprogress', - TESTING = 'testing', - DONE = 'done', - INPROD = 'inprod', - NOTPOSSIBLE = 'notpossible', -} - -interface Card { - id: number - name: string - description: string - category: string - points: number - state: CardState - votes: number[] -} - -type Columns = { - [key in CardState]: { - name: string - clickable: boolean - } -} - -interface Groups { - [key: string]: { - name: string - description: string - } -} - -interface Todos { - categories: Categories - cards: Card[] - columns: Columns - groups: Groups -} - -const todosFile = 'data/todos.json' - -function setup(data: SubmoduleData): void { - const { app } = data - - app.get('/voteTodo', (req: Request, res: Response) => { - logger.LogReq(req) - const userId = req.session.user.id - const id: string = req.query.id - const todos: Todos = utils.ReadJSON(todosFile) - - if (!id) { - res.json({ - msg: 'id query undefined', - result: 'not ok', - }) - } - - const cardIndex = todos.cards.findIndex((currcard) => { - return currcard.id === parseInt(id) - }) - if (cardIndex === -1) { - res.json({ - msg: 'card not found', - result: 'not ok', - }) - return - } - - const ind = todos.cards[cardIndex].votes.indexOf(userId) - if (ind === -1) { - todos.cards[cardIndex].votes.push(userId) - } else { - todos.cards[cardIndex].votes.splice(ind, 1) - } - - utils.WriteFile(JSON.stringify(todos, null, 2), todosFile) - res.json({ - todos: todos, - userId: userId, - msg: 'updated', - result: 'ok', - }) - }) - - app.get('/todos', (req: Request, res: Response) => { - logger.LogReq(req) - const userId = req.session.user.id - const todos = utils.ReadJSON(todosFile) - - res.json({ - todos: todos, - userId: userId, - result: 'ok', - }) - }) -} - -export default { - setup: setup, -} diff --git a/src/modules/api/submodules/userFiles.ts b/src/modules/api/submodules/userFiles.ts index dba9591..d2f210e 100644 --- a/src/modules/api/submodules/userFiles.ts +++ b/src/modules/api/submodules/userFiles.ts @@ -23,10 +23,11 @@ import fs from 'fs' import logger from '../../../utils/logger' import utils from '../../../utils/utils' import { Request, SubmoduleData, User } from '../../../types/basicTypes' +import { publicDir } from '../../../utils/files' const dataFileName = '.data.json' -function listDir(publicDir: string, subdir: string, userFilesDir: string) { +function listDir(subdir: string, userFilesDir: string) { const safeSubdir = subdir.replace(/\.+/g, '').replace(/\/+/g, '') const dir = userFilesDir + '/' + safeSubdir const usersFile = dir + '/' + dataFileName @@ -83,7 +84,7 @@ function listDir(publicDir: string, subdir: string, userFilesDir: string) { } function setup(data: SubmoduleData): void { - const { app, publicdirs } = data + const { app } = data app.use((req: Request, _res, next) => { // /userFiles/test/2021-04-28_10-59.png @@ -121,8 +122,6 @@ function setup(data: SubmoduleData): void { next() }) - const publicDir = publicdirs[0] - const userFilesDir = publicDir + 'userFiles' if (!utils.FileExists(userFilesDir)) { utils.CreatePath(userFilesDir, true) @@ -138,7 +137,7 @@ function setup(data: SubmoduleData): void { const subdir: string = req.query.subdir if (subdir) { - const result = listDir(publicDir, subdir, userFilesDir) + const result = listDir(subdir, userFilesDir) res.json(result) } else { res.json({ @@ -315,7 +314,7 @@ function setup(data: SubmoduleData): void { utils.WriteFile(JSON.stringify(data), dataFilePath) } - const result = listDir(publicDir, dir, userFilesDir) + const result = listDir(dir, userFilesDir) res.json(result) }) @@ -333,7 +332,7 @@ function setup(data: SubmoduleData): void { return } utils.CreatePath(userFilesDir + '/' + safeName, true) - const result = listDir(publicDir, name, userFilesDir) + const result = listDir(name, userFilesDir) if (result.files.length === 0) { utils.deleteDir(userFilesDir + '/' + safeName) } else { diff --git a/src/modules/dataEditor/dataEditor.ts b/src/modules/dataEditor/dataEditor.ts index f0e706b..8b9f177 100644 --- a/src/modules/dataEditor/dataEditor.ts +++ b/src/modules/dataEditor/dataEditor.ts @@ -29,10 +29,10 @@ import logger from '../../utils/logger' import auth from '../../middlewares/auth.middleware' import { SetupData } from '../../server' import { ModuleType, Request } from '../../types/basicTypes' +import { publicDir } from '../../utils/files' // stuff gotten from server.js let userDB: Database -let publicdirs: string[] = [] let nextdir = '' function GetApp(): ModuleType { @@ -61,9 +61,7 @@ function GetApp(): ModuleType { } next() }) - publicdirs.forEach((pdir) => { - app.use(express.static(pdir)) - }) + app.use(express.static(publicDir)) app.use(express.static(nextdir)) // -------------------------------------------------------------- @@ -103,7 +101,6 @@ export default { getApp: GetApp, setup: (data: SetupData): void => { userDB = data.userDB - publicdirs = data.publicdirs nextdir = data.nextdir }, } diff --git a/src/modules/qmining/qmining.ts b/src/modules/qmining/qmining.ts index 200ff5c..ca980ea 100644 --- a/src/modules/qmining/qmining.ts +++ b/src/modules/qmining/qmining.ts @@ -30,9 +30,9 @@ import auth from '../../middlewares/auth.middleware' import { SetupData } from '../../server' import { ModuleType, Request } from '../../types/basicTypes' import { LinksSchema, validateJSON } from '../../types/typeSchemas' +import { publicDir } from '../../utils/files' // stuff gotten from server.js -let publicdirs: string[] = [] let userDB: Database let nextdir = '' @@ -62,9 +62,7 @@ function GetApp(): ModuleType { } next() }) - publicdirs.forEach((pdir) => { - app.use(express.static(pdir)) - }) + app.use(express.static(publicDir)) app.use(express.static(nextdir)) const linksFile = 'data/links.json' let links: { [key: string]: string } = {} @@ -243,7 +241,6 @@ export default { getApp: GetApp, setup: (data: SetupData): void => { userDB = data.userDB - publicdirs = data.publicdirs nextdir = data.nextdir }, } diff --git a/src/server.ts b/src/server.ts index d2406d7..09e06be 100755 --- a/src/server.ts +++ b/src/server.ts @@ -69,7 +69,6 @@ interface Modules { interface Module { path: string - publicdirs: Array name: string route: string nextdir?: string @@ -81,7 +80,6 @@ interface Module { export interface SetupData { url: string - publicdirs: Array userDB?: Database nextdir?: string httpServer: http.Server @@ -233,15 +231,10 @@ Object.keys(modules).forEach(function (key) { const mod = require(module.path).default // eslint-disable-line // const mod = require(module.path) - module.publicdirs.forEach((pdir) => { - utils.CreatePath(pdir) - }) - if (mod.setup) { mod.setup({ url: constants.domain, // used by api.ts -> userManagement.ts -> cookies userDB: userDB, - publicdirs: module.publicdirs, nextdir: module.nextdir, httpServer: httpServer, httpsServer: httpsServer, diff --git a/src/types/basicTypes.ts b/src/types/basicTypes.ts index 0d89211..3861fca 100644 --- a/src/types/basicTypes.ts +++ b/src/types/basicTypes.ts @@ -122,7 +122,6 @@ export interface ModuleSpecificData { export interface SubmoduleData { app: express.Application url: string - publicdirs: Array userDB?: Database nextdir?: string moduleSpecificData: ModuleSpecificData diff --git a/src/utils/files.ts b/src/utils/files.ts index ca6375e..d327f34 100644 --- a/src/utils/files.ts +++ b/src/utils/files.ts @@ -65,6 +65,8 @@ export const validateAndSetupFiles = (): boolean => { return everythingValid } +export const publicDir = './public' + export const readAndValidateFile = (file: FileDescriptor): T => { if (!file.schema) return null const fileExists = utils.FileExists(file.path) diff --git a/submodules/qmining-data-editor b/submodules/qmining-data-editor index 55f7efc..e6e1cca 160000 --- a/submodules/qmining-data-editor +++ b/submodules/qmining-data-editor @@ -1 +1 @@ -Subproject commit 55f7efc6d4388519ed127068d5ec12b109c9c5ab +Subproject commit e6e1ccaeb8da8cf4c6fe8624697e15fdc3ce9c41 diff --git a/submodules/qmining-page b/submodules/qmining-page index 2e12f32..055a732 160000 --- a/submodules/qmining-page +++ b/submodules/qmining-page @@ -1 +1 @@ -Subproject commit 2e12f3275d47334acb97437ecb9f72af4261d334 +Subproject commit 055a732733b05d4579fa8e9a85da6b97c29957de