Merged type fixes

This commit is contained in:
mrfry 2022-03-22 11:23:17 +01:00
commit 85b5acc692
22 changed files with 583 additions and 150 deletions

View file

@ -1,4 +1,24 @@
import type { Response, NextFunction } from 'express' /* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import type { Response, NextFunction, RequestHandler } from 'express'
import type { Request } from '../types/basicTypes' import type { Request } from '../types/basicTypes'
import type { Database } from 'better-sqlite3' import type { Database } from 'better-sqlite3'
@ -7,7 +27,7 @@ import utils from '../utils/utils'
import dbtools from '../utils/dbtools' import dbtools from '../utils/dbtools'
interface Options { interface Options {
userDB: any userDB: Database
jsonResponse: boolean jsonResponse: boolean
exceptions: Array<string> exceptions: Array<string>
} }
@ -36,7 +56,7 @@ function renderLogin(_req: Request, res: Response, jsonResponse: boolean) {
} }
} }
export default function (options: Options): any { export default function (options: Options): RequestHandler {
const { const {
userDB, userDB,
jsonResponse, jsonResponse,
@ -133,7 +153,7 @@ export default function (options: Options): any {
} }
} }
function GetUserBySessionID(db: any, sessionID: string) { function GetUserBySessionID(db: Database, sessionID: string) {
logger.DebugLog(`Getting user from db`, 'auth', 2) logger.DebugLog(`Getting user from db`, 'auth', 2)
const session = dbtools.Select(db, 'sessions', { const session = dbtools.Select(db, 'sessions', {

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import logger from '../utils/logger' import logger from '../utils/logger'
import type { Response, NextFunction } from 'express' import type { Response, NextFunction } from 'express'
import type { Request } from '../types/basicTypes' import type { Request } from '../types/basicTypes'

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import cookie from 'cookie' import cookie from 'cookie'
import logger from '../utils/logger' import logger from '../utils/logger'

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
const DbStruct = { const DbStruct = {
msgs: { msgs: {
tableStruct: { tableStruct: {

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import { Server as socket, Socket } from 'socket.io' import { Server as socket, Socket } from 'socket.io'
import utils from '../../../utils/utils' import utils from '../../../utils/utils'
@ -179,15 +199,8 @@ function setup(data: SubmoduleData): void {
}) })
app.get('/hasNewMsg', (req: Request, res) => { app.get('/hasNewMsg', (req: Request, res) => {
let userid: any = req.query.userid const user: User = req.session.user
if (!userid || isNaN(userid)) { const userid: number = user.id
res.json({
success: false,
msg: 'Query "userid" (number) is required!',
})
return
}
userid = parseInt(userid)
const groups = dbtools const groups = dbtools
.runStatement( .runStatement(

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import { Response } from 'express' import { Response } from 'express'
import logger from '../../../utils/logger' import logger from '../../../utils/logger'

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import logger from '../../../utils/logger' import logger from '../../../utils/logger'
@ -175,7 +195,7 @@ function setup(data: SubmoduleData): void {
app.get('/forumEntries', (req: Request, res) => { app.get('/forumEntries', (req: Request, res) => {
logger.LogReq(req) logger.LogReq(req)
const forumName: any = req.query.forumName const forumName: string = req.query.forumName
if (!forumName) { if (!forumName) {
res.json({ res.json({
success: false, success: false,
@ -251,7 +271,7 @@ function setup(data: SubmoduleData): void {
forumDir forumDir
) )
const user: User = req.session.user const user: User = req.session.user
const admins: any = utils.FileExists(adminUsersFile) const admins: string[] = utils.FileExists(adminUsersFile)
? utils.ReadJSON(adminUsersFile) ? utils.ReadJSON(adminUsersFile)
: [] : []
@ -260,7 +280,7 @@ function setup(data: SubmoduleData): void {
date: utils.GetDateString(), date: utils.GetDateString(),
user: user.id, user: user.id,
title: title, title: title,
admin: admins.includes(user.id), admin: admins.includes(user.id.toString()),
commentCount: 0, commentCount: 0,
} }
@ -290,7 +310,7 @@ function setup(data: SubmoduleData): void {
) => { ) => {
logger.LogReq(req) logger.LogReq(req)
const { postKey } = req.body const { postKey } = req.body
const forumName: any = req.body.forumName const forumName = req.body.forumName
if (!forumName) { if (!forumName) {
res.json({ res.json({
success: false, success: false,
@ -334,7 +354,7 @@ function setup(data: SubmoduleData): void {
) => { ) => {
logger.LogReq(req) logger.LogReq(req)
const forumName: any = req.body.forumName const forumName = req.body.forumName
if (!forumName) { if (!forumName) {
res.json({ res.json({
success: false, success: false,
@ -347,7 +367,7 @@ function setup(data: SubmoduleData): void {
forumDir forumDir
) )
const user: User = req.session.user const user: User = req.session.user
const admins: any = utils.FileExists(adminUsersFile) const admins: string[] = utils.FileExists(adminUsersFile)
? utils.ReadJSON(adminUsersFile) ? utils.ReadJSON(adminUsersFile)
: [] : []
const { type, path, postKey } = req.body const { type, path, postKey } = req.body
@ -373,7 +393,7 @@ function setup(data: SubmoduleData): void {
date: utils.GetDateString(), date: utils.GetDateString(),
user: user.id, user: user.id,
content: content, content: content,
admin: admins.includes(user.id), admin: admins.includes(user.id.toString()),
} }
if (!postData.comments) { if (!postData.comments) {
postData.comments = [] postData.comments = []
@ -418,7 +438,7 @@ function setup(data: SubmoduleData): void {
) => { ) => {
logger.LogReq(req) logger.LogReq(req)
const forumName: any = req.body.forumName const forumName = req.body.forumName
if (!forumName) { if (!forumName) {
res.json({ res.json({
success: false, success: false,

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import fs from 'fs' import fs from 'fs'
import { Response } from 'express' import { Response } from 'express'
import { fork, ChildProcess } from 'child_process' import { fork, ChildProcess } from 'child_process'
@ -137,7 +157,7 @@ function getDetailedRes(questionDbs: QuestionDb[]) {
}) })
} }
function getMotd(version: any, motd: string) { function getMotd(version: string, motd: string) {
if (version) { if (version) {
if (version.startsWith('2.0.')) { if (version.startsWith('2.0.')) {
if (utils.FileExists(oldMotdFile)) { if (utils.FileExists(oldMotdFile)) {
@ -485,7 +505,7 @@ function setup(data: SubmoduleData): Submodule {
app.get('/allqr.txt', function (req: Request, res: Response) { app.get('/allqr.txt', function (req: Request, res: Response) {
logger.LogReq(req) logger.LogReq(req)
const db: any = req.query.db const db: string = req.query.db
let stringifiedData = '' let stringifiedData = ''
res.setHeader('content-type', 'text/plain; charset=utf-8') res.setHeader('content-type', 'text/plain; charset=utf-8')
@ -728,7 +748,7 @@ function setup(data: SubmoduleData): Submodule {
utils.WriteFile('[]', registeredScriptsFile) utils.WriteFile('[]', registeredScriptsFile)
} }
const ua: any = req.headers['user-agent'] const ua: string = req.headers['user-agent']
const registeredScripts: RegisteredUserEntry[] = utils.ReadJSON( const registeredScripts: RegisteredUserEntry[] = utils.ReadJSON(
registeredScriptsFile registeredScriptsFile
) )
@ -739,7 +759,7 @@ function setup(data: SubmoduleData): Submodule {
}) })
if (index === -1) { if (index === -1) {
const x: any = { const x: RegisteredUserEntry = {
cid: cid, cid: cid,
version: version, version: version,
installSource: installSource, installSource: installSource,
@ -975,7 +995,7 @@ function setup(data: SubmoduleData): Submodule {
// TODO: get status of it cleaning // TODO: get status of it cleaning
logger.LogReq(req) logger.LogReq(req)
const user: User = req.session.user const user: User = req.session.user
const status: any = req.query.status const status: string = req.query.status
if (status) { if (status) {
if (!questionCleaner) { if (!questionCleaner) {

View file

@ -1,6 +1,27 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import logger from '../../../utils/logger' import logger from '../../../utils/logger'
import utils from '../../../utils/utils' import utils from '../../../utils/utils'
import { Request, SubmoduleData, User } from '../../../types/basicTypes' import type { Request, SubmoduleData, User } from '../../../types/basicTypes'
import type { Response } from 'express'
const quickVoteResultsDir = 'stats/qvote' const quickVoteResultsDir = 'stats/qvote'
const quickVotes = 'stats/qvote/votes.json' const quickVotes = 'stats/qvote/votes.json'
@ -20,9 +41,9 @@ interface QuickVote {
function setup(data: SubmoduleData): void { function setup(data: SubmoduleData): void {
const { app /* userDB, url, publicdirs, moduleSpecificData */ } = data const { app /* userDB, url, publicdirs, moduleSpecificData */ } = data
app.get('/quickvote', (req: Request, res: any) => { app.get('/quickvote', (req: Request, res: Response) => {
const key = req.query.key.toString() const key = req.query.key.toString()
const val: any = req.query.val const val: string = req.query.val
const user: User = req.session.user const user: User = req.session.user
if (!key || !val) { if (!key || !val) {

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import logger from '../../../utils/logger' import logger from '../../../utils/logger'
import utils from '../../../utils/utils' import utils from '../../../utils/utils'
import { Request, SubmoduleData, User } from '../../../types/basicTypes' import { Request, SubmoduleData, User } from '../../../types/basicTypes'
@ -40,10 +60,10 @@ function mergeObjSum(a: Subjects, b: Subjects) {
function setup(data: SubmoduleData): void { function setup(data: SubmoduleData): void {
const { app /* userDB, url, publicdirs, moduleSpecificData */ } = data const { app /* userDB, url, publicdirs, moduleSpecificData */ } = data
app.get('/ranklist', (req: Request, res: any) => { app.get('/ranklist', (req: Request, res) => {
logger.LogReq(req) logger.LogReq(req)
let result: IdStats let result: IdStats
const querySince: any = req.query.since const querySince: string = req.query.since
const user: User = req.session.user const user: User = req.session.user
if (!querySince) { if (!querySince) {

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import { Response } from 'express' import { Response } from 'express'
import logger from '../../../utils/logger' import logger from '../../../utils/logger'
@ -59,7 +79,7 @@ function setup(data: SubmoduleData): void {
app.get('/voteTodo', (req: Request, res: Response) => { app.get('/voteTodo', (req: Request, res: Response) => {
logger.LogReq(req) logger.LogReq(req)
const userId = req.session.user.id const userId = req.session.user.id
const id: any = req.query.id const id: string = req.query.id
const todos: Todos = utils.ReadJSON(todosFile) const todos: Todos = utils.ReadJSON(todosFile)
if (!id) { if (!id) {

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import fs from 'fs' import fs from 'fs'
import logger from '../../../utils/logger' import logger from '../../../utils/logger'
@ -112,7 +132,7 @@ function setup(data: SubmoduleData): void {
utils.CreatePath(userFilesDir, true) utils.CreatePath(userFilesDir, true)
} }
const subdir: any = req.query.subdir const subdir: string = req.query.subdir
if (subdir) { if (subdir) {
const result = listDir(publicDir, subdir, userFilesDir) const result = listDir(publicDir, subdir, userFilesDir)
@ -138,43 +158,46 @@ function setup(data: SubmoduleData): void {
} }
}) })
app.post('/deleteUserFile', (req: Request, res) => { app.post(
logger.LogReq(req) '/deleteUserFile',
const dir: any = req.body.dir (req: Request<{ dir: string; fname: string }>, res) => {
const fname: any = req.body.fname logger.LogReq(req)
if (!dir || !fname) { const dir: string = req.body.dir
const fname: string = req.body.fname
if (!dir || !fname) {
res.json({
success: false,
msg: `'dir' or 'fname' is undefined!`,
})
return
}
const safeDir = dir.replace(/\.+/g, '').replace(/\/+/g, '')
const safeFname = fname.replace(/\.+/g, '.').replace(/\/+/g, '')
const filePath = userFilesDir + '/' + safeDir + '/' + safeFname
if (!utils.FileExists(filePath)) {
res.json({
success: false,
msg: `path does not exists!`,
})
return
}
utils.deleteFile(filePath)
const usersFile = userFilesDir + '/' + safeDir + '/' + dataFileName
const users = utils.ReadJSON(usersFile)
delete users[safeFname]
utils.WriteFile(JSON.stringify(users), usersFile)
res.json({ res.json({
success: false, success: true,
msg: `'dir' or 'fname' is undefined!`,
}) })
return
} }
const safeDir = dir.replace(/\.+/g, '').replace(/\/+/g, '') )
const safeFname = fname.replace(/\.+/g, '.').replace(/\/+/g, '')
const filePath = userFilesDir + '/' + safeDir + '/' + safeFname
if (!utils.FileExists(filePath)) { app.post('/newUserDir', (req: Request<{ name: string }>, res) => {
res.json({
success: false,
msg: `path does not exists!`,
})
return
}
utils.deleteFile(filePath)
const usersFile = userFilesDir + '/' + safeDir + '/' + dataFileName
const users = utils.ReadJSON(usersFile)
delete users[safeFname]
utils.WriteFile(JSON.stringify(users), usersFile)
res.json({
success: true,
})
})
app.post('/newUserDir', (req: Request, res) => {
logger.LogReq(req) logger.LogReq(req)
const name: any = req.body.name const name: string = req.body.name
if (!name) { if (!name) {
res.json({ res.json({
success: false, success: false,
@ -198,7 +221,7 @@ function setup(data: SubmoduleData): void {
}) })
}) })
app.post('/uploadUserFile', (req: Request, res) => { app.post('/uploadUserFile', (req: Request<{ dir: string }>, res) => {
logger.LogReq(req) logger.LogReq(req)
const user: User = req.session.user const user: User = req.session.user
@ -241,7 +264,7 @@ function setup(data: SubmoduleData): void {
}) })
}) })
app.post('/voteFile', (req: Request, res) => { app.post('/voteFile', (req: Request<{ path: string; to: string }>, res) => {
logger.LogReq(req) logger.LogReq(req)
const user: User = req.session.user const user: User = req.session.user
// { path: 'userFiles/test/2021-04-28_10-59.png', to: 'up' } 19 // { path: 'userFiles/test/2021-04-28_10-59.png', to: 'up' } 19

View file

@ -1,9 +1,34 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import type { Database } from 'better-sqlite3' import type { Database } from 'better-sqlite3'
import logger from '../../../utils/logger' import logger from '../../../utils/logger'
import utils from '../../../utils/utils' import utils from '../../../utils/utils'
import { Request, SubmoduleData, User } from '../../../types/basicTypes' import {
Request,
SubmoduleData,
User,
Submodule,
} from '../../../types/basicTypes'
import dbtools from '../../../utils/dbtools' import dbtools from '../../../utils/dbtools'
const minimumAlowwedSessions = 2 // how many sessions are allowed for a user const minimumAlowwedSessions = 2 // how many sessions are allowed for a user
@ -38,7 +63,7 @@ function BackupDB(usersDbBackupPath: string, userDB: Database) {
}) })
} }
function setup(data: SubmoduleData): any { function setup(data: SubmoduleData): Submodule {
const { app, userDB, url /* publicdirs, moduleSpecificData */ } = data const { app, userDB, url /* publicdirs, moduleSpecificData */ } = data
let domain: any = url.split('.') // [ "https://api", "frylabs", "net" ] let domain: any = url.split('.') // [ "https://api", "frylabs", "net" ]
domain.shift() // [ "frylabs", "net" ] domain.shift() // [ "frylabs", "net" ]

View file

@ -1,4 +1,22 @@
export interface Users {} /* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
const DBStruct = { const DBStruct = {
users: { users: {

View file

@ -69,7 +69,7 @@ function GetApp(): ModuleType {
}) })
app.use(express.static(nextdir)) app.use(express.static(nextdir))
const linksFile = 'data/links.json' const linksFile = 'data/links.json'
let links: any = {} let links: { [key: string]: string } = {}
function loadDonateURL() { function loadDonateURL() {
try { try {

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import express from 'express' import express from 'express'
import { SearchResultQuestion } from '../utils/classes' import { SearchResultQuestion } from '../utils/classes'
import type { Database } from 'better-sqlite3' import type { Database } from 'better-sqlite3'
@ -77,8 +97,8 @@ export interface Request<T = any> extends express.Request {
body: T body: T
cookies: any cookies: any
session: any session: any
busboy: any
files: any files: any
query: { [key: string]: string }
} }
export interface SubmoduleData { export interface SubmoduleData {
@ -112,8 +132,8 @@ export interface RegisteredUserEntry {
installSource: string installSource: string
date: string date: string
userAgent: string userAgent: string
uid: number loginDate?: string
loginDate: string uid?: number
} }
export interface Submodule { export interface Submodule {

View file

@ -1,5 +1,6 @@
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
Question Server
Question Server
GitLab: <https://gitlab.com/MrFry/mrfrys-node-server> GitLab: <https://gitlab.com/MrFry/mrfrys-node-server>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@ -437,7 +438,7 @@ export function backupData(questionDbs: Array<QuestionDb>): void {
logger.Log(`Backing up ${data.name}...`) logger.Log(`Backing up ${data.name}...`)
writeData( writeData(
data.data, data.data,
`${path}${data.name}_${utils.GetDateString(true)}.json` `${path}${data.name}_${utils.GetDateString(undefined, true)}.json`
) )
logger.Log('Done') logger.Log('Done')
} catch (err) { } catch (err) {

View file

@ -1,4 +1,23 @@
// import os from 'os' /* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import { isMainThread, parentPort, workerData } from 'worker_threads' import { isMainThread, parentPort, workerData } from 'worker_threads'
import logger from './logger' import logger from './logger'
@ -13,7 +32,7 @@ import { editDb, Edits } from './actions'
export interface WorkerResult { export interface WorkerResult {
msg: string msg: string
workerIndex: number workerIndex: number
result: SearchResultQuestion[] result?: SearchResultQuestion[]
} }
interface DetailedMatch { interface DetailedMatch {
@ -557,7 +576,7 @@ function doSearch(
function setNoPossibleAnswersPenalties( function setNoPossibleAnswersPenalties(
possibleAnswers: QuestionData['possibleAnswers'], possibleAnswers: QuestionData['possibleAnswers'],
result: SearchResultQuestion[] result: SearchResultQuestion[]
): any { ): SearchResultQuestion[] {
if (!Array.isArray(possibleAnswers)) { if (!Array.isArray(possibleAnswers)) {
return result return result
} }
@ -605,9 +624,6 @@ interface WorkData {
} }
if (!isMainThread) { if (!isMainThread) {
// os.setPriority(10)
// logger.Log(`Worker thread priority set to ${os.getPriority()}`)
const { const {
workerIndex, workerIndex,
initData, initData,

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
// https://www.sqlitetutorial.net/sqlite-nodejs/ // https://www.sqlitetutorial.net/sqlite-nodejs/
// https://github.com/JoshuaWise/better-sqlite3/blob/HEAD/docs/api.md // https://github.com/JoshuaWise/better-sqlite3/blob/HEAD/docs/api.md
@ -16,18 +36,25 @@ export default {
sanitizeQuery: sanitizeQuery, sanitizeQuery: sanitizeQuery,
} }
import Sqlite, { Database } from 'better-sqlite3' import Sqlite, { Database, RunResult } from 'better-sqlite3'
import logger from '../utils/logger' import logger from '../utils/logger'
import utils from '../utils/utils' import utils from '../utils/utils'
const debugLog = process.env.NS_SQL_DEBUG_LOG const debugLog = process.env.NS_SQL_DEBUG_LOG
function sanitizeQuery(val: string): string { function sanitizeQuery(val: string | number): string | number {
return val.replace(/'/g, '').replace(/;/g, '') if (typeof val === 'string') {
return val.replace(/'/g, '').replace(/;/g, '')
}
return val
} }
// { asd: 'asd', basd: 4 } => asd = 'asd', basd = 4 // { asd: 'asd', basd: 4 } => asd = 'asd', basd = 4
function GetSqlQuerry(conditions: any, type: string, joiner?: string) { function GetSqlQuerry(
conditions: { [key: string]: string | number },
type?: string,
joiner?: string
) {
const res = Object.keys(conditions).reduce((acc, key) => { const res = Object.keys(conditions).reduce((acc, key) => {
const item = conditions[key] const item = conditions[key]
const conditionKey = sanitizeQuery(key) const conditionKey = sanitizeQuery(key)
@ -53,7 +80,7 @@ function GetSqlQuerry(conditions: any, type: string, joiner?: string) {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
function GetDB(path: string): any { function GetDB(path: string): Database {
utils.CreatePath(path) utils.CreatePath(path)
const res = new Sqlite(path) const res = new Sqlite(path)
res.pragma('synchronous = OFF') res.pragma('synchronous = OFF')
@ -66,7 +93,12 @@ function DebugLog(msg: string) {
} }
} }
function AddColumn(db: any, table: any, col: any): any { // FIXME: this might not work: what is col exactly, and how we use AddColumn?
function AddColumn(
db: Database,
table: string,
col: { [key: string]: string | number }
): RunResult {
try { try {
const colName = Object.keys(col)[0] const colName = Object.keys(col)[0]
const colType = col.type const colType = col.type
@ -77,10 +109,17 @@ function AddColumn(db: any, table: any, col: any): any {
return stmt.run() return stmt.run()
} catch (err) { } catch (err) {
console.error(err) console.error(err)
return null
} }
} }
function TableInfo(db: any, table: any): any { function TableInfo(
db: Database,
table: string
): {
columns: any[]
dataCount: number
} {
try { try {
const command = `PRAGMA table_info(${table})` const command = `PRAGMA table_info(${table})`
const stmt = PrepareStatement(db, command) const stmt = PrepareStatement(db, command)
@ -98,10 +137,16 @@ function TableInfo(db: any, table: any): any {
} }
} catch (err) { } catch (err) {
console.error(err) console.error(err)
return null
} }
} }
function Update(db: any, table: any, newData: any, conditions: any): any { function Update(
db: Database,
table: string,
newData: { [key: string]: string | number },
conditions: { [key: string]: string | number }
): RunResult {
try { try {
const command = `UPDATE ${table} SET ${GetSqlQuerry( const command = `UPDATE ${table} SET ${GetSqlQuerry(
newData, newData,
@ -112,10 +157,15 @@ function Update(db: any, table: any, newData: any, conditions: any): any {
return stmt.run() return stmt.run()
} catch (err) { } catch (err) {
console.error(err) console.error(err)
return null
} }
} }
function Delete(db: any, table: any, conditions: any): any { function Delete(
db: Database,
table: string,
conditions: { [key: string]: string | number }
): RunResult {
try { try {
const command = `DELETE FROM ${table} WHERE ${GetSqlQuerry( const command = `DELETE FROM ${table} WHERE ${GetSqlQuerry(
conditions, conditions,
@ -126,10 +176,31 @@ function Delete(db: any, table: any, conditions: any): any {
return stmt.run() return stmt.run()
} catch (err) { } catch (err) {
console.error(err) console.error(err)
return null
} }
} }
function CreateTable(db: any, name: any, columns: any, foreignKeys: any): any { interface DbColumnDescription {
[key: string]: {
type: string
primary?: boolean
autoIncrement?: boolean
notNull?: boolean
defaultZero?: boolean
[key: string]: any
}
}
function CreateTable(
db: Database,
name: string,
columns: DbColumnDescription,
foreignKeys: {
keysFrom: string[]
table: string
keysTo: string[]
}[]
): RunResult {
// CREATE TABLE users(pw text PRIMARY KEY NOT NULL, id number, lastIP text, notes text, loginCount // CREATE TABLE users(pw text PRIMARY KEY NOT NULL, id number, lastIP text, notes text, loginCount
// number, lastLogin text, lastAccess text // number, lastLogin text, lastAccess text
// //
@ -160,20 +231,14 @@ function CreateTable(db: any, name: any, columns: any, foreignKeys: any): any {
const fKeys: string[] = [] const fKeys: string[] = []
if (foreignKeys) { if (foreignKeys) {
foreignKeys.forEach( foreignKeys.forEach((foreignKey) => {
(foreignKey: { const { keysFrom, table, keysTo } = foreignKey
keysFrom: string[] fKeys.push(
table: string `, FOREIGN KEY(${keysFrom.join(
keysTo: string[] ', '
}) => { )}) REFERENCES ${table}(${keysTo.join(', ')})`
const { keysFrom, table, keysTo } = foreignKey )
fKeys.push( })
`, FOREIGN KEY(${keysFrom.join(
', '
)}) REFERENCES ${table}(${keysTo.join(', ')})`
)
}
)
} }
// IF NOT EXISTS // IF NOT EXISTS
@ -182,10 +247,11 @@ function CreateTable(db: any, name: any, columns: any, foreignKeys: any): any {
return stmt.run() return stmt.run()
} catch (err) { } catch (err) {
console.error(err) console.error(err)
return null
} }
} }
function SelectAll(db: any, from: any): any { function SelectAll(db: Database, from: string): any[] {
try { try {
const command = `SELECT * from ${from}` const command = `SELECT * from ${from}`
@ -193,11 +259,17 @@ function SelectAll(db: any, from: any): any {
return stmt.all() return stmt.all()
} catch (err) { } catch (err) {
console.error(err) console.error(err)
return null
} }
} }
// SELECT * FROM MyTable WHERE SomeColumn > LastValue ORDER BY SomeColumn LIMIT 100; // SELECT * FROM MyTable WHERE SomeColumn > LastValue ORDER BY SomeColumn LIMIT 100;
function Select(db: any, from: any, conditions: any, options: any = {}): any { function Select(
db: Database,
from: string,
conditions: { [key: string]: string | number },
options: { joiner?: string; limit?: number } = {}
): any[] {
const { joiner, limit } = options const { joiner, limit } = options
try { try {
@ -215,10 +287,15 @@ function Select(db: any, from: any, conditions: any, options: any = {}): any {
return stmt.all() return stmt.all()
} catch (err) { } catch (err) {
console.error(err) console.error(err)
return null
} }
} }
function Insert(db: any, table: any, data: any): any { function Insert(
db: Database,
table: string,
data: { [key: string]: number | string }
): RunResult {
try { try {
const cols = Object.keys(data) const cols = Object.keys(data)
.reduce((acc, key) => { .reduce((acc, key) => {
@ -228,15 +305,13 @@ function Insert(db: any, table: any, data: any): any {
.join(', ') .join(', ')
const values = Object.keys(data) const values = Object.keys(data)
.reduce((acc, key) => { .map((item) => {
const item = data[key]
if (typeof item === 'string') { if (typeof item === 'string') {
acc.push(`'${item}'`) return `'${item}'`
} else { } else {
acc.push(`${item}`) return `${item}`
} }
return acc })
}, [])
.join(', ') .join(', ')
const command = `INSERT INTO ${table} (${cols}) VALUES (${values})` const command = `INSERT INTO ${table} (${cols}) VALUES (${values})`
@ -245,25 +320,22 @@ function Insert(db: any, table: any, data: any): any {
return stmt.run() return stmt.run()
} catch (err) { } catch (err) {
console.error(err) console.error(err)
return null
} }
} }
function runStatement(db: any, command: string, runType?: string): any { function runStatement(db: Database, command: string, runType?: string): any {
const stmt = PrepareStatement(db, command) const stmt = PrepareStatement(db, command)
if (!runType) { if (!runType) {
return stmt.all() return stmt.all()
} else if (runType === 'run') { } else if (runType === 'run') {
return stmt.run() return stmt.run()
} }
return null
} }
function CloseDB(db: any): void { function CloseDB(db: Database): void {
db.close((err: Error) => { db.close()
if (err) {
return console.error(err.message)
}
DebugLog('Close the database connection.')
})
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------

View file

@ -106,18 +106,6 @@ function LogReq(
statusCode?: string | number statusCode?: string | number
): void { ): void {
try { try {
const ip: any =
req.headers['cf-connecting-ip'] || req.connection.remoteAddress
// if (!toFile) {
// ip = expandWithSpaces(ip, 39)
// }
const nolog = noLogips.some((noLogip) => {
return ip.includes(noLogip)
})
if (nolog) {
return
}
let logEntry = '' // logHashed(ip) let logEntry = '' // logHashed(ip)
let dl = DELIM let dl = DELIM
if (req.url.includes('lred')) { if (req.url.includes('lred')) {

View file

@ -1,3 +1,23 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
export default { export default {
ReadFile: ReadFile, ReadFile: ReadFile,
ReadJSON: ReadJSON, ReadJSON: ReadJSON,
@ -24,7 +44,7 @@ import { Request } from '../types/basicTypes'
interface URLFormatOptions { interface URLFormatOptions {
pathname?: string pathname?: string
query?: any query?: { [key: string]: string }
} }
function formatUrl(options: URLFormatOptions): string { function formatUrl(options: URLFormatOptions): string {
@ -42,8 +62,11 @@ function formatUrl(options: URLFormatOptions): string {
return path + queryString return path + queryString
} }
function GetDateString(noTime?: boolean): string { function GetDateString(
const date = new Date() referenceDate?: Date | string,
noTime?: boolean
): string {
const date = referenceDate ? new Date(referenceDate) : new Date()
if (noTime) { if (noTime) {
return ( return (
@ -183,7 +206,14 @@ function deleteFile(fname: string): Boolean {
return false return false
} }
function uploadFile(req: Request, path: string): Promise<any> { function uploadFile(
req: Request,
path: string
): Promise<{
body: Request['body']
fileName: string
filePath: string
}> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
if (!req.files) { if (!req.files) {
@ -235,7 +265,7 @@ function uploadFile(req: Request, path: string): Promise<any> {
}) })
} }
function statFile(file: string): any { function statFile(file: string): fs.Stats {
if (FileExists(file)) { if (FileExists(file)) {
return fs.statSync(file) return fs.statSync(file)
} else { } else {
@ -243,7 +273,7 @@ function statFile(file: string): any {
} }
} }
function renameFile(oldPath: string, newPath: string): any { function renameFile(oldPath: string, newPath: string): string {
if (FileExists(oldPath)) { if (FileExists(oldPath)) {
fs.renameSync(oldPath, newPath) fs.renameSync(oldPath, newPath)
return newPath return newPath

View file

@ -1,10 +1,30 @@
/* ----------------------------------------------------------------------------
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/>.
------------------------------------------------------------------------- */
import { Worker } from 'worker_threads' import { Worker } from 'worker_threads'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { EventEmitter } from 'events' import { EventEmitter } from 'events'
import os from 'os' import os from 'os'
import logger from './logger' import logger from './logger'
import { Result } from './actions' import { Result, Edits } from './actions'
import type { Question, QuestionDb, QuestionData } from '../types/basicTypes' import type { Question, QuestionDb, QuestionData } from '../types/basicTypes'
import type { WorkerResult } from './classes' import type { WorkerResult } from './classes'
@ -27,7 +47,7 @@ interface TaskObject {
searchTillMatchPercent?: number searchTillMatchPercent?: number
[key: string]: any [key: string]: any
} }
| { dbIndex: number; edits: any } | { dbIndex: number; edits: Edits }
| QuestionDb | QuestionDb
| Result | Result
} }
@ -76,7 +96,7 @@ function handleWorkerError(worker: WorkerObj, err: Error) {
} }
// TODO: accuire all workers here, and handle errors so they can be removed if threads exit // TODO: accuire all workers here, and handle errors so they can be removed if threads exit
export function msgAllWorker(data: TaskObject): Promise<any> { export function msgAllWorker(data: TaskObject): Promise<WorkerResult[]> {
logger.DebugLog('MSGING ALL WORKER', 'job', 1) logger.DebugLog('MSGING ALL WORKER', 'job', 1)
return new Promise((resolve) => { return new Promise((resolve) => {
const promises: Promise<WorkerResult>[] = [] const promises: Promise<WorkerResult>[] = []
@ -93,7 +113,7 @@ export function msgAllWorker(data: TaskObject): Promise<any> {
export function doALongTask( export function doALongTask(
obj: TaskObject, obj: TaskObject,
targetWorkerIndex?: number targetWorkerIndex?: number
): Promise<any> { ): Promise<WorkerResult> {
if (Object.keys(pendingJobs).length > alertOnPendingCount) { if (Object.keys(pendingJobs).length > alertOnPendingCount) {
logger.Log( logger.Log(
`More than ${alertOnPendingCount} callers waiting for free resource! (${ `More than ${alertOnPendingCount} callers waiting for free resource! (${
@ -120,7 +140,7 @@ export function doALongTask(
}) })
} }
export function initWorkerPool(initData: any): Array<WorkerObj> { export function initWorkerPool(initData: Array<QuestionDb>): Array<WorkerObj> {
if (workers) { if (workers) {
logger.Log('WORKERS ALREADY EXISTS', logger.GetColor('redbg')) logger.Log('WORKERS ALREADY EXISTS', logger.GetColor('redbg'))
return null return null
@ -150,7 +170,6 @@ export function initWorkerPool(initData: any): Array<WorkerObj> {
function processJob() { function processJob() {
if (Object.keys(pendingJobs).length > 0) { if (Object.keys(pendingJobs).length > 0) {
// FIXME: FIFO OR ANYTHING ELSE (JOB PROCESSING ORDER)
const keys = Object.keys(pendingJobs) const keys = Object.keys(pendingJobs)
let jobKey: string, freeWorker: WorkerObj let jobKey: string, freeWorker: WorkerObj
let i = 0 let i = 0
@ -239,11 +258,18 @@ function doSomething(currWorker: WorkerObj, obj: TaskObject) {
}) })
} }
const workerTs = (file: string, wkOpts: any) => { const workerTs = (
wkOpts.eval = true file: string,
if (!wkOpts.workerData) { wkOpts: {
wkOpts.workerData = {} workerData: {
workerIndex: number
initData: QuestionDb[]
__filename?: string
}
eval?: boolean
} }
) => {
wkOpts.eval = true
wkOpts.workerData.__filename = file wkOpts.workerData.__filename = file
return new Worker( return new Worker(
` `