diff --git a/README.md b/README.md index 9e9cad4..3544094 100755 --- a/README.md +++ b/README.md @@ -69,6 +69,8 @@ To setup P2P functionality you have to create a few files in `./data/p2p`: * `peers.json` : an array, with objects same as above, and `{ publicKey: "public key of the server" }`. Public key is used to encrypt the users database in the response, so they can be synced too. +Extra configuration: HTTP and pw! TODO + Uppon syncing data or having a peer request data from your server there will be new entries in `./data/p2p/thirdPartyPeers.json`. Here you can review the peers, see their contact and host, and if you choose you can add them to your `peers.json` file. `thirdPartyPeers.json` should also contain @@ -138,7 +140,6 @@ needed at all | NS_THREAD_COUNT | number | Nubmer of CPU cores to use | | NS_NOUSER | boolean | If the authorization should be skipped (for testing) | | NS_NO_HTTPS_FORCE | boolean | Disables automatic redirects from http to https | - | NS_DEVEL | boolean | Developemnt mode. Now it only forces login page to use localhost | | NS_LOGLEVEL | number | Debug log level, 0 is the least verbose | | NS_NOLOG | boolean | If logging should be skipped | | NS_SQL_DEBUG_LOG | boolean | If the SQL queries should be logged | diff --git a/package.json b/package.json index 5ac2113..e7b52ac 100755 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "scripts": { "start": "node ./dist/server.js", - "dev": "npm run build && NS_THREAD_COUNT=2 NS_DEVEL=1 NS_NOUSER=1 node --inspect ./dist/server.js", + "dev": "npm run build && NS_NO_HTTPS_FORCE=1 NS_THREAD_COUNT=2 NS_NOUSER=1 node --inspect ./dist/server.js", "build": "tsc && bash -c './scripts/postBuild.sh'", "export": "tsc && bash -c './scripts/postBuild.sh'", "test": "NS_NOLOG=1 NS_THREAD_COUNT=1 jest", diff --git a/src/middlewares/auth.middleware.ts b/src/middlewares/auth.middleware.ts index c7ff824..916cfb6 100644 --- a/src/middlewares/auth.middleware.ts +++ b/src/middlewares/auth.middleware.ts @@ -24,6 +24,10 @@ import type { Database } from 'better-sqlite3' import logger from '../utils/logger' import dbtools from '../utils/dbtools' +import { paths } from '../utils/files' +import utils from '../utils/utils' + +const domain = utils.ReadFile(paths.domainFile).trim() interface Options { userDB: Database @@ -31,7 +35,7 @@ interface Options { } export const testUser: User = { - id: 19, + id: 1, avaiblePWRequests: 645, pwRequestCount: 19, created: new Date().getTime(), @@ -51,7 +55,8 @@ function renderLogin(req: Request, res: Response) { }) } else { res.render('login', { - devel: process.env.NS_DEVEL, + useHttp: process.env.NS_NO_HTTPS_FORCE, + domain: domain, }) } } diff --git a/src/modules/api/api.ts b/src/modules/api/api.ts index 2c0e82b..8087c12 100644 --- a/src/modules/api/api.ts +++ b/src/modules/api/api.ts @@ -105,7 +105,7 @@ function GetApp(): ModuleType { function reloadRootRedirectURL() { if (utils.FileExists(paths.rootRedirectToFile)) { - rootRedirectURL = utils.ReadFile(paths.rootRedirectToFile) + rootRedirectURL = utils.ReadFile(paths.rootRedirectToFile).trim() } } diff --git a/src/modules/api/submodules/p2p.ts b/src/modules/api/submodules/p2p.ts index d6f5673..11668d1 100644 --- a/src/modules/api/submodules/p2p.ts +++ b/src/modules/api/submodules/p2p.ts @@ -19,7 +19,6 @@ ------------------------------------------------------------------------- */ import { Response } from 'express' -import http from 'http' import logger from '../../../utils/logger' import { @@ -60,6 +59,7 @@ import { SelfInfoSchema, } from '../../../types/typeSchemas' import { paths } from '../../../utils/files' +import { GetResult, get, post } from '../../../utils/networkUtils' interface MergeResult { newData: Subject[] @@ -87,47 +87,17 @@ interface RemotePeerInfo { } } -interface RequestResult { - data?: T - error?: Error - options?: http.RequestOptions -} - interface SyncDataRes { questionDbs?: QuestionDb[] remoteInfo?: RemotePeerInfo encryptedUsers?: string - count: { + count?: { qdbs: number subjects: number questions: number } } -// FIXME: to utils/http.ts -function get(options: http.RequestOptions): Promise> { - return new Promise((resolve) => { - const req = http.get(options, function (res) { - const bodyChunks: Uint8Array[] = [] - res.on('data', (chunk) => { - bodyChunks.push(chunk) - }).on('end', () => { - const body = Buffer.concat(bodyChunks).toString() - try { - resolve({ data: JSON.parse(body) }) - } catch (e) { - console.log(body) - resolve({ error: e, options: options }) - } - }) - }) - req.on('error', function (e) { - resolve({ error: e, options: options }) - // reject(e) - }) - }) -} - function updateThirdPartyPeers( newVal: Omit[] ) { @@ -341,6 +311,54 @@ function setupQuestionsForMerge(qdb: QuestionDb, peer: PeerInfo) { } } +async function authAndGetNewData({ + peer, + selfInfo, + lastSyncWithPeer, + lastSync, +}: { + peer: PeerInfo + selfInfo: PeerInfo + lastSyncWithPeer: number + lastSync: number +}): Promise> { + const { data, error, cookies } = await post<{ + result: string + msg: string + }>({ + hostname: peer.host, + path: '/api/login', + port: peer.port, + bodyObject: { pw: peer.pw }, + http: peer.http, + }) + + if (error || !data || data.result !== 'success') { + return { + error: data ? new Error(data.msg) : error, + data: { + peer: peer, + }, + } + } + + const getRes = await get( + { + headers: { + cookie: cookies.join(), + }, + host: peer.host, + port: peer.port, + path: `/api/getnewdatasince?host=${encodeURIComponent( + peerToString(selfInfo) + )}${lastSync ? `&since=${lastSyncWithPeer}` : ''}`, + }, + peer.http + ) + + return { ...getRes, data: { ...getRes.data, peer: peer } } +} + function setup(data: SubmoduleData): Submodule { const { app, @@ -453,32 +471,35 @@ function setup(data: SubmoduleData): Submodule { // FUNCTIONS // --------------------------------------------------------------------------------------- - function getSelfInfo(includeQdbInfo?: boolean) { + function getSelfInfo(includeVerboseInfo?: boolean) { const result: RemotePeerInfo = { selfInfo: selfInfo, myPeers: peers, } - result.serverRevision = utils.getGitRevision(__dirname) - result.scriptRevision = utils.getGitRevision( - paths.moodleTestUserscriptDir - ) - result.qminingPageRevision = utils.getGitRevision(paths.qminingPageDir) - result.dataEditorRevision = utils.getGitRevision( - paths.dataEditorPageDir - ) - result.qminingPageBuildTime = utils - .statFile(paths.qminingIndexPath) - ?.mtime.getTime() - result.serverBuildTime = utils - .statFile(paths.serverPath) - ?.mtime.getTime() - result.dataEditorBuildTime = utils - .statFile(paths.dataEditorIndexPath) - ?.mtime.getTime() - result.scriptVersion = utils.getScriptVersion() - result.userCount = dbtools.TableInfo(userDB, 'users').dataCount - if (includeQdbInfo) { + if (includeVerboseInfo) { + result.serverRevision = utils.getGitRevision(__dirname) + result.scriptRevision = utils.getGitRevision( + paths.moodleTestUserscriptDir + ) + result.qminingPageRevision = utils.getGitRevision( + paths.qminingPageDir + ) + result.dataEditorRevision = utils.getGitRevision( + paths.dataEditorPageDir + ) + result.qminingPageBuildTime = utils + .statFile(paths.qminingIndexPath) + ?.mtime.getTime() + result.serverBuildTime = utils + .statFile(paths.serverPath) + ?.mtime.getTime() + result.dataEditorBuildTime = utils + .statFile(paths.dataEditorIndexPath) + ?.mtime.getTime() + result.scriptVersion = utils.getScriptVersion() + result.userCount = dbtools.TableInfo(userDB, 'users').dataCount + const questionDbCount = getQuestionDbs().length const { subjCount, questionCount } = countOfQdbs(getQuestionDbs()) result.qdbInfo = { @@ -585,19 +606,12 @@ function setup(data: SubmoduleData): Submodule { const requests = peers.map((peer) => { const lastSyncWithPeer = peer.lastSync || 0 - return new Promise>( - (resolve) => { - get({ - host: peer.host, - port: peer.port, - path: `/getnewdatasince?host=${encodeURIComponent( - peerToString(selfInfo) - )}${lastSync ? `&since=${lastSyncWithPeer}` : ''}`, - }).then((res) => { - resolve({ ...res, data: { ...res.data, peer: peer } }) - }) - } - ) + return authAndGetNewData({ + peer: peer, + selfInfo: selfInfo, + lastSyncWithPeer: lastSyncWithPeer, + lastSync: lastSync, + }) }) const allResults = await Promise.all(requests) @@ -912,6 +926,10 @@ function setup(data: SubmoduleData): Submodule { // --------------------------------------------------------------------------------------- // APP SETUP // --------------------------------------------------------------------------------------- + app.get('/selfInfo', (_req: Request, res: Response) => { + res.json(selfInfo) + }) + app.get('/p2pinfo', (_req: Request, res: Response) => { res.json(getSelfInfo(true)) }) diff --git a/src/modules/api/submodules/userManagement.ts b/src/modules/api/submodules/userManagement.ts index 890d87b..dbe25c0 100644 --- a/src/modules/api/submodules/userManagement.ts +++ b/src/modules/api/submodules/userManagement.ts @@ -68,7 +68,7 @@ function createDefaultUser(userDb: Database) { const pw = uuidv4() const insertRes = dbtools.Insert(userDb, 'users', { pw: pw, - avaiblePWRequests: 0, + avaiblePWRequests: 50, created: utils.GetDateString(), }) logger.Log('ID and PW for user #1: ', 'yellowbg') diff --git a/src/server.ts b/src/server.ts index 2e74a69..f67d9ce 100755 --- a/src/server.ts +++ b/src/server.ts @@ -267,7 +267,7 @@ app.get('*', (req, res) => { if (req.is('application/json')) { res.status(404).end() } else { - res.status(404).render('404') + res.status(404).render('404', { domain: domain }) } }) diff --git a/src/sharedViews/404.ejs b/src/sharedViews/404.ejs index 90dc519..4209515 100755 --- a/src/sharedViews/404.ejs +++ b/src/sharedViews/404.ejs @@ -3,7 +3,7 @@ - Nem található - Qmining | Frylabs.net + Qmining | <%= domain %> - 404