mrfrys-node-server/src/utils/files.ts
2023-04-08 18:19:12 +02:00

248 lines
8.4 KiB
TypeScript

import { Schema } from 'jsonschema'
import {
TestUsersSchema,
isJsonValidAndLogError,
PeersInfoSchema,
ModulesSchema,
SelfInfoSchema,
} from '../types/typeSchemas'
import logger from './logger'
import utils from './utils'
// FIXME: remove all file exists checks from everywhere for files that are created / checked here
type FileDescriptor = {
path: string
schema?: Schema
defaultValue?: string
shouldBe?: string
description?: string
}
export const validateFiles = (): boolean => {
let everythingValid = true
Object.entries(files).forEach(([key, file]: [string, FileDescriptor]) => {
let fileExists = utils.FileExists(file.path)
if (file.defaultValue != null && !fileExists) {
// FIXME: create path too
utils.WriteFile(file.defaultValue, file.path)
fileExists = true
}
if (file.shouldBe && !fileExists) {
const errMsg = [`File "${file.path}" does not exist! (${key})`]
if (file.shouldBe) {
errMsg.push(`Should be: ${file.shouldBe}`)
}
logger.Log(errMsg.join(' '), 'redbg')
everythingValid = false
return
}
if (file.schema && fileExists) {
const val = utils.ReadJSON(file.path)
if (!isJsonValidAndLogError(val, file.schema, file.path)) {
everythingValid = false
return
}
}
})
return everythingValid
}
export const files = {
// --------------------------------------------------------------------------------
// server / modules files
// --------------------------------------------------------------------------------
serverPath: {
path: 'dist/server.js',
shouldBe:
'server main entry file, created after running "npm run build"',
},
qminingPageDir: {
path: 'submodules/qmining-page',
shouldBe:
'qmining page submodule directory, created by pulling submodules / setup script',
},
qminingIndexPath: {
path: 'nextStatic/qminingPagePublic/index.html',
shouldBe:
'qmining page-s build index.html, created by "npm run build" in qmining page submodule dir',
},
dataEditorPageDir: {
path: 'submodules/qmining-data-editor',
shouldBe:
'qmining data editor page submodule directory, created by pulling submodules / setup script',
},
dataEditorIndexPath: {
path: 'nextStatic/dataEditorPublic/index.html',
shouldBe:
'qmining data editor-s build index.html, created by "npm run build" in qmining data editor submodule dir',
},
moodleTestUserscriptDir: {
path: 'submodules/moodle-test-userscript',
shouldBe:
'moodle test userscript submodule directory, created by pulling submodules / setup script',
},
moodleTestUserscriptPath: {
path: 'submodules/moodle-test-userscript/stable.user.js',
shouldBe:
'moodle test userscript file, created by pulling submodules / setup script',
},
domainFile: {
path: 'data/domain',
shouldBe:
'server domain for cookies and stuff, for ex.: "frylabs.net", no "http://" and things like that, just the domain',
},
// --------------------------------------------------------------------------------
// stats files
// --------------------------------------------------------------------------------
registeredScriptsFile: {
path: 'stats/registeredScripts.json',
defaultValue: JSON.stringify([]),
},
askedQuestionFile: {
path: 'stats/askedQuestions',
description: 'text file of recieved data on /ask',
},
recievedQuestionFile: {
path: 'stats/recievedQuestions',
description: 'text file of recieved data on /isAdding',
},
dailyDataCountFile: {
path: 'stats/dailyDataCount',
description: 'text file of daily data count',
},
dataEditsLog: {
path: 'stats/dataEdits',
description: 'text file of data edit logs',
},
// --------------------------------------------------------------------------------
// https files
// --------------------------------------------------------------------------------
privkeyFile: {
path: '/etc/letsencrypt/live/frylabs.net/privkey.pem',
description: 'private key file for https',
},
fullchainFile: {
path: '/etc/letsencrypt/live/frylabs.net/fullchain.pem',
description: 'full chain key file for https',
},
chainFile: {
path: '/etc/letsencrypt/live/frylabs.net/chain.pem',
description: 'chain key file for https',
},
// --------------------------------------------------------------------------------
// api files
// --------------------------------------------------------------------------------
rootRedirectToFile: {
path: 'data/apiRootRedirectTo',
description: 'url to redirect users trying to acces root api path',
},
modulesFile: {
path: './src/modules.json',
shouldBe: 'module files for server',
schema: ModulesSchema,
},
extraModulesFile: {
path: './src/extraModules/extraModules.json',
description: 'extra private modules for server, not tracked by git',
schema: ModulesSchema,
},
statExcludeFile: {
path: './data/statExclude.json',
shouldBe:
'array of strings which if included in requests url-s then the request itself is not counted in stats',
defaultValue: JSON.stringify([]),
schema: { type: 'array', items: { type: 'string' } },
},
usersDBPath: {
path: './data/dbs/users.db',
shouldBe: 'users sqlite db file',
},
// --------------------------------------------------------------------------------
// qmining api
// --------------------------------------------------------------------------------
testUsersFile: {
path: 'data/testUsers.json',
defaultValue: JSON.stringify({ userIds: [] }),
schema: TestUsersSchema,
description:
'test users, recieved data from them wont get added to question dbs',
},
// --------------------------------------------------------------------------------
// log files
// --------------------------------------------------------------------------------
vlogDir: {
path: 'stats/vlogs/',
description: 'verbose logs directory',
},
logDir: {
path: 'stats/logs/',
description: 'basic logs directory',
},
statFile: {
path: 'stats/stats',
defaultValue: JSON.stringify({}),
description: 'json of visited paths all time',
},
vStatFile: {
path: 'stats/vstats',
defaultValue: JSON.stringify({}),
description: 'json of visited paths by day',
},
uStatsFile: {
path: 'stats/ustats',
defaultValue: JSON.stringify({}),
description: 'json of visits per user',
},
uvStatsFile: {
path: 'stats/uvstats',
defaultValue: JSON.stringify({}),
description: 'json of visits per user by day',
},
nologFile: {
path: './data/nolog',
defaultValue: '',
description:
'text file of users seperated by new lines to ignore in logging / stats',
},
// --------------------------------------------------------------------------------
// peer files
// --------------------------------------------------------------------------------
peersPath: {
path: 'data/p2p/',
description: 'p2p files directory',
},
peersFile: {
path: 'data/p2p/peers.json',
description: 'json of list of peers',
defaultValue: JSON.stringify([]),
schema: PeersInfoSchema,
},
selfInfoFile: {
path: 'data/p2p/selfInfo.json',
description: 'json of info of this servers peer functionality',
defaultValue: JSON.stringify({}),
schema: SelfInfoSchema,
},
thirdPartyPeersFile: {
path: 'data/p2p/thirdPartyPeers.json',
description: 'json of third party peers reported by other peers',
},
keyFile: {
path: 'data/p2p/key',
},
} as const satisfies Record<string, FileDescriptor>
export const paths = Object.entries(files).reduce(
(acc, [key, value]) => ({ ...acc, [key]: value.path }),
{}
) as Record<keyof typeof files, string>