p2p instant question sending fixes

This commit is contained in:
mrfry 2023-04-26 15:02:50 +02:00
parent 977c118da8
commit f047701106
9 changed files with 75 additions and 56 deletions

View file

@ -93,11 +93,11 @@ To setup P2P functionality you have to create a few files in `./data/p2p`:
} }
``` ```
* `peers.json` : an array, with objects same as above, and: * `peers.json`: List of registered peers. An array, with objects same as above, and:
```json ```json
{ {
"pw": "password to the host, so the server can log in there. Please use a dedicated password, that only the server uses!", "pw": "password to the host, so the server can log in there. Please use a dedicated password, that only the server uses!",
"publicKey": "public key of the server" "publicKey": "public key of the server for encryption"
} }
``` ```
Public key is optional, but needed to encrypt and add the users database in the response, so they Public key is optional, but needed to encrypt and add the users database in the response, so they

View file

@ -56,7 +56,7 @@ function renderLogin(req: Request, res: Response) {
if (req.headers['content-type'] === 'application/json') { if (req.headers['content-type'] === 'application/json') {
res.json({ res.json({
result: 'nouser', result: 'nouser',
msg: 'You are not logged in', message: 'You are not logged in',
}) })
return return
} else { } else {

View file

@ -325,13 +325,11 @@ async function authAndGetNewData({
peer, peer,
selfInfo, selfInfo,
lastSyncWithPeer, lastSyncWithPeer,
lastSync,
}: { }: {
peers: PeerInfo[] peers: PeerInfo[]
peer: PeerInfo peer: PeerInfo
selfInfo: PeerInfo selfInfo: PeerInfo
lastSyncWithPeer: number lastSyncWithPeer: number
lastSync: number
}): Promise<GetResult<SyncDataRes & { peer: PeerInfo }>> { }): Promise<GetResult<SyncDataRes & { peer: PeerInfo }>> {
let sessionCookie = peer.sessionCookie let sessionCookie = peer.sessionCookie
@ -354,13 +352,13 @@ async function authAndGetNewData({
return get<SyncDataRes>( return get<SyncDataRes>(
{ {
headers: { headers: {
cookies: `sessionID=${sessionCookie}`, cookie: `sessionID=${sessionCookie}`,
}, },
host: peer.host, host: peer.host,
port: peer.port, port: peer.port,
path: `/api/getnewdatasince?host=${encodeURIComponent( path: `/api/getnewdatasince?host=${encodeURIComponent(
peerToString(selfInfo) peerToString(selfInfo)
)}${lastSync ? `&since=${lastSyncWithPeer}` : ''}`, )}${lastSyncWithPeer ? `&since=${lastSyncWithPeer}` : ''}`,
}, },
peer.http peer.http
) )
@ -637,7 +635,6 @@ function setup(data: SubmoduleData): Submodule {
peer: peer, peer: peer,
selfInfo: selfInfo, selfInfo: selfInfo,
lastSyncWithPeer: lastSyncWithPeer, lastSyncWithPeer: lastSyncWithPeer,
lastSync: lastSync,
}) })
}) })
@ -671,23 +668,28 @@ function setup(data: SubmoduleData): Submodule {
} }
const recievedDataCounts: (number | string)[][] = [] const recievedDataCounts: (number | string)[][] = []
const resultDataWithoutEmptyDbs = resultDataWithoutErrors.filter( const resultDataWithoutEmptyDbs: (SyncDataRes & { peer: PeerInfo })[] =
(res) => { []
const qdbCount = res.questionDbs.length resultDataWithoutErrors.forEach((res) => {
const { subjCount, questionCount } = countOfQdbs( const qdbCount = res.questionDbs.length
res.questionDbs const { subjCount, questionCount } = countOfQdbs(res.questionDbs)
)
recievedDataCounts.push([ recievedDataCounts.push([
peerToString(res.peer), peerToString(res.peer),
qdbCount, qdbCount,
subjCount, subjCount,
questionCount, questionCount,
]) ])
return questionCount > 0 if (questionCount > 0) {
resultDataWithoutEmptyDbs.push(res)
} else {
updatePeersFile(peers, {
...res.peer,
lastSync: syncStart,
})
} }
) })
logger.Log(`\tRecieved data from peers:`) logger.Log(`\tRecieved data from peers:`)
logger.logTable( logger.logTable(

View file

@ -600,8 +600,7 @@ function setup(data: SubmoduleData): Submodule {
) )
res.json({ res.json({
success: resultArray.length > 0, success: true,
newQuestions: resultArray, // FIXME: this is useless?
totalNewQuestions: totalNewQuestions, totalNewQuestions: totalNewQuestions,
}) })

View file

@ -111,9 +111,9 @@
const textNode = document.getElementById('text') const textNode = document.getElementById('text')
if (resp.result === 'success') { if (resp.result === 'success') {
location.reload() location.reload()
textNode.innerText = resp.msg textNode.innerText = resp.message
} else { } else {
textNode.innerText = resp.msg textNode.innerText = resp.message
button.disabled = false button.disabled = false
button.classList.remove('disabledButton') button.classList.remove('disabledButton')
} }

View file

@ -14,19 +14,37 @@ export function get<T = any>(
const provider = useHttp ? http : https const provider = useHttp ? http : https
return new Promise((resolve) => { return new Promise((resolve) => {
const req = provider.get(options, function (res) { const req = provider.get(
const bodyChunks: Uint8Array[] = [] {
res.on('data', (chunk) => { ...options,
bodyChunks.push(chunk) headers: {
}).on('end', () => { ...options?.headers,
const body = Buffer.concat(bodyChunks).toString() 'Content-Type': 'application/json',
try { },
resolve({ data: JSON.parse(body) }) },
} catch (e) { function (res) {
resolve({ error: e, options: options }) const bodyChunks: Uint8Array[] = []
} res.on('data', (chunk) => {
}) bodyChunks.push(chunk)
}) }).on('end', () => {
const body = Buffer.concat(bodyChunks).toString()
try {
if (res.statusCode === 200) {
resolve({ data: JSON.parse(body) })
} else {
resolve({
data: JSON.parse(body),
error: new Error(
`HTTP response code: ${res.statusCode}`
),
})
}
} catch (e) {
resolve({ error: e, options: options })
}
})
}
)
req.on('error', function (e) { req.on('error', function (e) {
resolve({ error: e, options: options }) resolve({ error: e, options: options })
}) })
@ -36,7 +54,7 @@ export function get<T = any>(
export interface PostResult<T> { export interface PostResult<T> {
data?: T data?: T
error?: Error error?: Error
cookies?: string[] cookie?: string[]
} }
interface PostParams { interface PostParams {
@ -45,7 +63,7 @@ interface PostParams {
port: number port: number
bodyObject: any bodyObject: any
http?: boolean http?: boolean
cookies?: string cookie?: string
} }
// https://nodejs.org/api/http.html#httprequesturl-options-callback // https://nodejs.org/api/http.html#httprequesturl-options-callback
@ -55,7 +73,7 @@ export function post<T = any>({
port, port,
bodyObject, bodyObject,
http, http,
cookies, cookie,
}: PostParams): Promise<PostResult<T>> { }: PostParams): Promise<PostResult<T>> {
const provider = http ? httpRequest : httpsRequest const provider = http ? httpRequest : httpsRequest
const body = JSON.stringify(bodyObject) const body = JSON.stringify(bodyObject)
@ -70,9 +88,9 @@ export function post<T = any>({
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body), 'Content-Length': Buffer.byteLength(body),
...(cookies ...(cookie
? { ? {
cookie: cookies, cookie: cookie,
} }
: {}), : {}),
}, },
@ -88,7 +106,7 @@ export function post<T = any>({
try { try {
resolve({ resolve({
data: JSON.parse(body), data: JSON.parse(body),
cookies: res.headers['set-cookie'], cookie: res.headers['set-cookie'],
}) })
} catch (e) { } catch (e) {
resolve({ error: e }) resolve({ error: e })
@ -101,16 +119,15 @@ export function post<T = any>({
resolve({ error: e }) resolve({ error: e })
}) })
req.write(body) req.end(body)
req.end()
}) })
} }
export function parseCookies(responseCookies: string[]): { export function parseCookie(responseCookie: string[]): {
[key: string]: string [key: string]: string
} { } {
const cookiesArray = responseCookies.join('; ').split('; ') const cookieArray = responseCookie.join('; ').split('; ')
const parsedCookies: { [key: string]: string } = cookiesArray.reduce( const parsedCookie: { [key: string]: string } = cookieArray.reduce(
(acc, cookieString) => { (acc, cookieString) => {
const [key, val] = cookieString.split('=') const [key, val] = cookieString.split('=')
return { return {
@ -120,5 +137,5 @@ export function parseCookies(responseCookies: string[]): {
}, },
{} {}
) )
return parsedCookies return parsedCookie
} }

View file

@ -1,6 +1,6 @@
import { PeerInfo } from '../types/basicTypes' import { PeerInfo } from '../types/basicTypes'
import { paths } from './files' import { paths } from './files'
import { parseCookies, post } from './networkUtils' import { parseCookie, post } from './networkUtils'
import utils from './utils' import utils from './utils'
export function peerToString(peer: { export function peerToString(peer: {
@ -33,7 +33,7 @@ export function updatePeersFile(
} }
export async function loginToPeer(peer: PeerInfo): Promise<string | Error> { export async function loginToPeer(peer: PeerInfo): Promise<string | Error> {
const { data, error, cookies } = await post<{ const { data, error, cookie } = await post<{
result: string result: string
msg: string msg: string
}>({ }>({
@ -48,6 +48,6 @@ export async function loginToPeer(peer: PeerInfo): Promise<string | Error> {
return data ? new Error(data.msg) : error return data ? new Error(data.msg) : error
} }
const parsedCookies = parseCookies(cookies) const parsedCookies = parseCookie(cookie)
return parsedCookies.sessionID return parsedCookies.sessionID
} }

View file

@ -85,7 +85,7 @@ export const handleQuestionsToPeers = async (
http: peer.http, http: peer.http,
path: '/api/isAdding', path: '/api/isAdding',
bodyObject: dataToSend, bodyObject: dataToSend,
cookies: `sessionID=${sessionCookie}`, cookie: `sessionID=${sessionCookie}`,
}) })
} }
@ -115,6 +115,7 @@ export const handleQuestionsToPeers = async (
if (res.error || !res.data?.success) { if (res.error || !res.data?.success) {
results.errors.push(peer) results.errors.push(peer)
console.error('AAAAAAAAAAAAAAAAAAAAAAA')
console.error(res.error || JSON.stringify(res.data)) console.error(res.error || JSON.stringify(res.data))
} else if (res.data?.totalNewQuestions > 0) { } else if (res.data?.totalNewQuestions > 0) {
results.hasNew.push(peer) results.hasNew.push(peer)

@ -1 +1 @@
Subproject commit 8e192d3b23736851423cd469b950a2e97139f357 Subproject commit aad2822226c6fc039ee190581b0eaa55f2859dc9