mrfrys-node-server/src/modules/api/api.ts
2023-05-01 09:20:22 +02:00

214 lines
5.9 KiB
TypeScript

/* ----------------------------------------------------------------------------
Question Server
GitLab: <https://gitlab.com/MrFry/mrfrys-node-server>
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 <https://www.gnu.org/licenses/>.
------------------------------------------------------------------------- */
// package requires
import express, { RequestHandler } from 'express'
import fileUpload from 'express-fileupload'
import type { Database } from 'better-sqlite3'
import http from 'http'
import https from 'https'
// other requires
import logger from '../../utils/logger'
import utils from '../../utils/utils'
import auth from '../../middlewares/auth.middleware'
import { SetupData } from '../../server'
import {
DataFile,
ModuleSpecificData,
ModuleType,
QuestionDb,
Request,
Submodule,
} from '../../types/basicTypes'
import { loadJSON } from '../../utils/actions'
import { paths, publicDir } from '../../utils/files'
import { initWorkerPool } from '../../worker/workerPool'
// other paths
const moduleName = 'API'
// stuff gotten from server.js
let userDB: Database
let httpServer: http.Server
let httpsServer: https.Server
function GetApp(): ModuleType {
const app = express()
app.use(
express.urlencoded({
limit: '10mb',
extended: true,
}) as RequestHandler
)
app.use(
express.json({
limit: '10mb',
}) as RequestHandler
)
app.set('view engine', 'ejs')
app.set('views', ['./src/modules/api/views', './src/sharedViews'])
app.use(
auth({
userDB: userDB,
})
)
app.use(
fileUpload({
limits: { fileSize: 50 * 1024 * 1024 },
})
)
// -------------------------------------------------------------------------------------------
let rootRedirectURL = ''
function reloadRootRedirectURL() {
if (utils.FileExists(paths.rootRedirectToFile)) {
rootRedirectURL = utils.ReadFile(paths.rootRedirectToFile).trim()
}
}
const filesToWatch = [
{
fname: paths.rootRedirectToFile,
logMsg: 'Root redirect URL changed',
action: reloadRootRedirectURL,
},
]
function Load() {
filesToWatch.forEach((ftw) => {
if (utils.FileExists(ftw.fname)) {
utils.WatchFile(ftw.fname, () => {
logger.Log(ftw.logMsg)
ftw.action()
})
ftw.action()
}
})
}
Load()
// --------------------------------------------------------------
app.get('/', function (req: Request, res: any) {
logger.LogReq(req)
if (rootRedirectURL) {
res.redirect(rootRedirectURL)
} else {
res.json({ msg: 'hi c:' })
}
})
// -------------------------------------------------------------------------------------------
const dbsFile = publicDir + 'questionDbs.json'
// FIXME: is dataFiles only a temp variable? does this cause any problems?
if (!utils.FileExists(dbsFile)) {
utils.WriteFile('[]', dbsFile)
}
const dataFiles: Array<DataFile> = utils.ReadJSON(dbsFile)
let questionDbs: Array<QuestionDb> = loadJSON(dataFiles, publicDir)
initWorkerPool(() => questionDbs)
const submoduleDatas = setupSubModules(app, {
getQuestionDbs: () => {
return questionDbs
},
setQuestionDbs: (newQdbs: QuestionDb[]) => {
questionDbs = newQdbs
},
dbsFile: dbsFile,
})
// -------------------------------------------------------------------------------------------
app.use(express.static(publicDir))
// -------------------------------------------------------------------------------------------
function DailyAction() {
submoduleDatas.forEach((data) => {
if (data.dailyAction) {
data.dailyAction()
}
})
}
submoduleDatas.forEach((data) => {
if (data.load) {
data.load()
}
})
return {
dailyAction: DailyAction,
app: app,
}
}
function setupSubModules(
parentApp: express.Application,
moduleSpecificData: ModuleSpecificData
): Submodule[] {
const submoduleDir = './submodules/'
const absolutePath = __dirname + '/' + submoduleDir
if (!utils.FileExists(absolutePath)) {
return null
}
const files = utils.ReadDir(absolutePath)
const moduleDatas: Submodule[] = []
files.forEach((file) => {
if (!file.endsWith('.js')) {
return
}
const submodulePath = submoduleDir + file
try {
const mod = require(submodulePath).default // eslint-disable-line
const loadedModData = mod.setup({
app: parentApp,
userDB: userDB,
moduleSpecificData: moduleSpecificData,
httpServer: httpServer,
httpsServer: httpsServer,
})
moduleDatas.push(loadedModData || {})
} catch (e) {
logger.Log(`Error loading submodule from ${submodulePath}`)
console.error(e)
}
})
return moduleDatas
}
export default {
name: moduleName,
getApp: GetApp,
setup: (data: SetupData): void => {
userDB = data.userDB
httpServer = data.httpServer
httpsServer = data.httpsServer
},
}