refactor(SDK): generate unique names for device info

Signed-off-by: Fernando Fernández <ferferga@hotmail.com>
This commit is contained in:
Fernando Fernández
2024-05-19 14:24:46 +02:00
parent bef453c96b
commit a1f4e221d4
5 changed files with 48 additions and 55 deletions
+1
View File
@@ -40,6 +40,7 @@
"radix-vue": "1.7.4",
"sortablejs": "1.15.2",
"swiper": "11.1.1",
"unique-names-generator": "4.7.1",
"uuid": "9.0.1",
"vue": "3.4.27",
"vue-i18n": "9.13.1",
+4
View File
@@ -33,6 +33,10 @@
{{ clientVersion }}
</td>
</tr>
<tr>
<td>{{ $t('deviceName') }}</td>
<td>{{ remote.sdk.deviceInfo.name }}</td>
</tr>
</tbody>
</VTable>
</div>
+34 -54
View File
@@ -1,75 +1,55 @@
/**
* We generate an unique name for this device instead of guessing the user's browser based on the user agent:
* - Browser user agent can be spoofed and is not reliable.
* - There's a major push to deprecate it: https://developers.google.com/privacy-sandbox/blog/user-agent-reduction-deprecation-trial?hl=es-419
* - Browsers are so ubiquitous that there are multiple form factors and devices that can run them. We can't easily track
* which device the user is using, so the best thing is to not rely on any platform-specific support and provide generic support
* for everything, using browser APIs like MediaCapabilities for playback capability detection.
*/
import { type Api, Jellyfin } from '@jellyfin/sdk';
import { v4 } from 'uuid';
import {
isAndroid,
isApple,
isChrome,
isChromiumBased,
isEdge,
isFirefox,
isMobile,
isTizen,
isWebOS
} from '@/utils/browser-detection';
import { version } from '@/../package.json';
import { adjectives, animals, colors, countries, languages, names, starWars, uniqueNamesGenerator } from 'unique-names-generator';
import { destr } from 'destr';
interface DeviceInfo {
id: string;
name: string;
}
/**
* Returns the device ID, creating it in case it does not exist
* Returns the device ID and name, creating it in case it does not exist
*/
function ensureDeviceId(): string {
const storageKey = 'deviceId';
const val = window.localStorage.getItem(storageKey);
function ensureDeviceInfo(): DeviceInfo {
const storageKey = 'device';
const storeData = destr<DeviceInfo | null>(window.localStorage.getItem(storageKey));
if (!storeData) {
const payload = {
id: v4(),
name: uniqueNamesGenerator({
dictionaries: [adjectives, animals, colors, countries, names, languages, starWars],
separator: '-',
length: 3
})
};
if (!val) {
const id = v4();
window.localStorage.setItem(storageKey, JSON.stringify(payload));
window.localStorage.setItem(storageKey, id);
return id;
return payload;
}
return val;
return storeData;
}
const SDK = new Jellyfin({
clientInfo: {
name: 'Jellyfin Web (Vue)',
name: 'Jellyfin Vue',
version: version
},
deviceInfo: {
name: getDeviceName(),
id: ensureDeviceId()
}
deviceInfo: ensureDeviceInfo()
});
/**
* Gets the device's name based on the browser's user agent.
*/
function getDeviceName(): string {
let deviceName = 'Unknown';
if (isChrome()) {
deviceName = 'Chrome';
} else if (isEdge() && !isChromiumBased()) {
deviceName = 'Edge (EdgeHTML)';
} else if (isEdge()) {
deviceName = 'Edge (Chromium)';
} else if (isFirefox()) {
deviceName = 'Firefox';
} else if (isApple() && !isMobile()) {
deviceName = 'Safari';
} else if (isWebOS()) {
deviceName = 'LG Smart TV';
} else if (isTizen()) {
deviceName = 'Samsung Smart TV';
} else if (isApple() && isMobile()) {
deviceName = 'iPhone';
} else if (isAndroid()) {
deviceName = 'Android';
}
return deviceName;
}
/**
* Connects to the given server with the given credentials without
* altering the app's API/SDK or axios instance.
-1
View File
@@ -31,7 +31,6 @@ import { remote } from '@/plugins/remote';
import { apiStore } from '@/store/api';
import { getImageInfo } from '@/utils/images';
import { getItemRuntime } from '@/utils/items';
import playbackProfile from '@/utils/playback-profiles';
import { msToTicks } from '@/utils/time';
import { mediaControls, mediaElementRef } from '@/store';
import { CommonStore } from '@/store/super/common-store';
+9
View File
@@ -40,6 +40,7 @@
"radix-vue": "1.7.4",
"sortablejs": "1.15.2",
"swiper": "11.1.1",
"unique-names-generator": "4.7.1",
"uuid": "9.0.1",
"vue": "3.4.27",
"vue-i18n": "9.13.1",
@@ -10399,6 +10400,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/unique-names-generator": {
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz",
"integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==",
"engines": {
"node": ">=8"
}
},
"node_modules/universalify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",