diff --git a/tracker/tracker-assist/CHANGELOG.md b/tracker/tracker-assist/CHANGELOG.md index f61aad123..5df2617c9 100644 --- a/tracker/tracker-assist/CHANGELOG.md +++ b/tracker/tracker-assist/CHANGELOG.md @@ -1,3 +1,11 @@ +## 5.0.2 + +- Added `onCallDeny`, `onRemoteControlDeny` and `onRecordingDeny` callbacks to signal denial of user's consent to call/control/recording + +## 5.0.1 + +- dependency updates + ## 5.0.0 - fix recording state import diff --git a/tracker/tracker-assist/package.json b/tracker/tracker-assist/package.json index 4c8c98d53..1bda6b785 100644 --- a/tracker/tracker-assist/package.json +++ b/tracker/tracker-assist/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker-assist", "description": "Tracker plugin for screen assistance through the WebRTC", - "version": "5.0.1", + "version": "5.0.2", "keywords": [ "WebRTC", "assistance", diff --git a/tracker/tracker-assist/src/Assist.ts b/tracker/tracker-assist/src/Assist.ts index 8d14740a5..f31f85c22 100644 --- a/tracker/tracker-assist/src/Assist.ts +++ b/tracker/tracker-assist/src/Assist.ts @@ -25,6 +25,9 @@ export interface Options { onCallStart: StartEndCallback; onRemoteControlStart: StartEndCallback; onRecordingRequest?: (agentInfo: Record) => any; + onCallDeny?: () => any; + onRemoteControlDeny?: (agentInfo: Record) => any; + onRecordingDeny?: (agentInfo: Record) => any; session_calling_peer_key: string; session_control_peer_key: string; callConfirm: ConfirmOptions; @@ -46,7 +49,7 @@ enum CallingState { Requesting, True, False, -}; +} // TODO typing???? @@ -84,7 +87,7 @@ export default class Assist { onAgentConnect: ()=>{}, onRemoteControlStart: ()=>{}, callConfirm: {}, - controlConfirm: {}, // TODO: clear options passing/merging/overriting + controlConfirm: {}, // TODO: clear options passing/merging/overwriting recordingConfirm: {}, }, options, @@ -194,7 +197,7 @@ export default class Assist { annot.mount() return callingAgents.get(id) }, - id => { + (id, isDenied) => { if (id) { const cb = this.agents[id].onControlReleased delete this.agents[id].onControlReleased @@ -210,14 +213,20 @@ export default class Assist { callUI?.remove() callUI = null } + if (isDenied) { + const info = id ? this.agents[id]?.agentInfo : {} + this.options.onRemoteControlDeny?.(info || {}) + } }, ) const onAcceptRecording = () => { socket.emit('recording_accepted') } - const onRejectRecording = () => { + const onRejectRecording = (agentData) => { socket.emit('recording_rejected') + + this.options.onRecordingDeny?.(agentData || {}) } const recordingState = new ScreenRecordingState(this.options.recordingConfirm) @@ -296,7 +305,7 @@ export default class Assist { socket.on('request_recording', (id, agentData) => { if (!recordingState.isActive) { this.options.onRecordingRequest?.(JSON.parse(agentData)) - recordingState.requestRecording(id, onAcceptRecording, onRejectRecording) + recordingState.requestRecording(id, onAcceptRecording, () => onRejectRecording(agentData)) } else { this.emit('recording_busy') } @@ -365,7 +374,7 @@ export default class Assist { }) } - const handleCallEnd = () => { // Completle stop and clear all calls + const handleCallEnd = () => { // Complete stop and clear all calls // Streams Object.values(calls).forEach(call => call.close()) Object.keys(calls).forEach(peerId => { @@ -417,6 +426,7 @@ export default class Assist { confirmAnswer.then(async agreed => { if (!agreed) { initiateCallEnd() + this.options.onCallDeny?.() return } // Request local stream for the new connection @@ -428,7 +438,7 @@ export default class Assist { } calls[call.peer] = call } catch (e) { - app.debug.error('Audio mediadevice request error:', e) + app.debug.error('Audio media device request error:', e) initiateCallEnd() return } diff --git a/tracker/tracker-assist/src/RemoteControl.ts b/tracker/tracker-assist/src/RemoteControl.ts index 017918238..c56ed3222 100644 --- a/tracker/tracker-assist/src/RemoteControl.ts +++ b/tracker/tracker-assist/src/RemoteControl.ts @@ -25,7 +25,7 @@ export default class RemoteControl { constructor( private readonly options: AssistOptions, private readonly onGrand: (id: string) => string | undefined, - private readonly onRelease: (id?: string | null) => void) {} + private readonly onRelease: (id?: string | null, isDenied?: boolean) => void) {} reconnect(ids: string[]) { const storedID = sessionStorage.getItem(this.options.session_control_peer_key) @@ -55,7 +55,7 @@ export default class RemoteControl { this.grantControl(id) } else { this.confirm?.remove() - this.releaseControl() + this.releaseControl(true) } }) .then(() => { @@ -67,7 +67,7 @@ export default class RemoteControl { }) } - releaseControl = () => { + releaseControl = (isDenied?: boolean) => { if (this.confirm) { this.confirm.remove() this.confirm = null @@ -75,7 +75,7 @@ export default class RemoteControl { this.resetMouse() this.status = RCStatus.Disabled sessionStorage.removeItem(this.options.session_control_peer_key) - this.onRelease(this.agentID) + this.onRelease(this.agentID, isDenied) this.agentID = null } diff --git a/tracker/tracker-assist/src/ScreenRecordingState.ts b/tracker/tracker-assist/src/ScreenRecordingState.ts index a962e85ac..87464f18a 100644 --- a/tracker/tracker-assist/src/ScreenRecordingState.ts +++ b/tracker/tracker-assist/src/ScreenRecordingState.ts @@ -109,6 +109,6 @@ export default class ScreenRecordingState { this.status = RecordingState.Off this.overlayAdded = false - this.uiComponents.forEach((el) => el.parentElement?.removeChild(el)) + this.uiComponents?.forEach((el) => el.parentElement?.removeChild(el)) } }