diff --git a/src/client/index.ts b/src/client/index.ts index d7c9333cd..b6062bc20 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -47,6 +47,15 @@ client.add('/calls/set-channel', async (data: { channel: number }) => { PhoneService.setChannel(data.channel); }); +RegisterCommand( + 'select-device', + async (_: unknown, args: string[]) => { + const deviceId = parseInt(args[0], 10); + client.post('/select-device', { deviceId }); + }, + false, +); + /** Server listener */ onNet(BROADCAST_EVENT_LISTENER, (data: { data: unknown; event: string }) => { global.SendNUIMessage({ type: NUI_BROADCAST_EVENT, payload: data }); diff --git a/src/server/index.ts b/src/server/index.ts index 9a070a439..2d2546568 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -17,6 +17,7 @@ import { emitMiddleware } from './middlewares/emitMiddleware'; import { messagesRouter } from './router/messages'; import { conversationsRouter } from './router/conversations'; import { contactsRouter } from './router/contacts'; +import { selectDeviceMiddleware } from './middlewares/selectDeviceMiddleware'; function bootstrap() { initDB(); @@ -34,6 +35,7 @@ function bootstrap() { app.use(emitMiddleware); app.use(sourceMiddleware); + app.use(selectDeviceMiddleware); app.use(deviceMiddleware); app.use(parseBodyMiddleware); diff --git a/src/server/middlewares/deviceMiddleware.ts b/src/server/middlewares/deviceMiddleware.ts index 5f36f2549..1c0cb468f 100644 --- a/src/server/middlewares/deviceMiddleware.ts +++ b/src/server/middlewares/deviceMiddleware.ts @@ -2,6 +2,9 @@ import { RouterContext } from 'fivem-router'; import z from 'zod'; import { DeviceWithSimCard } from '../../shared/Types'; import DeviceRepository from '../repositories/DeviceRepository'; +import PlayerService from '../services/PlayerService'; +import { handleError } from '../utils/errors'; +import { DeviceNotFoundError } from '../../shared/Errors'; declare module 'fivem-router' { interface RouterContext { @@ -48,26 +51,15 @@ try { } export const deviceMiddleware = async (ctx: RouterContext, next: () => Promise) => { - const { data: headerDeviceId } = z.coerce - .number() - .safeParse(ctx.request?.headers?.['x-device-id']); - - let deviceIdentifier = !headerDeviceId ? getDeviceIdentifierBySource(ctx.source) : ''; - - if (!deviceIdentifier && !headerDeviceId) { - ctx.throw(401, 'Device ID not found. Are you calling this from the server?'); - return next(); - } + const deviceIdentifier = PlayerService.getDevice(ctx.source); try { - let device; - - if (headerDeviceId) { - device = await DeviceRepository.getDeviceById(headerDeviceId); - } else { - device = await DeviceRepository.getDeviceByIdentifier(deviceIdentifier); + if (!deviceIdentifier) { + throw new DeviceNotFoundError('CALLER'); } + const device = await DeviceRepository.getDeviceByIdentifier(deviceIdentifier); + if (!device && ctx.url === '/devices/register') { console.log('Device not found, registering new device'); await next(); @@ -75,14 +67,13 @@ export const deviceMiddleware = async (ctx: RouterContext, next: () => Promise Promise) => { + if (ctx.url !== '/select-device') { + return next(); + } + + try { + const { deviceIdentifier } = selectDeviceSchema.parse(ctx.request.body); + await PlayerService.selectDevice(ctx.source, deviceIdentifier); + ctx.status = 200; + ctx.body = { + ok: true, + message: `Device selected: ${deviceIdentifier}`, + }; + } catch (error) { + handleError(error, ctx); + } +}; diff --git a/src/server/router/conversations.ts b/src/server/router/conversations.ts index f113a3de5..5fd444ac6 100644 --- a/src/server/router/conversations.ts +++ b/src/server/router/conversations.ts @@ -26,7 +26,6 @@ conversationsRouter.add('/:phoneNumber', async (ctx, next) => { const { phoneNumber } = z.object({ phoneNumber: z.string().min(2).max(15) }).parse(ctx.params); const messages = await ConversationService.getConversation(ctx, phoneNumber); - console.log(messages); ctx.body = { ok: true, diff --git a/src/server/services/ConversationService.ts b/src/server/services/ConversationService.ts index 3740e2097..be3aa377d 100644 --- a/src/server/services/ConversationService.ts +++ b/src/server/services/ConversationService.ts @@ -36,16 +36,6 @@ class ConversationService { } async getConversation(ctx: RouterContext, phoneNumber: string) { - const device = await this.deviceRepository.getDeviceById(ctx.device.id); - - if (!device) { - throw new SimcardNotFoundError('SENDER'); - } - - if (!device.sim_card_id) { - throw new SimcardNotFoundError('SENDER'); - } - const receiverSimcard = await this.simCardRepository.getSimCardByPhoneNumber(phoneNumber); if (!receiverSimcard) { @@ -56,7 +46,7 @@ class ConversationService { throw new SimCardNotActiveError('RECEIVER'); } - return await this.messageRepository.getConversation(device.sim_card_id, receiverSimcard.id); + return await this.messageRepository.getConversation(ctx.device.sim_card_id, receiverSimcard.id); } } diff --git a/src/server/services/PlayerService.ts b/src/server/services/PlayerService.ts new file mode 100644 index 000000000..992cbfa74 --- /dev/null +++ b/src/server/services/PlayerService.ts @@ -0,0 +1,26 @@ +class PlayerService { + deviceMap: Map = new Map(); + constructor() {} + + public authorizeDevice(src: number, deviceIdentifier: string) { + return true; + } + + public async selectDevice(src: number, deviceIdentifier: string) { + if (!this.authorizeDevice(src, deviceIdentifier)) { + throw new Error('Unauthorized'); + } + + this.deviceMap.set(src, deviceIdentifier); + } + + public getDevice(src: number) { + return this.deviceMap.get(src); + } + + public async getDevices() { + return Array.from(this.deviceMap.values()); + } +} + +export default new PlayerService(); diff --git a/src/shared/Errors.ts b/src/shared/Errors.ts index d79c8d007..e0d98453f 100644 --- a/src/shared/Errors.ts +++ b/src/shared/Errors.ts @@ -71,6 +71,15 @@ export class DeviceNotFoundError extends BaseError { } } +export class DeviceIdentifierNotFound extends BaseError { + code = 404; + error_code = 'DEVICE_IDENTIFIER_NOT_FOUND' as const; + + constructor() { + super(`Device identifier was not found`); + } +} + export class MessageNotFoundError extends BaseError { code = 404; error_code = 'MESSAGE_NOT_FOUND' as const;