sending new users to peers on user creation

This commit is contained in:
mrfry 2023-04-29 09:59:39 +02:00
parent 2f24f214b2
commit cb0ad03336
9 changed files with 351 additions and 172 deletions

View file

@ -60,6 +60,7 @@ import {
peerToString,
updatePeersFile,
} from '../../../utils/p2putils'
import { Database } from 'better-sqlite3'
interface MergeResult {
newData: Subject[]
@ -456,6 +457,31 @@ async function authAndGetNewData({
}
}
function addUsersToDb(
users: User[],
userDB: Database,
extraProps: Partial<User>
) {
let addedUserCount = 0
users.forEach((remoteUser) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id, ...remoteUserWithoutId } = remoteUser
const localUser = dbtools.Select(userDB, 'users', {
pw: remoteUser.pw,
})
if (localUser.length === 0) {
addedUserCount += 1
// FIXME: users will not have consistend id across servers. This may be
// harmless, will see
dbtools.Insert(userDB, 'users', {
...(remoteUserWithoutId as Omit<User, 'id'>),
...extraProps,
})
}
})
return addedUserCount
}
function setup(data: SubmoduleData): Submodule {
const {
app,
@ -696,6 +722,7 @@ function setup(data: SubmoduleData): Submodule {
syncAll
? 'everything'
: Object.entries(shouldSync)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.filter(([_key, value]) => value)
.map(([key]) => key)
.join(', ')
@ -870,26 +897,16 @@ function setup(data: SubmoduleData): Submodule {
try {
userData.forEach((res) => {
if (res.encryptedUsers) {
let addedUserCount = 0
const decryptedUsers: User[] = JSON.parse(
decrypt(privateKey, res.encryptedUsers)
)
decryptedUsers.forEach((remoteUser) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id, ...remoteUserWithoutId } = remoteUser
const localUser = dbtools.Select(userDB, 'users', {
pw: remoteUser.pw,
})
if (localUser.length === 0) {
addedUserCount += 1
// FIXME: users will not have consistend id across servers. This may be
// harmless, will see
dbtools.Insert(userDB, 'users', {
...(remoteUserWithoutId as Omit<User, 'id'>),
sourceHost: peerToString(res.peer),
})
const addedUserCount = addUsersToDb(
decryptedUsers,
userDB,
{
sourceHost: peerToString(res.peer),
}
})
)
resultsCount[peerToString(res.peer)] = {
newUsers: addedUserCount,
}
@ -1169,39 +1186,17 @@ function setup(data: SubmoduleData): Submodule {
app.get('/getnewfilessince', (req: Request, res: Response<any>) => {
const since = Number.isNaN(+req.query.since) ? 0 : +req.query.since
const remoteHost = req.query.host
const hostToLog = remoteHost || 'Unknown host'
const result: any = {
remoteInfo: getSelfInfo(),
}
if (remoteHost) {
const remotePeerInfo = peers.find((peer) => {
return peerToString(peer) === remoteHost
})
if (!remotePeerInfo) {
handleNewThirdPartyPeer(remoteHost)
}
}
const usersSinceDate = since
? new Date(since).toLocaleString()
: 'all time'
logger.Log(
`\tSending new files to ${logger.C(
'blue'
)}${hostToLog}${logger.C()} since ${logger.C(
'blue'
)}${usersSinceDate}${logger.C()}`
)
res.json(result)
res.json({ since: since, message: 'unimplemented' })
})
app.get(
'/getnewuserssince',
(req: Request, res: Response<UserSyncDataRes>) => {
(
req: Request,
res: Response<
UserSyncDataRes & { message?: string; success?: boolean }
>
) => {
logger.LogReq(req)
const since = Number.isNaN(+req.query.since) ? 0 : +req.query.since
@ -1213,47 +1208,61 @@ function setup(data: SubmoduleData): Submodule {
remoteInfo: getSelfInfo(),
}
if (remoteHost) {
const remotePeerInfo = peers.find((peer) => {
return peerToString(peer) === remoteHost
if (!remoteHost) {
res.json({
...result,
success: false,
message: 'remoteHost key is missing from body',
})
if (!remotePeerInfo) {
handleNewThirdPartyPeer(remoteHost)
} else {
hostToLog = peerToString(remotePeerInfo)
}
return
}
if (remotePeerInfo) {
const remotePublicKey = remotePeerInfo?.publicKey
if (remotePublicKey) {
// FIXME: sign data?
const newUsers = getNewUsersSince(since)
sentUsers = newUsers.length
result.encryptedUsers = encrypt(
remotePublicKey,
JSON.stringify(newUsers)
)
const remotePeerInfo = peers.find((peer) => {
return peerToString(peer) === remoteHost
})
if (!remotePeerInfo) {
handleNewThirdPartyPeer(remoteHost)
} else {
hostToLog = peerToString(remotePeerInfo)
}
const usersSinceDate = since
? new Date(since).toLocaleString()
: 'all time'
if (!remotePeerInfo) {
res.json({
success: false,
message:
"couldn't find remote peer info based on remoteHost",
})
return
}
logger.Log(
`\tSending new users to ${logger.C(
'blue'
)}${hostToLog}${logger.C()} since ${logger.C(
'blue'
)}${usersSinceDate}${logger.C()}. Sent users: ${logger.C(
'blue'
)}${sentUsers}${logger.C()}`
)
} else if (remotePeerInfo) {
logger.Log(
`Warning: "${hostToLog}" has no public key saved!`,
'yellowbg'
)
}
}
const remotePublicKey = remotePeerInfo.publicKey
if (remotePublicKey) {
// FIXME: sign data?
const newUsers = getNewUsersSince(since)
sentUsers = newUsers.length
result.encryptedUsers = encrypt(
remotePublicKey,
JSON.stringify(newUsers)
)
const usersSinceDate = since
? new Date(since).toLocaleString()
: 'all time'
logger.Log(
`\tSending new users to ${logger.C(
'blue'
)}${hostToLog}${logger.C()} since ${logger.C(
'blue'
)}${usersSinceDate}${logger.C()}. Sent users: ${logger.C(
'blue'
)}${sentUsers}${logger.C()}`
)
} else if (remotePeerInfo) {
logger.Log(
`Warning: "${hostToLog}" has no public key saved!`,
'yellowbg'
)
}
res.json(result)
@ -1389,6 +1398,57 @@ function setup(data: SubmoduleData): Submodule {
})
})
app.post(
'/newusercreated',
(req: Request<{ host: string; newUsers: string }>, res: Response) => {
logger.LogReq(req)
const encryptedNewUsers = req.body.newUsers
const remoteHost = req.body.host
if (!encryptedNewUsers || !remoteHost) {
res.json({
success: false,
message:
'encryptedNewUsers or remoteHost key are missing from body',
})
return
}
const remotePeerInfo = peers.find((peer) => {
return peerToString(peer) === remoteHost
})
if (!remotePeerInfo) {
res.json({
success: false,
message:
"couldn't find remote peer info based on remoteHost",
})
return
}
const decryptedUsers: User[] = JSON.parse(
decrypt(privateKey, encryptedNewUsers)
)
const addedUserCount = addUsersToDb(decryptedUsers, userDB, {
sourceHost: peerToString(remotePeerInfo),
})
if (addedUserCount > 0) {
logger.Log(
`\tAdded ${addedUserCount} new users from "${peerToString(
remotePeerInfo
)}"`,
'cyan'
)
}
res.json({ success: true, addedUserCount: addedUserCount })
}
)
logger.Log(
'P2P functionality set up. Peers (' +
peers.length +