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:
parent
191b0a1517
commit
3e4f3152bc
4 changed files with 207 additions and 7 deletions
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue