|
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
|
|
shouldSearchDataFile,
|
|
|
|
|
loadJSON,
|
|
|
|
|
Result,
|
|
|
|
|
isQuestionValid,
|
|
|
|
|
} from '../../utils/actions'
|
|
|
|
|
import dbtools from '../../utils/dbtools'
|
|
|
|
|
import auth from '../../middlewares/auth.middleware'
|
|
|
|
@@ -58,7 +59,6 @@ import {
|
|
|
|
|
|
|
|
|
|
// files
|
|
|
|
|
const msgFile = 'stats/msgs'
|
|
|
|
|
const passwordFile = 'data/dataEditorPasswords.json'
|
|
|
|
|
const dataEditsLog = 'stats/dataEdits'
|
|
|
|
|
const dailyDataCountFile = 'stats/dailyDataCount'
|
|
|
|
|
const usersDbBackupPath = 'data/dbs/backup'
|
|
|
|
@@ -262,8 +262,7 @@ function GetApp(): ModuleType {
|
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
app.get('/getDbs', (req: Request, res: any) => {
|
|
|
|
|
logger.LogReq(req)
|
|
|
|
|
|
|
|
|
|
// logger.LogReq(req)
|
|
|
|
|
res.json(
|
|
|
|
|
questionDbs.map((qdb) => {
|
|
|
|
|
return {
|
|
|
|
@@ -824,114 +823,6 @@ function GetApp(): ModuleType {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------
|
|
|
|
|
// API
|
|
|
|
|
|
|
|
|
|
app.post('/uploaddata', (req: Request, res: any) => {
|
|
|
|
|
// body: JSON.stringify({
|
|
|
|
|
// newData: data,
|
|
|
|
|
// count: getCount(data),
|
|
|
|
|
// initialCount: initialCount,
|
|
|
|
|
// password: password,
|
|
|
|
|
// editedQuestions: editedQuestions
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
count,
|
|
|
|
|
initialCount,
|
|
|
|
|
editedQuestions,
|
|
|
|
|
password /*, newData*/,
|
|
|
|
|
} = req.body
|
|
|
|
|
const respStatuses = {
|
|
|
|
|
invalidPass: 'invalidPass',
|
|
|
|
|
ok: 'ok',
|
|
|
|
|
error: 'error',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.LogReq(req)
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// finding user
|
|
|
|
|
const pwds = JSON.parse(utils.ReadFile(passwordFile))
|
|
|
|
|
const userKey = Object.keys(pwds).find((key) => {
|
|
|
|
|
const userKey = pwds[key]
|
|
|
|
|
return userKey.password === password
|
|
|
|
|
})
|
|
|
|
|
// FIXME: check user type in dataeditorPW-s json
|
|
|
|
|
const user: any = pwds[userKey]
|
|
|
|
|
|
|
|
|
|
// logging and stuff
|
|
|
|
|
logger.Log(`Data upload`, logger.GetColor('bluebg'))
|
|
|
|
|
logger.Log(`PWD: ${password}`, logger.GetColor('bluebg'))
|
|
|
|
|
// returning if user password is not ok
|
|
|
|
|
if (!user) {
|
|
|
|
|
logger.Log(
|
|
|
|
|
`Data upload: invalid password ${password}`,
|
|
|
|
|
logger.GetColor('red')
|
|
|
|
|
)
|
|
|
|
|
utils.AppendToFile(
|
|
|
|
|
utils.GetDateString() +
|
|
|
|
|
'\n' +
|
|
|
|
|
password +
|
|
|
|
|
'(FAILED PASSWORD)\n' +
|
|
|
|
|
JSON.stringify(editedQuestions) +
|
|
|
|
|
'\n\n',
|
|
|
|
|
dataEditsLog
|
|
|
|
|
)
|
|
|
|
|
res.json({ status: respStatuses.invalidPass })
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
`Password accepted for ${user.name}`,
|
|
|
|
|
logger.GetColor('bluebg')
|
|
|
|
|
)
|
|
|
|
|
logger.Log(
|
|
|
|
|
`Old Subjects/Questions: ${initialCount.subjectCount} / ${
|
|
|
|
|
initialCount.questionCount
|
|
|
|
|
} | New: ${count.subjectCount} / ${
|
|
|
|
|
count.questionCount
|
|
|
|
|
} | Edited question count: ${Object.keys(editedQuestions).length}`,
|
|
|
|
|
logger.GetColor('bluebg')
|
|
|
|
|
)
|
|
|
|
|
// saving detailed editedCount
|
|
|
|
|
utils.AppendToFile(
|
|
|
|
|
utils.GetDateString() +
|
|
|
|
|
'\n' +
|
|
|
|
|
JSON.stringify(user) +
|
|
|
|
|
'\n' +
|
|
|
|
|
JSON.stringify(editedQuestions) +
|
|
|
|
|
'\n\n',
|
|
|
|
|
dataEditsLog
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// making backup
|
|
|
|
|
// TODO
|
|
|
|
|
// utils.CopyFile(
|
|
|
|
|
// './' + dataFile,
|
|
|
|
|
// `./publicDirs/qminingPublic/backs/data_before_${
|
|
|
|
|
// user.name
|
|
|
|
|
// }_${utils.GetDateString().replace(/ /g, '_')}`
|
|
|
|
|
// ) // TODO: rewrite to dinamyc public!!!
|
|
|
|
|
// logger.Log('Backup made')
|
|
|
|
|
// // writing data
|
|
|
|
|
// utils.WriteFile(JSON.stringify(newData), dataFile)
|
|
|
|
|
// logger.Log('New data file written')
|
|
|
|
|
// // reloading data file
|
|
|
|
|
// data = [...newData]
|
|
|
|
|
// data = newData
|
|
|
|
|
logger.Log('Data set to newData')
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
status: respStatuses.ok,
|
|
|
|
|
user: user.name,
|
|
|
|
|
})
|
|
|
|
|
logger.Log('Data updating done!', logger.GetColor('bluebg'))
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.Log(`Data upload error! `, logger.GetColor('redbg'))
|
|
|
|
|
console.error(error)
|
|
|
|
|
res.json({ status: respStatuses.error, msg: error.message })
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function getNewQdb(location, maxIndex) {
|
|
|
|
|
logger.Log(
|
|
|
|
@@ -1069,6 +960,10 @@ function GetApp(): ModuleType {
|
|
|
|
|
|
|
|
|
|
function saveQuestion(questions, subj, testUrl, userid) {
|
|
|
|
|
// TODO: clear folder every now and then, check if saved questions exist
|
|
|
|
|
if (!subj) {
|
|
|
|
|
logger.Log('No subj name to save test question')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const questionsToSave = {
|
|
|
|
|
questions: questions,
|
|
|
|
|
subj: subj,
|
|
|
|
@@ -1077,7 +972,7 @@ function GetApp(): ModuleType {
|
|
|
|
|
date: new Date(),
|
|
|
|
|
}
|
|
|
|
|
const fname = `${utils.GetDateString()}_${userid}_${testUrl}.json`
|
|
|
|
|
const subject = getSubjNameWithoutYear(subj)
|
|
|
|
|
const subject = getSubjNameWithoutYear(subj).replace(/\//g, '-')
|
|
|
|
|
const subjPath = `${savedQuestionsDir}/${subject}`
|
|
|
|
|
const savedSubjQuestionsFilePath = `${subjPath}/${savedQuestionsFileName}`
|
|
|
|
|
|
|
|
|
@@ -1451,6 +1346,354 @@ function GetApp(): ModuleType {
|
|
|
|
|
res.json({ msg: 'done' })
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
app.get('/possibleAnswers', (req: Request, res: any) => {
|
|
|
|
|
logger.LogReq(req)
|
|
|
|
|
const files = utils.ReadDir(savedQuestionsDir)
|
|
|
|
|
|
|
|
|
|
files.sort(function(a, b) {
|
|
|
|
|
return (
|
|
|
|
|
fs.statSync(savedQuestionsDir + '/' + b).mtime.getTime() -
|
|
|
|
|
fs.statSync(savedQuestionsDir + '/' + a).mtime.getTime()
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
savedQuestionsFileName: savedQuestionsFileName,
|
|
|
|
|
subjects: files.map((subj) => {
|
|
|
|
|
return {
|
|
|
|
|
name: subj,
|
|
|
|
|
path: `savedQuestions/${subj}/`,
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
app.post('/rmPossibleAnswer', (req: Request, res: any) => {
|
|
|
|
|
logger.LogReq(req)
|
|
|
|
|
const user: User = req.session.user
|
|
|
|
|
|
|
|
|
|
const subj = req.body.subj
|
|
|
|
|
const file = req.body.file
|
|
|
|
|
const savedQuestionsPath = `${savedQuestionsDir}/${subj}/${savedQuestionsFileName}`
|
|
|
|
|
const savedQuestions = utils.ReadJSON(savedQuestionsPath)
|
|
|
|
|
let path = `${savedQuestionsDir}/${subj}/${file}`
|
|
|
|
|
// to prevent deleting ../../../ ... /etc/shadow
|
|
|
|
|
while (path.includes('..')) {
|
|
|
|
|
path = path.replace(/\.\./g, '.')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (utils.FileExists(path)) {
|
|
|
|
|
utils.deleteFile(path)
|
|
|
|
|
|
|
|
|
|
utils.WriteFile(
|
|
|
|
|
JSON.stringify(
|
|
|
|
|
savedQuestions.filter((sq) => {
|
|
|
|
|
return sq.fname !== file
|
|
|
|
|
})
|
|
|
|
|
),
|
|
|
|
|
savedQuestionsPath
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
`User #${user.id} deleted '${file}' from subject '${subj}'`,
|
|
|
|
|
logger.GetColor('cyanbg')
|
|
|
|
|
)
|
|
|
|
|
res.json({
|
|
|
|
|
res: 'ok',
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
logger.Log(
|
|
|
|
|
`User #${user.id} tried to delete '${file}' from subject '${subj}', but failed`,
|
|
|
|
|
logger.GetColor('red')
|
|
|
|
|
)
|
|
|
|
|
res.json({
|
|
|
|
|
res: 'fail',
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
app.post('/updateQuestion', (req: Request, res) => {
|
|
|
|
|
logger.LogReq(req)
|
|
|
|
|
const user: User = req.session.user
|
|
|
|
|
const date = utils.GetDateString()
|
|
|
|
|
let saveDb = false
|
|
|
|
|
|
|
|
|
|
const editType = req.body.type
|
|
|
|
|
const selectedDb = req.body.selectedDb
|
|
|
|
|
if (!editType || !selectedDb) {
|
|
|
|
|
res.json({
|
|
|
|
|
status: 'fail',
|
|
|
|
|
msg: 'No .editType or .selectedDb !',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const dbIndex = questionDbs.findIndex((qdb) => {
|
|
|
|
|
return qdb.name === selectedDb.name
|
|
|
|
|
})
|
|
|
|
|
const currDb = questionDbs[dbIndex]
|
|
|
|
|
|
|
|
|
|
if (dbIndex === -1) {
|
|
|
|
|
res.json({
|
|
|
|
|
status: 'fail',
|
|
|
|
|
msg: `No question db named like ${selectedDb.name}!`,
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
// "index": 0,
|
|
|
|
|
// "subjName": "VHDL programozás",
|
|
|
|
|
// "type": "delete",
|
|
|
|
|
// "selectedDb": {
|
|
|
|
|
// "path": "questionDbs/elearning.uni-obuda.hu.json",
|
|
|
|
|
// "name": "elearning.uni-obuda.hu"
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
if (editType === 'delete') {
|
|
|
|
|
const { index, subjName } = req.body
|
|
|
|
|
let deletedQuestion = {}
|
|
|
|
|
if (isNaN(index) || !subjName) {
|
|
|
|
|
res.json({
|
|
|
|
|
status: 'fail',
|
|
|
|
|
msg: 'No .index or .subjName !',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
questionDbs[dbIndex].data = currDb.data.map((subj) => {
|
|
|
|
|
if (subj.Name !== subjName) {
|
|
|
|
|
return subj
|
|
|
|
|
} else {
|
|
|
|
|
return {
|
|
|
|
|
...subj,
|
|
|
|
|
Questions: subj.Questions.filter((question, i) => {
|
|
|
|
|
if (index === i) {
|
|
|
|
|
deletedQuestion = question
|
|
|
|
|
return false
|
|
|
|
|
} else {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
`User #${user.id} deleted a question from '${subjName}'`,
|
|
|
|
|
logger.GetColor('cyanbg')
|
|
|
|
|
)
|
|
|
|
|
utils.AppendToFile(
|
|
|
|
|
`${date}: User ${user.id} deleted a question from '${subjName}' (index: ${index})`,
|
|
|
|
|
dataEditsLog
|
|
|
|
|
)
|
|
|
|
|
utils.AppendToFile(JSON.stringify(deletedQuestion, null, 2), dataEditsLog)
|
|
|
|
|
saveDb = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
// "index": 0,
|
|
|
|
|
// "subjName": "Elektronika",
|
|
|
|
|
// "type": "edit",
|
|
|
|
|
// "newVal": {
|
|
|
|
|
// "Q": "Analóg műszer esetén az érzékenység az a legkisebb mennyiség, amely a műszer kijelzőjén meghatározott mértékű változást okoz.",
|
|
|
|
|
// "A": "Igaz",
|
|
|
|
|
// "data": {
|
|
|
|
|
// "type": "simple",
|
|
|
|
|
// "possibleAnswers": [
|
|
|
|
|
// "Igaz"
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// "possibleAnswers": [
|
|
|
|
|
// "Igaz"
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// "selectedDb": {
|
|
|
|
|
// "path": "questionDbs/elearning.uni-obuda.hu.json",
|
|
|
|
|
// "name": "elearning.uni-obuda.hu"
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
if (editType === 'edit') {
|
|
|
|
|
const { index, subjName, newVal } = req.body
|
|
|
|
|
let oldVal = {}
|
|
|
|
|
if (isNaN(index) || !subjName) {
|
|
|
|
|
res.json({
|
|
|
|
|
status: 'fail',
|
|
|
|
|
msg: 'No .index or .subjName !',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (!isQuestionValid(newVal)) {
|
|
|
|
|
res.json({
|
|
|
|
|
status: 'fail',
|
|
|
|
|
msg: 'edited question is not valid',
|
|
|
|
|
question: newVal,
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
questionDbs[dbIndex].data = currDb.data.map((subj) => {
|
|
|
|
|
if (subj.Name !== subjName) {
|
|
|
|
|
return subj
|
|
|
|
|
} else {
|
|
|
|
|
return {
|
|
|
|
|
...subj,
|
|
|
|
|
Questions: subj.Questions.map((question, i) => {
|
|
|
|
|
if (index === i) {
|
|
|
|
|
oldVal = question
|
|
|
|
|
return newVal
|
|
|
|
|
} else {
|
|
|
|
|
return question
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
`User #${user.id} edited a question in '${subjName}'`,
|
|
|
|
|
logger.GetColor('cyanbg')
|
|
|
|
|
)
|
|
|
|
|
utils.AppendToFile(
|
|
|
|
|
`${date}: User ${user.id} edited a question in '${subjName}' (index: ${index})`,
|
|
|
|
|
dataEditsLog
|
|
|
|
|
)
|
|
|
|
|
utils.AppendToFile(
|
|
|
|
|
JSON.stringify(
|
|
|
|
|
{
|
|
|
|
|
newVal: newVal,
|
|
|
|
|
oldVal: oldVal,
|
|
|
|
|
},
|
|
|
|
|
null,
|
|
|
|
|
2
|
|
|
|
|
),
|
|
|
|
|
dataEditsLog
|
|
|
|
|
)
|
|
|
|
|
saveDb = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
// "subjName": "Elektronika",
|
|
|
|
|
// "changedQuestions": [
|
|
|
|
|
// {
|
|
|
|
|
// "index": 1,
|
|
|
|
|
// "value": {
|
|
|
|
|
// "Q": "A műszer pontosságát a hibájával fejezzük ki, melyet az osztályjel (osztálypontosság ) mutat meg.",
|
|
|
|
|
// "A": "Hamis",
|
|
|
|
|
// "data": {
|
|
|
|
|
// "type": "simple",
|
|
|
|
|
// "possibleAnswers": [
|
|
|
|
|
// "Igaz",
|
|
|
|
|
// "Hamis"
|
|
|
|
|
// ]
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// ],
|
|
|
|
|
// "deletedQuestions": [
|
|
|
|
|
// 0
|
|
|
|
|
// ],
|
|
|
|
|
// "type": "subjEdit",
|
|
|
|
|
// "selectedDb": {
|
|
|
|
|
// "path": "questionDbs/elearning.uni-obuda.hu.json",
|
|
|
|
|
// "name": "elearning.uni-obuda.hu"
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
if (editType === 'subjEdit') {
|
|
|
|
|
const { subjName, changedQuestions, deletedQuestions } = req.body
|
|
|
|
|
const deletedQuestionsToWrite = []
|
|
|
|
|
const changedQuestionsToWrite = []
|
|
|
|
|
if (
|
|
|
|
|
!Array.isArray(changedQuestions) ||
|
|
|
|
|
!Array.isArray(deletedQuestions)
|
|
|
|
|
) {
|
|
|
|
|
res.json({
|
|
|
|
|
status: 'fail',
|
|
|
|
|
msg: 'no changedQuestions or deletedQuestions!',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// processing changed questions
|
|
|
|
|
questionDbs[dbIndex].data = currDb.data.map((subj) => {
|
|
|
|
|
if (subj.Name !== subjName) {
|
|
|
|
|
return subj
|
|
|
|
|
} else {
|
|
|
|
|
return {
|
|
|
|
|
...subj,
|
|
|
|
|
Questions: subj.Questions.map((question, i) => {
|
|
|
|
|
const changedTo = changedQuestions.find((cq) => {
|
|
|
|
|
return cq.index === i
|
|
|
|
|
})
|
|
|
|
|
if (changedTo) {
|
|
|
|
|
changedQuestionsToWrite.push({
|
|
|
|
|
oldVal: question,
|
|
|
|
|
newVal: changedTo.value,
|
|
|
|
|
})
|
|
|
|
|
return changedTo.value
|
|
|
|
|
} else {
|
|
|
|
|
return question
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// processing deletedQuestions
|
|
|
|
|
questionDbs[dbIndex].data = currDb.data.map((subj) => {
|
|
|
|
|
if (subj.Name !== subjName) {
|
|
|
|
|
return subj
|
|
|
|
|
} else {
|
|
|
|
|
return {
|
|
|
|
|
...subj,
|
|
|
|
|
Questions: subj.Questions.filter((question, i) => {
|
|
|
|
|
const isDeleted = deletedQuestions.includes(i)
|
|
|
|
|
if (isDeleted) {
|
|
|
|
|
deletedQuestionsToWrite.push(question)
|
|
|
|
|
return false
|
|
|
|
|
} else {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
`User #${user.id} modified '${subjName}'. Edited: ${deletedQuestionsToWrite.length}, deleted: ${deletedQuestionsToWrite.length}`,
|
|
|
|
|
logger.GetColor('cyanbg')
|
|
|
|
|
)
|
|
|
|
|
utils.AppendToFile(
|
|
|
|
|
`${date} User #${user.id} modified '${subjName}'. Edited: ${deletedQuestionsToWrite.length}, deleted: ${deletedQuestionsToWrite.length}`,
|
|
|
|
|
dataEditsLog
|
|
|
|
|
)
|
|
|
|
|
utils.AppendToFile(
|
|
|
|
|
JSON.stringify(
|
|
|
|
|
{
|
|
|
|
|
deletedQuestions: deletedQuestionsToWrite,
|
|
|
|
|
changedQuestions: changedQuestionsToWrite,
|
|
|
|
|
},
|
|
|
|
|
null,
|
|
|
|
|
2
|
|
|
|
|
),
|
|
|
|
|
dataEditsLog
|
|
|
|
|
)
|
|
|
|
|
saveDb = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (saveDb) {
|
|
|
|
|
utils.WriteFile(JSON.stringify(currDb.data), currDb.path)
|
|
|
|
|
msgAllWorker({
|
|
|
|
|
qdbs: questionDbs,
|
|
|
|
|
type: 'update',
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
status: 'OK',
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
app.get('*', function(req: Request, res: any) {
|
|
|
|
|