mrfrys-node-server/src/modules/api/api.ts
2022-03-20 11:49:05 +01:00

233 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 { ModuleType, Request, Submodule } from '../../types/basicTypes'
// files
const rootRedirectToFile = 'data/apiRootRedirectTo'
// other constants
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('.') // [ "https://api", "frylabs", "net" ]
domain.shift() // [ "frylabs", "net" ]
domain = domain.join('.') // "frylabs.net"
logger.DebugLog(`Cookie domain: ${domain}`, 'cookie', 1)
// -------------------------------------------------------------------------------------------
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,
jsonResponse: true,
exceptions: [
'/register',
'/favicon.ico',
'/login',
'/postfeedback',
'/fosuploader',
'/badtestsender',
],
})
)
app.use(
fileUpload({
limits: { fileSize: 50 * 1024 * 1024 },
})
)
// -------------------------------------------------------------------------------------------
let rootRedirectURL = ''
function reloadRootRedirectURL() {
if (utils.FileExists(rootRedirectToFile)) {
rootRedirectURL = utils.ReadFile(rootRedirectToFile)
}
}
const filesToWatch = [
{
fname: 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()
} else {
logger.Log(
`File ${ftw.fname} does not exists to watch!`,
logger.GetColor('redbg')
)
}
})
}
Load()
// --------------------------------------------------------------
app.get('/', function (req: Request, res: any) {
logger.LogReq(req)
if (reloadRootRedirectURL) {
res.redirect(rootRedirectURL)
} else {
res.json({ msg: 'hi c:' })
}
})
// -------------------------------------------------------------------------------------------
const submoduleDatas = setupSubModules(app)
// -------------------------------------------------------------------------------------------
publicdirs.forEach((pdir) => {
logger.Log(`Using public dir: ${pdir}`)
app.use(express.static(pdir))
})
// -------------------------------------------------------------------------------------------
app.get('*', function (_req: Request, res: any) {
res.status(404).render('404')
})
app.post('*', function (_req: Request, res: any) {
res.status(404).render('404')
})
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?: any
): 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 {
logger.Log(`Loading submodule '${file}' for '${moduleName}'...`)
const mod = require(submodulePath).default // eslint-disable-line
const loadedModData = mod.setup({
app: parentApp,
userDB: userDB,
url: url,
publicdirs: publicdirs,
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
url = data.url
publicdirs = data.publicdirs
httpServer = data.httpServer
httpsServer = data.httpsServer
},
}