diff --git a/client/pages/config/sessions.vue b/client/pages/config/sessions.vue index 86ec7eec6..4341ea07d 100644 --- a/client/pages/config/sessions.vue +++ b/client/pages/config/sessions.vue @@ -66,7 +66,11 @@

{{ getPlayMethodName(session.playMethod) }}

-

+

+ +

{{ $elapsedPrettyLocalized(session.timeListening) }}

@@ -130,7 +134,11 @@

{{ getPlayMethodName(session.playMethod) }}

-

+

+ +

{{ $elapsedPretty(session.timeListening) }}

@@ -172,7 +180,11 @@

{{ getPlayMethodName(session.playMethod) }}

-

+

+ +

{{ $secondsToTimestamp(session.currentTime) }}

@@ -433,16 +445,16 @@ export default { this.selectedSession = session this.showSessionModal = true }, - getDeviceInfoString(deviceInfo) { - if (!deviceInfo) return '' - var lines = [] + getDeviceInfoLines(deviceInfo) { + if (!deviceInfo) return [] + const lines = [] if (deviceInfo.clientName) lines.push(`${deviceInfo.clientName} ${deviceInfo.clientVersion || ''}`) if (deviceInfo.osName) lines.push(`${deviceInfo.osName} ${deviceInfo.osVersion}`) if (deviceInfo.browserName) lines.push(deviceInfo.browserName) if (deviceInfo.manufacturer && deviceInfo.model) lines.push(`${deviceInfo.manufacturer} ${deviceInfo.model}`) if (deviceInfo.sdkVersion) lines.push(`SDK Version: ${deviceInfo.sdkVersion}`) - return lines.join('
') + return lines }, getPlayMethodName(playMethod) { if (playMethod === this.$constants.PlayMethod.DIRECTPLAY) return 'Direct Play' diff --git a/client/pages/config/users/_id/sessions.vue b/client/pages/config/users/_id/sessions.vue index 060f34be8..cb18f5ee3 100644 --- a/client/pages/config/users/_id/sessions.vue +++ b/client/pages/config/users/_id/sessions.vue @@ -38,8 +38,12 @@

{{ getPlayMethodName(session.playMethod) }}

-

- +

+ +

+

{{ $elapsedPrettyLocalized(session.timeListening) }}

@@ -193,16 +197,16 @@ export default { this.selectedSession = session this.showSessionModal = true }, - getDeviceInfoString(deviceInfo) { - if (!deviceInfo) return '' - var lines = [] + getDeviceInfoLines(deviceInfo) { + if (!deviceInfo) return [] + const lines = [] if (deviceInfo.clientName) lines.push(`${deviceInfo.clientName} ${deviceInfo.clientVersion || ''}`) if (deviceInfo.osName) lines.push(`${deviceInfo.osName} ${deviceInfo.osVersion}`) if (deviceInfo.browserName) lines.push(deviceInfo.browserName) if (deviceInfo.manufacturer && deviceInfo.model) lines.push(`${deviceInfo.manufacturer} ${deviceInfo.model}`) if (deviceInfo.sdkVersion) lines.push(`SDK Version: ${deviceInfo.sdkVersion}`) - return lines.join('
') + return lines }, getPlayMethodName(playMethod) { if (playMethod === this.$constants.PlayMethod.DIRECTPLAY) return 'Direct Play' diff --git a/server/objects/DeviceInfo.js b/server/objects/DeviceInfo.js index ceff6c32e..22ebfbea4 100644 --- a/server/objects/DeviceInfo.js +++ b/server/objects/DeviceInfo.js @@ -1,6 +1,10 @@ -const uuidv4 = require("uuid").v4 +const uuidv4 = require('uuid').v4 +const { stripAllTags } = require('../utils/htmlSanitizer') class DeviceInfo { + /** @type {string[]} Fields to sanitize when loading from stored data */ + static stringFields = ['deviceId', 'clientVersion', 'manufacturer', 'model', 'sdkVersion', 'clientName', 'deviceName'] + constructor(deviceInfo = null) { this.id = null this.userId = null @@ -31,7 +35,7 @@ class DeviceInfo { construct(deviceInfo) { for (const key in deviceInfo) { if (deviceInfo[key] !== undefined && this[key] !== undefined) { - this[key] = deviceInfo[key] + this[key] = DeviceInfo.stringFields.includes(key) ? stripAllTags(deviceInfo[key]) : deviceInfo[key] } } } @@ -63,7 +67,8 @@ class DeviceInfo { } get deviceDescription() { - if (this.model) { // Set from mobile apps + if (this.model) { + // Set from mobile apps if (this.sdkVersion) return `${this.model} SDK ${this.sdkVersion} / v${this.clientVersion}` return `${this.model} / v${this.clientVersion}` } @@ -72,18 +77,7 @@ class DeviceInfo { // When client doesn't send a device id getTempDeviceId() { - const keys = [ - this.userId, - this.browserName, - this.browserVersion, - this.osName, - this.osVersion, - this.clientVersion, - this.manufacturer, - this.model, - this.sdkVersion, - this.ipAddress - ].map(k => k || '') + const keys = [this.userId, this.browserName, this.browserVersion, this.osName, this.osVersion, this.clientVersion, this.manufacturer, this.model, this.sdkVersion, this.ipAddress].map((k) => k || '') return 'temp-' + Buffer.from(keys.join('-'), 'utf-8').toString('base64') } @@ -99,12 +93,12 @@ class DeviceInfo { this.osVersion = ua?.os.version || null this.deviceType = ua?.device.type || null - this.clientVersion = clientDeviceInfo?.clientVersion || serverVersion - this.manufacturer = clientDeviceInfo?.manufacturer || null - this.model = clientDeviceInfo?.model || null - this.sdkVersion = clientDeviceInfo?.sdkVersion || null + this.clientVersion = stripAllTags(clientDeviceInfo?.clientVersion) || serverVersion + this.manufacturer = stripAllTags(clientDeviceInfo?.manufacturer) || null + this.model = stripAllTags(clientDeviceInfo?.model) || null + this.sdkVersion = stripAllTags(clientDeviceInfo?.sdkVersion) || null - this.clientName = clientDeviceInfo?.clientName || null + this.clientName = stripAllTags(clientDeviceInfo?.clientName) || null if (this.sdkVersion) { if (!this.clientName) this.clientName = 'Abs Android' this.deviceName = `${this.manufacturer || 'Unknown'} ${this.model || ''}` @@ -149,4 +143,4 @@ class DeviceInfo { return hasUpdates } } -module.exports = DeviceInfo \ No newline at end of file +module.exports = DeviceInfo diff --git a/server/utils/htmlSanitizer.js b/server/utils/htmlSanitizer.js index 4ed30e727..dbac1e5e0 100644 --- a/server/utils/htmlSanitizer.js +++ b/server/utils/htmlSanitizer.js @@ -27,6 +27,8 @@ function sanitize(html) { module.exports.sanitize = sanitize function stripAllTags(html, shouldDecodeEntities = true) { + if (typeof html !== 'string') return '' + const sanitizerOptions = { allowedTags: [], disallowedTagsMode: 'discard'