Skip to content

Commit

Permalink
feat: add storage server proxy for downloading and uploading data fro…
Browse files Browse the repository at this point in the history
…m relay server
  • Loading branch information
EmiM committed Mar 27, 2024
1 parent 066a201 commit 3c6796d
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 9 deletions.
11 changes: 11 additions & 0 deletions packages/backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"dotenv": "8.2.0",
"events": "^3.2.0",
"express": "^4.17.1",
"fetch-retry": "^6.0.0",
"get-port": "^5.1.1",
"go-ipfs": "npm:[email protected]",
"http-server": "^0.12.3",
Expand Down
41 changes: 32 additions & 9 deletions packages/backend/src/nest/socket/socket.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import { CONFIG_OPTIONS, SERVER_IO_PROVIDER } from '../const'
import { ConfigOptions, ServerIoProviderTypes } from '../types'
import { suspendableSocketEvents } from './suspendable.events'
import Logger from '../common/logger'
import fetch from 'node-fetch'
import { ServerStoredCommunityMetadata } from '../storageServerProxy/storageServerProxy.types'
import { p2pAddressesToPairs } from '@quiet/common'

@Injectable()
export class SocketService extends EventEmitter implements OnModuleInit {
Expand Down Expand Up @@ -175,15 +178,35 @@ export class SocketService extends EventEmitter implements OnModuleInit {
socket.on(
SocketActionTypes.DOWNLOAD_INVITE_DATA,
async (payload: { serverAddress: string; cid: string }, callback: (response: CreateNetworkPayload) => void) => {
// this.emit(SocketActionTypes.DOWNLOAD_INVITE_DATA, payload, callback)
console.log('download invite data', payload)
// Mock it for now
callback({
ownership: CommunityOwnership.User,
peers: [],
psk: '',
ownerOrbitDbIdentity: '',
})
// FIXME
this.emit(
SocketActionTypes.DOWNLOAD_STORAGE_SERVER_DATA,
payload,
async (downloadedData: ServerStoredCommunityMetadata) => {
const createNetworkPayload: CreateNetworkPayload = {
ownership: CommunityOwnership.User,
peers: p2pAddressesToPairs(downloadedData.peerList), // TODO: prepare in storageServerProxy
psk: downloadedData.psk,
ownerOrbitDbIdentity: downloadedData.ownerOrbitDbIdentity,
}
const communityMetadataPayload: CommunityMetadata = {
id: downloadedData.id,
ownerCertificate: downloadedData.ownerCertificate,
rootCa: downloadedData.rootCa,
}
// TODO: Save the data to the store
this.emit(SocketActionTypes.SET_COMMUNITY_METADATA, communityMetadataPayload)
// TODO: emit metadata

callback(createNetworkPayload)
}
)
// callback({
// ownership: CommunityOwnership.User,
// peers: data.peerList,
// psk: data.psk,
// ownerOrbitDbIdentity: data.ownerOrbitDbIdentity,
// })
}
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Module } from '@nestjs/common'
import { ServerProxyService } from './storageServerProxy.service'

@Module({
providers: [ServerProxyService],
exports: [ServerProxyService],
})
export class ServerProxyServiceModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Injectable, OnModuleInit } from '@nestjs/common'
import EventEmitter from 'events'
import { ServerStoredCommunityMetadata } from './storageServerProxy.types'
import fetchRetry from 'fetch-retry'
import { SocketActionTypes } from '@quiet/types'
const fetch = fetchRetry(global.fetch)
// TODO: handle errors
// TODO: handle retries
@Injectable()
export class ServerProxyService extends EventEmitter implements OnModuleInit {
serverAddress: string

constructor() {
super()
}

onModuleInit() {
this.on(SocketActionTypes.SET_STORAGE_SERVER_ADDRESS, (payload: { serverAddress: string }) =>
this.setServerAddress(payload.serverAddress)
)
this.on(
SocketActionTypes.DOWNLOAD_STORAGE_SERVER_DATA,
async (payload: { cid: string }, callback: (downloadedData: ServerStoredCommunityMetadata) => void) => {
callback(await this.downloadData(payload.cid))
}
)
this.on(
SocketActionTypes.UPLOAD_STORAGE_SERVER_DATA,
async (payload: { cid: string; data: ServerStoredCommunityMetadata }, callback: (cid: string) => void) => {
callback(await this.uploadData(payload.cid, payload.data))
}
)
}

setServerAddress = (serverAddress: string) => {
this.serverAddress = serverAddress
}

get authUrl() {
const authUrl = new URL('auth', this.serverAddress)
return authUrl.href
}

getInviteUrl = (cid: string) => {
const invitationUrl = new URL('invite', this.serverAddress)
invitationUrl.searchParams.append('CID', cid)
return invitationUrl.href
}

getAuthorizationHeader = (token: string) => {
return `Bearer ${token}`
}

auth = async () => {
console.log('Authenticating')
const authResponse = await fetch(this.authUrl, {
method: 'POST',
})
console.log('Auth response status', authResponse.status)
const authResponseData = await authResponse.json()
console.log('Auth response data', authResponseData)
return authResponseData['access_token']
}

public downloadData = async (cid: string): Promise<ServerStoredCommunityMetadata> => {
console.log('Downloading data', cid)
const accessToken = await this.auth()
const dataResponse = await fetch(this.getInviteUrl(cid), {
method: 'GET',
headers: { Authorization: this.getAuthorizationHeader(accessToken) },
})
const data = await dataResponse.json()
console.log('Downloaded data', data)
// this.emit('storageServerDataDownloaded', data)
return data
}

public uploadData = async (cid: string, data: ServerStoredCommunityMetadata) => {
console.log('Uploading data', cid, data)
const accessToken = await this.auth()
const putBody = JSON.stringify(data)
console.log('putBody', putBody)
const dataResponsePost = await fetch(this.getInviteUrl(cid), {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: this.getAuthorizationHeader(accessToken),
},
body: putBody,
})
console.log('Upload data response status', dataResponsePost)
// if (dataResponsePost.status === 200) {
// this.emit('storageServerDataUploaded', { cid })
// }
return cid
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type ServerStoredCommunityMetadata = {
id: string
ownerCertificate: string
rootCa: string
ownerOrbitDbIdentity: string
peerList: string[]
psk: string
}
6 changes: 6 additions & 0 deletions packages/types/src/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ export enum SocketActionTypes {
PEER_LIST = 'peerList',
TOR_INITIALIZED = 'torInitialized',

// ====== Storage server ======

SET_STORAGE_SERVER_ADDRESS = 'setStorageServerAddress',
DOWNLOAD_STORAGE_SERVER_DATA = 'downloadStorageServerData',
UPLOAD_STORAGE_SERVER_DATA = 'uploadStorageServerData',

// ====== Misc ======

PUSH_NOTIFICATION = 'pushNotification',
Expand Down

0 comments on commit 3c6796d

Please sign in to comment.