123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- /* global AUTH_CONFIG */
- import { browserName, locale } from './utils';
- async function checkCrypto() {
- try {
- const key = await crypto.subtle.generateKey(
- {
- name: 'AES-GCM',
- length: 128
- },
- true,
- ['encrypt', 'decrypt']
- );
- await crypto.subtle.exportKey('raw', key);
- await crypto.subtle.encrypt(
- {
- name: 'AES-GCM',
- iv: crypto.getRandomValues(new Uint8Array(12)),
- tagLength: 128
- },
- key,
- new ArrayBuffer(8)
- );
- await crypto.subtle.importKey(
- 'raw',
- crypto.getRandomValues(new Uint8Array(16)),
- 'PBKDF2',
- false,
- ['deriveKey']
- );
- await crypto.subtle.importKey(
- 'raw',
- crypto.getRandomValues(new Uint8Array(16)),
- 'HKDF',
- false,
- ['deriveKey']
- );
- await crypto.subtle.generateKey(
- {
- name: 'ECDH',
- namedCurve: 'P-256'
- },
- true,
- ['deriveBits']
- );
- return true;
- } catch (err) {
- try {
- window.asmCrypto = await import('asmcrypto.js');
- await import('@dannycoates/webcrypto-liner/build/shim');
- return true;
- } catch (e) {
- return false;
- }
- }
- }
- function checkStreams() {
- try {
- new ReadableStream({
- pull() {}
- });
- return true;
- } catch (e) {
- return false;
- }
- }
- async function polyfillStreams() {
- try {
- await import('@mattiasbuelens/web-streams-polyfill');
- return true;
- } catch (e) {
- return false;
- }
- }
- export default async function getCapabilities() {
- const browser = browserName();
- const isMobile = /mobi|android/i.test(navigator.userAgent);
- const serviceWorker = 'serviceWorker' in navigator && browser !== 'edge';
- let crypto = await checkCrypto();
- const nativeStreams = checkStreams();
- let polyStreams = false;
- if (!nativeStreams) {
- polyStreams = await polyfillStreams();
- }
- let account = typeof AUTH_CONFIG !== 'undefined';
- try {
- account = account && !!localStorage;
- } catch (e) {
- account = false;
- }
- const share =
- isMobile &&
- typeof navigator.share === 'function' &&
- locale().startsWith('en'); // en until strings merge
- const standalone =
- window.matchMedia('(display-mode: standalone)').matches ||
- navigator.standalone;
- const mobileFirefox = browser === 'firefox' && isMobile;
- return {
- account,
- crypto,
- serviceWorker,
- streamUpload: nativeStreams || polyStreams,
- streamDownload:
- nativeStreams && serviceWorker && browser !== 'safari' && !mobileFirefox,
- multifile: nativeStreams || polyStreams,
- share,
- standalone
- };
- }
|