mirror of
https://github.com/rilaxik/fivem-rpc.git
synced 2026-09-29 01:30:42 +00:00
fix(rpc): prevent client id spoofing
This commit is contained in:
+38
-6
@@ -4,13 +4,14 @@ import {
|
||||
notRegisteredMessage,
|
||||
RPCError,
|
||||
} from '../utils/errors'
|
||||
import { generateUUID } from '../utils/funcs'
|
||||
import { generateUUID, isRPCState, parse } from '../utils/funcs'
|
||||
import { Pending } from '../utils/pending'
|
||||
import {
|
||||
type RPCConfig,
|
||||
type RPCEnvironment,
|
||||
RPCErrors,
|
||||
type RPCState,
|
||||
type RPCStateRaw,
|
||||
} from '../utils/types'
|
||||
|
||||
export class RPCInstanceBase {
|
||||
@@ -36,7 +37,7 @@ export class RPCInstanceBase {
|
||||
emitter.on(event, cb)
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/** Unregisters `cb` for `event` on `emitter`; `method` is only for logs */
|
||||
protected unlisten(emitter: Emitter, method: string, event: string): this {
|
||||
this.log(`${method} ${event}`)
|
||||
@@ -76,15 +77,46 @@ export class RPCInstanceBase {
|
||||
return this._emitterLocal.emit<R>(event, ...args)
|
||||
}
|
||||
|
||||
/** Settles the call waiting for `response`; ignores late or unexpected ones */
|
||||
protected settle(response: RPCState): void {
|
||||
/**
|
||||
* Settles the call waiting for `response`; ignores late or unexpected ones.
|
||||
*
|
||||
* @param peer - who sent the response (server: `source`)
|
||||
*/
|
||||
protected settle(response: RPCState, peer?: number): void {
|
||||
const found = response.error
|
||||
? this._pending.reject(response.uuid, RPCError.fromResponse(response))
|
||||
: this._pending.resolve(response.uuid, response.data?.[0])
|
||||
? this._pending.reject(
|
||||
response.uuid,
|
||||
RPCError.fromResponse(response),
|
||||
peer,
|
||||
)
|
||||
: this._pending.resolve(response.uuid, response.data?.[0], peer)
|
||||
|
||||
if (!found) this.logIgnored(response)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and validates an incoming payload. Anything else sent on the RPC
|
||||
* channels (broken JSON, other shapes) is dropped: `null`.
|
||||
*/
|
||||
protected accept(input: RPCStateRaw | unknown): RPCState | null {
|
||||
const payload =
|
||||
typeof input === 'string'
|
||||
? parse(input as RPCStateRaw)
|
||||
: isRPCState(input)
|
||||
? input
|
||||
: null
|
||||
|
||||
if (!payload) {
|
||||
this.log(`dropped invalid payload ${String(input).slice(0, 200)}`)
|
||||
return null
|
||||
}
|
||||
|
||||
this.log(
|
||||
`accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`,
|
||||
)
|
||||
return payload
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the listener for `request` and builds the response to send back.
|
||||
* Never throws: a missing listener or a thrown error ends up in `error`.
|
||||
|
||||
Reference in New Issue
Block a user