Device manager - parse user agent for device information (#9352)

* record device client inforamtion events on app start

* matrix-client-information -> matrix_client_information

* fix types

* remove another unused export

* add docs link

* display device client information in device details

* update snapshots

* integration-ish test client information in metadata

* tests

* fix tests

* export helper

* DeviceClientInformation type

* Device manager - select all devices (#9330)

* add device selection that does nothing

* multi select and sign out of sessions

* test multiple selection

* fix type after rebase

* select all sessions

* rename type

* use ExtendedDevice type everywhere

* rename clientName to appName for less collision with UA parser

* fix bad find and replace

* rename ExtendedDeviceInfo to ExtendedDeviceAppInfo

* rename DeviceType comp to DeviceTypeIcon

* update tests for new required property deviceType

* add stubbed user agent parsing

* setup test cases

* detect device type correctly

* 80% working ua parser

* parse asera gents for device info

* combine clientName/Version into one field, remove debug from tests
This commit is contained in:
Kerry 2022-10-06 10:06:29 +02:00 committed by GitHub
parent 191b0a1517
commit 3e4f3152bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 207 additions and 7 deletions

View file

@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import UAParser from 'ua-parser-js';
export enum DeviceType {
Desktop = 'Desktop',
Mobile = 'Mobile',
@ -26,20 +28,86 @@ export type ExtendedDeviceInformation = {
deviceModel?: string;
// eg Android 11
deviceOperatingSystem?: string;
// eg Firefox
clientName?: string;
// eg 1.1.0
clientVersion?: string;
// eg Firefox 1.1.0
client?: string;
};
// Element/1.8.21 (iPhone XS Max; iOS 15.2; Scale/3.00)
const IOS_KEYWORD = "; iOS ";
const BROWSER_KEYWORD = "Mozilla/";
const getDeviceType = (
userAgent: string,
device: UAParser.IDevice,
browser: UAParser.IBrowser,
operatingSystem: UAParser.IOS,
): DeviceType => {
if (browser.name === 'Electron') {
return DeviceType.Desktop;
}
if (!!browser.name) {
return DeviceType.Web;
}
if (
device.type === 'mobile' ||
operatingSystem.name?.includes('Android') ||
userAgent.indexOf(IOS_KEYWORD) > -1
) {
return DeviceType.Mobile;
}
return DeviceType.Unknown;
};
/**
* Some mobile model and OS strings are not recognised
* by the UA parsing library
* check they exist by hand
*/
const checkForCustomValues = (userAgent: string): {
customDeviceModel?: string;
customDeviceOS?: string;
} => {
if (userAgent.includes(BROWSER_KEYWORD)) {
return {};
}
const mightHaveDevice = userAgent.includes('(');
if (!mightHaveDevice) {
return {};
}
const deviceInfoSegments = userAgent.substring(userAgent.indexOf('(') + 1).split('; ');
const customDeviceModel = deviceInfoSegments[0] || undefined;
const customDeviceOS = deviceInfoSegments[1] || undefined;
return { customDeviceModel, customDeviceOS };
};
const concatenateNameAndVersion = (name?: string, version?: string): string | undefined =>
name && [name, version].filter(Boolean).join(' ');
export const parseUserAgent = (userAgent?: string): ExtendedDeviceInformation => {
if (!userAgent) {
return {
deviceType: DeviceType.Unknown,
};
}
// @TODO(kerrya) not yet implemented
const parser = new UAParser(userAgent);
const browser = parser.getBrowser();
const device = parser.getDevice();
const operatingSystem = parser.getOS();
const deviceOperatingSystem = concatenateNameAndVersion(operatingSystem.name, operatingSystem.version);
const deviceModel = concatenateNameAndVersion(device.vendor, device.model);
const client = concatenateNameAndVersion(browser.name, browser.major || browser.version);
const { customDeviceModel, customDeviceOS } = checkForCustomValues(userAgent);
const deviceType = getDeviceType(userAgent, device, browser, operatingSystem);
return {
deviceType: DeviceType.Unknown,
deviceType,
deviceModel: deviceModel || customDeviceModel,
deviceOperatingSystem: deviceOperatingSystem || customDeviceOS,
client,
};
};