diff --git a/.eslintrc.yml b/.eslintrc.yml index c8b60c4c..400d29f3 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -5,21 +5,24 @@ env: extends: - eslint:recommended - prettier - - plugin:node/recommended + - plugin:n/recommended - plugin:security/recommended plugins: - - node + - n - security root: true rules: - node/no-deprecated-api: off - node/no-unsupported-features/es-syntax: off - node/no-unsupported-features/node-builtins: off - node/no-unpublished-require: off - node/no-unpublished-import: off + n/no-deprecated-api: off + n/no-unsupported-features/es-syntax: off + n/no-unsupported-features/node-builtins: off + n/no-unpublished-require: off + n/no-unpublished-import: off + n/no-process-exit: off + # This forces using file extensions in imports, which is a best practice, but refactoring would take some time + n/no-missing-import: off security/detect-non-literal-fs-filename: off security/detect-object-injection: off diff --git a/.stylelintrc b/.stylelintrc index 0af67b03..afc9e08d 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -11,3 +11,5 @@ rules: selector-list-comma-newline-after: null value-list-comma-newline-after: null at-rule-no-unknown: null + # Conflicts with prettier + string-quotes: null diff --git a/Dockerfile b/Dockerfile index 53220098..e9603e98 100644 --- a/Dockerfile +++ b/Dockerfile @@ -63,7 +63,6 @@ COPY --chown=app:app server server COPY --chown=app:app --from=builder /app/dist dist RUN npm ci --production && npm cache clean --force -RUN mkdir -p /app/.config/configstore RUN ln -s dist/version.json version.json ENV PORT=1443 diff --git a/app/.eslintrc.yml b/app/.eslintrc.yml index 677cec88..5f342427 100644 --- a/app/.eslintrc.yml +++ b/app/.eslintrc.yml @@ -6,4 +6,4 @@ parserOptions: sourceType: module rules: - node/no-unsupported-features: off + n/no-unsupported-features: off diff --git a/app/capabilities.js b/app/capabilities.js index d43a6b10..be76bceb 100644 --- a/app/capabilities.js +++ b/app/capabilities.js @@ -45,13 +45,7 @@ async function checkCrypto() { ); return true; } catch (err) { - try { - window.asmCrypto = await import('asmcrypto.js'); - await import('@dannycoates/webcrypto-liner/build/shim'); - return true; - } catch (e) { - return false; - } + return false; } } @@ -66,25 +60,12 @@ function checkStreams() { } } -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; @@ -106,10 +87,10 @@ export default async function getCapabilities() { account, crypto, serviceWorker, - streamUpload: nativeStreams || polyStreams, + streamUpload: nativeStreams, streamDownload: nativeStreams && serviceWorker && browser !== 'safari' && !mobileFirefox, - multifile: nativeStreams || polyStreams, + multifile: nativeStreams, share, standalone }; diff --git a/app/ece.js b/app/ece.js index 4cd6b45e..d9f40c86 100644 --- a/app/ece.js +++ b/app/ece.js @@ -48,7 +48,7 @@ class ECETransformer { name: 'AES-GCM', length: 128 }, - true, // Edge polyfill requires key to be extractable to encrypt :/ + false, ['encrypt', 'decrypt'] ); } diff --git a/app/locale.js b/app/locale.js index ff8925fb..23dfdb7c 100644 --- a/app/locale.js +++ b/app/locale.js @@ -1,8 +1,8 @@ -import { FluentBundle } from '@fluent/bundle'; +import { FluentBundle, FluentResource } from '@fluent/bundle'; function makeBundle(locale, ftl) { const bundle = new FluentBundle(locale, { useIsolating: false }); - bundle.addMessages(ftl); + bundle.addResource(new FluentResource(ftl)); return bundle; } @@ -19,7 +19,7 @@ export async function getTranslator(locale) { return function(id, data) { for (let bundle of bundles) { if (bundle.hasMessage(id)) { - return bundle.format(bundle.getMessage(id), data); + return bundle.formatPattern(bundle.getMessage(id).value, data); } } }; diff --git a/app/main.css b/app/main.css index d5306936..db3852fc 100644 --- a/app/main.css +++ b/app/main.css @@ -7,17 +7,14 @@ html { @tailwind components; :not(input) { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; user-select: none; } :root { --violet-gradient: linear-gradient( -180deg, - rgba(144, 89, 255, 0.8) 0%, - rgba(144, 89, 255, 0.4) 100% + rgb(144 89 255 / 80%) 0%, + rgb(144 89 255 / 40%) 100% ); } @@ -71,7 +68,7 @@ body { .checkbox > label::before { /* @apply bg-grey-10; */ - @apply border; + @apply border-default; @apply rounded-sm; content: ''; @@ -204,19 +201,18 @@ progress::-webkit-progress-value { background-image: -webkit-linear-gradient( -45deg, transparent 20%, - rgba(255, 255, 255, 0.4) 20%, - rgba(255, 255, 255, 0.4) 40%, + rgb(255 255 255 / 40%) 20%, + rgb(255 255 255 / 40%) 40%, transparent 40%, transparent 60%, - rgba(255, 255, 255, 0.4) 60%, - rgba(255, 255, 255, 0.4) 80%, + rgb(255 255 255 / 40%) 60%, + rgb(255 255 255 / 40%) 80%, transparent 80% ), -webkit-linear-gradient(left, var(--color-primary), var(--color-primary)); /* stylelint-enable */ border-radius: 2px; background-size: 21px 20px, 100% 100%, 100% 100%; - -webkit-animation: animate-stripes 1s linear infinite; } progress::-moz-progress-bar { @@ -224,12 +220,12 @@ progress::-moz-progress-bar { background-image: -moz-linear-gradient( 135deg, transparent 20%, - rgba(255, 255, 255, 0.4) 20%, - rgba(255, 255, 255, 0.4) 40%, + rgb(255 255 255 / 40%) 20%, + rgb(255 255 255 / 40%) 40%, transparent 40%, transparent 60%, - rgba(255, 255, 255, 0.4) 60%, - rgba(255, 255, 255, 0.4) 80%, + rgb(255 255 255 / 40%) 60%, + rgb(255 255 255 / 40%) 80%, transparent 80% ), -moz-linear-gradient(left, var(--color-primary), var(--color-primary)); @@ -239,12 +235,6 @@ progress::-moz-progress-bar { animation: animate-stripes 1s linear infinite; } -@-webkit-keyframes animate-stripes { - 100% { - background-position: -21px 0; - } -} - @keyframes animate-stripes { 100% { background-position: -21px 0; @@ -313,7 +303,7 @@ select { @screen md { .main > section { - @apply border; + @apply border-default; @apply border-grey-80; } } @@ -323,13 +313,12 @@ select { @responsive { .shadow-light { - box-shadow: 0 0 8px 0 rgba(12, 12, 13, 0.1); + box-shadow: 0 0 8px 0 rgb(12 12 13 / 10%); } .shadow-big { - box-shadow: 0 12px 18px 2px rgba(34, 0, 51, 0.04), - 0 6px 22px 4px rgba(7, 48, 114, 0.12), - 0 6px 10px -4px rgba(14, 13, 26, 0.12); + box-shadow: 0 12px 18px 2px rgb(34 0 51 / 4%), + 0 6px 22px 4px rgb(7 48 114 / 12%), 0 6px 10px -4px rgb(14 13 26 / 12%); } } diff --git a/app/main.js b/app/main.js index c6a89dce..9c5a3de9 100644 --- a/app/main.js +++ b/app/main.js @@ -1,6 +1,5 @@ /* global DEFAULTS LIMITS WEB_UI PREFS */ import 'core-js'; -import 'fast-text-encoding'; // MS Edge support import 'intl-pluralrules'; import choo from 'choo'; import nanotiming from 'nanotiming'; diff --git a/app/storage.js b/app/storage.js index 304759ea..59bef6f4 100644 --- a/app/storage.js +++ b/app/storage.js @@ -110,7 +110,7 @@ class Storage { } set user(info) { - return this.engine.setItem('user', JSON.stringify(info)); + this.engine.setItem('user', JSON.stringify(info)); } getFileById(id) { diff --git a/app/streams.js b/app/streams.js index 00159a24..0ee754a4 100644 --- a/app/streams.js +++ b/app/streams.js @@ -1,5 +1,3 @@ -/* global TransformStream */ - export function transformStream(readable, transformer, oncancel) { try { return readable.pipeThrough(new TransformStream(transformer)); diff --git a/app/ui/account.js b/app/ui/account.js index 7d200049..9845a3a1 100644 --- a/app/ui/account.js +++ b/app/ui/account.js @@ -83,13 +83,13 @@ class Account extends Component {