Skip to content

Commit

Permalink
generate random secret
Browse files Browse the repository at this point in the history
  • Loading branch information
Kacper-RF committed Oct 11, 2023
1 parent 85f69b5 commit 7701605
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 26 deletions.
4 changes: 2 additions & 2 deletions packages/backend/src/backendManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ program
.option('-a, --appDataPath <string>', 'Path of application data directory')
.option('-d, --socketIOPort <number>', 'Socket io data server port')
.option('-r, --resourcesPath <string>', 'Application resources path')
.option('-tkn, --socketIOToken <string>', 'socketIO token')
.option('-scrt, --socketIOSecret <string>', 'socketIO secret')

program.parse(process.argv)
const options = program.opts()
Expand Down Expand Up @@ -53,7 +53,7 @@ export const runBackendDesktop = async () => {
const app = await NestFactory.createApplicationContext(
AppModule.forOptions({
socketIOPort: options.socketIOPort,
socketIOToken: options.socketIOToken,
socketIOSecret: options.socketIOSecret,
torBinaryPath: torBinForPlatform(resourcesPath),
torResourcesPath: torDirForPlatform(resourcesPath),
torControlPort: await getPort(),
Expand Down
14 changes: 9 additions & 5 deletions packages/backend/src/nest/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,26 +106,30 @@ export class AppModule {
const authToken = req.headers['authorization']
if (!authToken) {
console.error('No authorization header')

res.writeHead(401, 'Unauthorized')
res.writeHead(401, 'No authorization header')
res.end()
return
}

const socketIOToken = authToken && authToken.split(' ')[1]
if (!socketIOToken) {
console.error('No auth token')
res.writeHead(401, 'No authorization token')
res.end()
return
}

res.writeHead(401, 'Unauthorized')
if (!options.socketIOSecret) {
console.error('No socketIoSecret')
res.writeHead(401, 'No socketIoSecret')
res.end()
return
}

if (verifyJWT(socketIOToken)) {
if (verifyJWT(socketIOToken, options.socketIOSecret)) {
next()
} else {
console.error('Wrong JWT')

res.writeHead(401, 'Unauthorized')
res.end()
}
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/nest/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Server as SocketIO } from 'socket.io'
export class ConnectionsManagerTypes {
options: Partial<ConnectionsManagerOptions>
socketIOPort: number
socketIOToken?: string
socketIOSecret?: string
httpTunnelPort?: number
torAuthCookie?: string
torControlPort?: number
Expand Down
11 changes: 6 additions & 5 deletions packages/common/src/jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ interface JwtPayload {
appName: string
}

const SECRET = 'secret' //temporary
const APP_NAME = 'Quiet'

export const generateJWT = () => {
return sign({ appName: APP_NAME }, SECRET, { algorithm: 'HS256' })
export const generateSecret = () => Math.floor(Math.random() * 100 ** 10).toString()

export const generateJWT = (secret: string) => {
return sign({ appName: APP_NAME }, secret, { algorithm: 'HS256' })
}

export const verifyJWT = (token: string): boolean => {
const isVerify = verify(token, SECRET) as JwtPayload
export const verifyJWT = (token: string, secret: string): boolean => {
const isVerify = verify(token, secret) as JwtPayload
return isVerify.appName === APP_NAME ? true : false
}
10 changes: 5 additions & 5 deletions packages/desktop/src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Crypto } from '@peculiar/webcrypto'
import logger from './logger'
import { DATA_DIR, DEV_DATA_DIR } from '../shared/static'
import { fork, ChildProcess } from 'child_process'
import { generateJWT, getFilesData } from '@quiet/common'
import { generateJWT, generateSecret, getFilesData } from '@quiet/common'
import { updateDesktopFile, processInvitationCode } from './invitation'
import { argvInvitationCode, retrieveInvitationCode } from '@quiet/common'
const ElectronStore = require('electron-store')
Expand All @@ -30,7 +30,7 @@ const updaterInterval = 15 * 60_000
export const isDev = process.env.NODE_ENV === 'development'
export const isE2Etest = process.env.E2E_TEST === 'true'

const SOCKET_IO_TOKEN = generateJWT()
const SOCKET_IO_SECRET = generateSecret()

const webcrypto = new Crypto()

Expand Down Expand Up @@ -207,7 +207,7 @@ export const createWindow = async () => {
mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, './index.html'),
search: `dataPort=${ports.dataServer}&socketIOToken=${SOCKET_IO_TOKEN}`,
search: `dataPort=${ports.dataServer}&socketIOSecret=${SOCKET_IO_SECRET}`,
protocol: 'file:',
slashes: true,
hash: '/',
Expand Down Expand Up @@ -364,8 +364,8 @@ app.on('ready', async () => {
`${process.resourcesPath}`,
'-p',
'desktop',
'-tkn',
`${SOCKET_IO_TOKEN}`,
'-scrt',
`${SOCKET_IO_SECRET}`,
]

const backendBundlePath = path.normalize(require.resolve('backend-bundle'))
Expand Down
4 changes: 2 additions & 2 deletions packages/desktop/src/renderer/sagas/index.saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { socketActions } from './socket/socket.slice'

export default function* root(): Generator {
const dataPort = new URLSearchParams(window.location.search).get('dataPort') || ''
const socketIOToken = new URLSearchParams(window.location.search).get('socketIOToken') || ''
const socketIOSecret = new URLSearchParams(window.location.search).get('socketIOSecret') || ''
yield all([
takeEvery(communities.actions.handleInvitationCode.type, handleInvitationCodeSaga),
startConnectionSaga(
socketActions.startConnection({
dataPort: parseInt(dataPort),
socketIOToken,
socketIOSecret,
})
),
])
Expand Down
9 changes: 5 additions & 4 deletions packages/desktop/src/renderer/sagas/socket/socket.saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@ import { socket as stateManager, messages } from '@quiet/state-manager'
import { socketActions } from './socket.slice'
import { eventChannel } from 'redux-saga'
import { displayMessageNotificationSaga } from '../notifications/notifications.saga'

import logger from '../../logger'
import { generateJWT } from '@quiet/common'

const log = logger('socket')

export function* startConnectionSaga(
action: PayloadAction<ReturnType<typeof socketActions.startConnection>['payload']>
): Generator {
const { dataPort, socketIOToken } = action.payload
const { dataPort, socketIOSecret } = action.payload
if (!dataPort) {
log.error('About to start connection but no dataPort found')
}

const jwtToken = generateJWT(socketIOSecret)
const socket = yield* call(io, `http://127.0.0.1:${dataPort}`, {
withCredentials: true,
extraHeaders: {
authorization: `Bearer ${socketIOToken}`,
authorization: `Bearer ${jwtToken}`,
},
})
yield* fork(handleSocketLifecycleActions, socket)
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop/src/renderer/sagas/socket/socket.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class SocketState {

export interface WebsocketConnectionPayload {
dataPort: number
socketIOToken: string
socketIOSecret: string
}

export interface CloseConnectionPayload {
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop/src/renderer/testUtils/prepareStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,5 @@ function* mockSocketConnectionSaga(socket: MockedSocket): Generator {
socket.socketClient.emit('connect')
})
})
yield* put(socketActions.startConnection({ dataPort: 4677, socketIOToken: 'testToken' }))
yield* put(socketActions.startConnection({ dataPort: 4677, socketIOSecret: '010101010' }))
}

0 comments on commit 7701605

Please sign in to comment.