Compare commits
51 Commits
revert-101
...
master
Author | SHA1 | Date |
---|---|---|
Tim Visée | 6ad2885a16 | |
Aron Tecsi | 70662888b1 | |
timvisee | 9f09a79986 | |
Emil Stahl | db64c0467a | |
Tim Visée | ca52f84aa5 | |
timvisee | 6fff664947 | |
timvisee | 439ac0ab7c | |
timvisee | dee6b3e9cc | |
Teal Dulcet | dc9d072472 | |
simepy | 91773832c1 | |
timvisee | 65730db0db | |
timvisee | a86221b1cc | |
dependabot[bot] | bcc53f73c6 | |
dependabot[bot] | b0444f488b | |
Tim Visée | 70a11e5300 | |
Jun Omae | f62a99882d | |
timvisee | 309c7d63ac | |
dependabot[bot] | 1d75366f66 | |
timvisee | 0a849fb7c6 | |
dependabot[bot] | 88725df09d | |
dependabot[bot] | 5a92e7e5e7 | |
dependabot[bot] | 71541fc2b6 | |
Simon PERA | c524804c63 | |
timvisee | 5b4c0d2540 | |
Josh | e7f3c91d0b | |
Josh | 8bb198b73e | |
Tim Visée | 9e188bc76c | |
Marian Hähnlein | 1353a54c49 | |
Tim Visée | 4ae007167d | |
Marian Hähnlein | 660f36e584 | |
timvisee | 3dede083cd | |
timvisee | 26e81455ff | |
timvisee | 4ceac20623 | |
timvisee | 073accfe65 | |
timvisee | 6306a433e8 | |
timvisee | 1da317bcc1 | |
timvisee | 08f597405c | |
timvisee | c624766edc | |
Tim Visée | e030c46a9c | |
Marian Hähnlein | d081affa38 | |
Marian Hähnlein | 71372fcbc1 | |
HrBingR | 671390ca24 | |
HrBingR | 9221b86660 | |
HrBingR | fd2e954b3e | |
timvisee | c528ad3147 | |
HrBingR | df9c7ea734 | |
HrBingR | e32ea7d0aa | |
timvisee | 55ad08fd96 | |
timvisee | 96d53e4118 | |
HrBingR | bce861bcaf | |
HrBingR | 310271c10f |
|
@ -5,24 +5,21 @@ env:
|
||||||
extends:
|
extends:
|
||||||
- eslint:recommended
|
- eslint:recommended
|
||||||
- prettier
|
- prettier
|
||||||
- plugin:n/recommended
|
- plugin:node/recommended
|
||||||
- plugin:security/recommended
|
- plugin:security/recommended
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- n
|
- node
|
||||||
- security
|
- security
|
||||||
|
|
||||||
root: true
|
root: true
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
n/no-deprecated-api: off
|
node/no-deprecated-api: off
|
||||||
n/no-unsupported-features/es-syntax: off
|
node/no-unsupported-features/es-syntax: off
|
||||||
n/no-unsupported-features/node-builtins: off
|
node/no-unsupported-features/node-builtins: off
|
||||||
n/no-unpublished-require: off
|
node/no-unpublished-require: off
|
||||||
n/no-unpublished-import: off
|
node/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-non-literal-fs-filename: off
|
||||||
security/detect-object-injection: off
|
security/detect-object-injection: off
|
||||||
|
|
137
.gitlab-ci.yml
137
.gitlab-ci.yml
|
@ -1,105 +1,72 @@
|
||||||
image: "node:15-slim"
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- test
|
- test
|
||||||
- artifact
|
|
||||||
- release
|
- release
|
||||||
|
|
||||||
before_script:
|
|
||||||
# Install dependencies
|
|
||||||
- apt-get update
|
|
||||||
- apt-get install -y git python3 build-essential libxtst6
|
|
||||||
|
|
||||||
# Prepare Chrome for puppeteer
|
|
||||||
- apt-get install -y wget gnupg
|
|
||||||
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
|
|
||||||
- sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
|
|
||||||
- apt-get update
|
|
||||||
- apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 --no-install-recommends
|
|
||||||
|
|
||||||
# Build Send, run npm tests
|
# Build Send, run npm tests
|
||||||
test:
|
test:
|
||||||
stage: test
|
stage: test
|
||||||
|
image: "node:16-slim"
|
||||||
|
only:
|
||||||
|
- api
|
||||||
|
- branches
|
||||||
|
- chat
|
||||||
|
- merge_requests
|
||||||
|
- pushes
|
||||||
|
- schedules
|
||||||
|
- tags
|
||||||
|
- triggers
|
||||||
|
- web
|
||||||
|
before_script:
|
||||||
|
# Install dependencies
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y git python3 build-essential libxtst6
|
||||||
|
|
||||||
|
# Prepare Chrome for puppeteer
|
||||||
|
- apt-get install -y wget gnupg
|
||||||
|
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
|
||||||
|
- sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils
|
||||||
|
- apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 --no-install-recommends
|
||||||
script:
|
script:
|
||||||
- npm ci
|
- npm ci
|
||||||
- npm run lint
|
- npm run lint
|
||||||
- npm test
|
- npm test
|
||||||
|
|
||||||
# Build Docker image, export Docker image artifact
|
|
||||||
artifact-docker:
|
|
||||||
stage: artifact
|
|
||||||
image: docker:latest
|
|
||||||
needs: []
|
|
||||||
services:
|
|
||||||
- docker:dind
|
|
||||||
variables:
|
|
||||||
IMG_FILE: "send:git-$CI_COMMIT_SHORT_SHA.tar"
|
|
||||||
IMG_NAME: "send:git-$CI_COMMIT_SHORT_SHA"
|
|
||||||
before_script: []
|
|
||||||
script:
|
|
||||||
- docker build -t $IMG_NAME .
|
|
||||||
- docker image save -o $IMG_FILE $IMG_NAME
|
|
||||||
artifacts:
|
|
||||||
name: artifact-docker
|
|
||||||
paths:
|
|
||||||
- $IMG_FILE
|
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
# Release public Docker image for the master branch
|
|
||||||
release-docker-master:
|
|
||||||
stage: release
|
|
||||||
image: docker:latest
|
|
||||||
dependencies:
|
|
||||||
- artifact-docker
|
|
||||||
services:
|
|
||||||
- docker:dind
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
variables:
|
|
||||||
IMG_IMPORT_FILE: "send:git-$CI_COMMIT_SHORT_SHA.tar"
|
|
||||||
IMG_IMPORT_NAME: "send:git-$CI_COMMIT_SHORT_SHA"
|
|
||||||
IMG_NAME: "registry.gitlab.com/timvisee/send:master-$CI_COMMIT_SHORT_SHA"
|
|
||||||
before_script: []
|
|
||||||
script:
|
|
||||||
# Login in to registry
|
|
||||||
- 'docker login registry.gitlab.com -u $DOCKER_USER -p $DOCKER_PASS'
|
|
||||||
|
|
||||||
# Load existing, retag for new image images
|
|
||||||
- docker image load -i $IMG_IMPORT_FILE
|
|
||||||
- docker tag $IMG_IMPORT_NAME $IMG_NAME
|
|
||||||
|
|
||||||
# Publish tagged image
|
|
||||||
- docker push $IMG_NAME
|
|
||||||
|
|
||||||
- 'echo "Docker image artifact published, available as:" && echo " docker pull $IMG_NAME"'
|
|
||||||
|
|
||||||
# Release public Docker image for a version tag
|
|
||||||
release-docker:
|
release-docker:
|
||||||
stage: release
|
stage: release
|
||||||
image: docker:latest
|
image: docker:latest
|
||||||
dependencies:
|
|
||||||
- artifact-docker
|
|
||||||
services:
|
services:
|
||||||
- docker:dind
|
- docker:dind
|
||||||
only:
|
only:
|
||||||
- /^v(\d+\.)*\d+$/
|
- api
|
||||||
variables:
|
- branches
|
||||||
IMG_IMPORT_FILE: "send:git-$CI_COMMIT_SHORT_SHA.tar"
|
- chat
|
||||||
IMG_IMPORT_NAME: "send:git-$CI_COMMIT_SHORT_SHA"
|
- merge_requests
|
||||||
IMG_NAME: "registry.gitlab.com/timvisee/send:$CI_COMMIT_REF_NAME"
|
- pushes
|
||||||
IMG_NAME_LATEST: "registry.gitlab.com/timvisee/send:latest"
|
- schedules
|
||||||
before_script: []
|
- tags
|
||||||
|
- triggers
|
||||||
|
- web
|
||||||
script:
|
script:
|
||||||
# Login in to registry
|
- docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
|
||||||
- 'docker login registry.gitlab.com -u $DOCKER_USER -p $DOCKER_PASS'
|
- docker buildx create --name sendBuilder
|
||||||
|
- docker buildx use sendBuilder
|
||||||
# Load existing, retag for new image images
|
- |
|
||||||
- docker image load -i $IMG_IMPORT_FILE
|
if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then
|
||||||
- docker tag $IMG_IMPORT_NAME $IMG_NAME
|
IMAGE_NAMES="$CI_REGISTRY_IMAGE/mr:$CI_MERGE_REQUEST_IID"
|
||||||
- docker tag $IMG_IMPORT_NAME $IMG_NAME_LATEST
|
elif [ "$CI_COMMIT_TAG" != "" ]; then
|
||||||
|
IMAGE_NAMES="$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG $CI_REGISTRY_IMAGE:latest"
|
||||||
# Publish tagged image
|
else
|
||||||
- docker push $IMG_NAME
|
IMAGE_NAMES="$CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHORT_SHA"
|
||||||
- docker push $IMG_NAME_LATEST
|
fi
|
||||||
|
- |
|
||||||
- 'echo "Docker image artifact published, available as:" && echo " docker pull $IMG_NAME_LATEST" && echo " docker pull $IMG_NAME"'
|
for image in $IMAGE_NAMES; do
|
||||||
|
docker buildx build --platform linux/amd64,linux/arm64 -t $image . --push
|
||||||
|
done
|
||||||
|
- |
|
||||||
|
echo "Container image pushed. You can pull it with";
|
||||||
|
for image in $IMAGE_NAMES; do
|
||||||
|
echo "docker pull $image"
|
||||||
|
done
|
||||||
|
|
|
@ -63,6 +63,7 @@ COPY --chown=app:app server server
|
||||||
COPY --chown=app:app --from=builder /app/dist dist
|
COPY --chown=app:app --from=builder /app/dist dist
|
||||||
|
|
||||||
RUN npm ci --production && npm cache clean --force
|
RUN npm ci --production && npm cache clean --force
|
||||||
|
RUN mkdir -p /app/.config/configstore
|
||||||
RUN ln -s dist/version.json version.json
|
RUN ln -s dist/version.json version.json
|
||||||
|
|
||||||
ENV PORT=1443
|
ENV PORT=1443
|
||||||
|
|
|
@ -152,7 +152,7 @@ AWS example using Ubuntu Server `20.04`: [docs/AWS.md](docs/AWS.md)
|
||||||
- Web: _this repository_
|
- Web: _this repository_
|
||||||
- Command-line: [`ffsend`](https://github.com/timvisee/ffsend)
|
- Command-line: [`ffsend`](https://github.com/timvisee/ffsend)
|
||||||
- Android: _see [Android](#android) section_
|
- Android: _see [Android](#android) section_
|
||||||
- Thunderbird: [FileLink provider for Send](https://addons.thunderbird.net/en-US/thunderbird/addon/filelink-provider-for-send/)
|
- Thunderbird: [FileLink provider for Send](https://addons.thunderbird.net/thunderbird/addon/filelink-provider-for-send/)
|
||||||
|
|
||||||
#### Android
|
#### Android
|
||||||
|
|
||||||
|
|
|
@ -6,4 +6,4 @@ parserOptions:
|
||||||
sourceType: module
|
sourceType: module
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
n/no-unsupported-features: off
|
node/no-unsupported-features: off
|
||||||
|
|
|
@ -17,6 +17,7 @@ export default class Archive {
|
||||||
constructor(files = [], defaultTimeLimit = 86400, defaultDownloadLimit = 1) {
|
constructor(files = [], defaultTimeLimit = 86400, defaultDownloadLimit = 1) {
|
||||||
this.files = Array.from(files);
|
this.files = Array.from(files);
|
||||||
this.defaultTimeLimit = defaultTimeLimit;
|
this.defaultTimeLimit = defaultTimeLimit;
|
||||||
|
this.defaultDownloadLimit = defaultDownloadLimit;
|
||||||
this.timeLimit = defaultTimeLimit;
|
this.timeLimit = defaultTimeLimit;
|
||||||
this.dlimit = defaultDownloadLimit;
|
this.dlimit = defaultDownloadLimit;
|
||||||
this.password = null;
|
this.password = null;
|
||||||
|
@ -76,7 +77,7 @@ export default class Archive {
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.files = [];
|
this.files = [];
|
||||||
this.dlimit = 1;
|
this.dlimit = this.defaultDownloadLimit;
|
||||||
this.timeLimit = this.defaultTimeLimit;
|
this.timeLimit = this.defaultTimeLimit;
|
||||||
this.password = null;
|
this.password = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,13 @@ async function checkCrypto() {
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return false;
|
try {
|
||||||
|
window.asmCrypto = await import('asmcrypto.js');
|
||||||
|
await import('@dannycoates/webcrypto-liner/build/shim');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +66,25 @@ function checkStreams() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function polyfillStreams() {
|
||||||
|
try {
|
||||||
|
await import('@mattiasbuelens/web-streams-polyfill');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default async function getCapabilities() {
|
export default async function getCapabilities() {
|
||||||
const browser = browserName();
|
const browser = browserName();
|
||||||
const isMobile = /mobi|android/i.test(navigator.userAgent);
|
const isMobile = /mobi|android/i.test(navigator.userAgent);
|
||||||
const serviceWorker = 'serviceWorker' in navigator && browser !== 'edge';
|
const serviceWorker = 'serviceWorker' in navigator && browser !== 'edge';
|
||||||
let crypto = await checkCrypto();
|
let crypto = await checkCrypto();
|
||||||
const nativeStreams = checkStreams();
|
const nativeStreams = checkStreams();
|
||||||
|
let polyStreams = false;
|
||||||
|
if (!nativeStreams) {
|
||||||
|
polyStreams = await polyfillStreams();
|
||||||
|
}
|
||||||
let account = typeof AUTH_CONFIG !== 'undefined';
|
let account = typeof AUTH_CONFIG !== 'undefined';
|
||||||
try {
|
try {
|
||||||
account = account && !!localStorage;
|
account = account && !!localStorage;
|
||||||
|
@ -87,10 +106,10 @@ export default async function getCapabilities() {
|
||||||
account,
|
account,
|
||||||
crypto,
|
crypto,
|
||||||
serviceWorker,
|
serviceWorker,
|
||||||
streamUpload: nativeStreams,
|
streamUpload: nativeStreams || polyStreams,
|
||||||
streamDownload:
|
streamDownload:
|
||||||
nativeStreams && serviceWorker && browser !== 'safari' && !mobileFirefox,
|
nativeStreams && serviceWorker && browser !== 'safari' && !mobileFirefox,
|
||||||
multifile: nativeStreams,
|
multifile: nativeStreams || polyStreams,
|
||||||
share,
|
share,
|
||||||
standalone
|
standalone
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,7 +48,7 @@ class ECETransformer {
|
||||||
name: 'AES-GCM',
|
name: 'AES-GCM',
|
||||||
length: 128
|
length: 128
|
||||||
},
|
},
|
||||||
false,
|
true, // Edge polyfill requires key to be extractable to encrypt :/
|
||||||
['encrypt', 'decrypt']
|
['encrypt', 'decrypt']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* global DEFAULTS LIMITS WEB_UI PREFS */
|
/* global DEFAULTS LIMITS WEB_UI PREFS */
|
||||||
import 'core-js';
|
import 'core-js';
|
||||||
|
import 'fast-text-encoding'; // MS Edge support
|
||||||
import 'intl-pluralrules';
|
import 'intl-pluralrules';
|
||||||
import choo from 'choo';
|
import choo from 'choo';
|
||||||
import nanotiming from 'nanotiming';
|
import nanotiming from 'nanotiming';
|
||||||
|
|
|
@ -110,7 +110,7 @@ class Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
set user(info) {
|
set user(info) {
|
||||||
this.engine.setItem('user', JSON.stringify(info));
|
return this.engine.setItem('user', JSON.stringify(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
getFileById(id) {
|
getFileById(id) {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/* global TransformStream */
|
||||||
|
|
||||||
export function transformStream(readable, transformer, oncancel) {
|
export function transformStream(readable, transformer, oncancel) {
|
||||||
try {
|
try {
|
||||||
return readable.pipeThrough(new TransformStream(transformer));
|
return readable.pipeThrough(new TransformStream(transformer));
|
||||||
|
|
|
@ -26,7 +26,7 @@ function expiryInfo(translate, archive) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function password(state) {
|
function password(state) {
|
||||||
const MAX_LENGTH = 32;
|
const MAX_LENGTH = 4096;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="mb-2 px-1">
|
<div class="mb-2 px-1">
|
||||||
|
|
|
@ -32,7 +32,7 @@ module.exports = function(state, emit) {
|
||||||
class="w-full border-l border-t border-b rounded-l-lg rounded-r-none ${invalid
|
class="w-full border-l border-t border-b rounded-l-lg rounded-r-none ${invalid
|
||||||
? 'border-red dark:border-red-40'
|
? 'border-red dark:border-red-40'
|
||||||
: 'border-grey'} leading-loose px-2 py-1 dark:bg-grey-80"
|
: 'border-grey'} leading-loose px-2 py-1 dark:bg-grey-80"
|
||||||
maxlength="32"
|
maxlength="4096"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder="${state.translate('unlockInputPlaceholder')}"
|
placeholder="${state.translate('unlockInputPlaceholder')}"
|
||||||
oninput="${inputChanged}"
|
oninput="${inputChanged}"
|
||||||
|
|
|
@ -65,6 +65,45 @@ class Footer extends Component {
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defining a custom footer
|
||||||
|
var footer = [];
|
||||||
|
if (this.state != undefined && this.state.WEB_UI != undefined) {
|
||||||
|
const WEB_UI = this.state.WEB_UI;
|
||||||
|
|
||||||
|
if (WEB_UI.CUSTOM_FOOTER_URL != '' && WEB_UI.CUSTOM_FOOTER_TEXT != '') {
|
||||||
|
footer.push(html`
|
||||||
|
<li class="m-2">
|
||||||
|
<a href="${WEB_UI.CUSTOM_FOOTER_URL}" target="_blank">
|
||||||
|
${WEB_UI.CUSTOM_FOOTER_TEXT}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
else if (WEB_UI.CUSTOM_FOOTER_URL != '') {
|
||||||
|
footer.push(html`
|
||||||
|
<li class="m-2">
|
||||||
|
<a href="${WEB_UI.CUSTOM_FOOTER_URL}" target="_blank">
|
||||||
|
${WEB_UI.CUSTOM_FOOTER_URL}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
else if (WEB_UI.CUSTOM_FOOTER_TEXT != '') {
|
||||||
|
footer.push(html`
|
||||||
|
<li class="m-2">
|
||||||
|
${WEB_UI.CUSTOM_FOOTER_TEXT}
|
||||||
|
</li>
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
footer.push(html`
|
||||||
|
<li class="m-2">
|
||||||
|
${translate('footerText')}
|
||||||
|
</li>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<footer
|
<footer
|
||||||
class="flex flex-col md:flex-row items-start w-full flex-none self-start p-6 md:p-8 font-medium text-xs text-grey-60 dark:text-grey-40 md:items-center justify-between"
|
class="flex flex-col md:flex-row items-start w-full flex-none self-start p-6 md:p-8 font-medium text-xs text-grey-60 dark:text-grey-40 md:items-center justify-between"
|
||||||
|
@ -72,7 +111,7 @@ class Footer extends Component {
|
||||||
<ul
|
<ul
|
||||||
class="flex flex-col md:flex-row items-start md:items-center md:justify-start"
|
class="flex flex-col md:flex-row items-start md:items-center md:justify-start"
|
||||||
>
|
>
|
||||||
<li class="m-2">${translate('footerText')}</li>
|
${footer}
|
||||||
</ul>
|
</ul>
|
||||||
<ul
|
<ul
|
||||||
class="flex flex-col md:flex-row items-start md:items-center md:justify-end"
|
class="flex flex-col md:flex-row items-start md:items-center md:justify-end"
|
||||||
|
|
52
app/utils.js
52
app/utils.js
|
@ -23,34 +23,39 @@ function locale() {
|
||||||
return document.querySelector('html').lang;
|
return document.querySelector('html').lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadShim(polyfill) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const shim = document.createElement('script');
|
||||||
|
shim.src = polyfill;
|
||||||
|
shim.addEventListener('load', () => resolve(true));
|
||||||
|
shim.addEventListener('error', () => resolve(false));
|
||||||
|
document.head.appendChild(shim);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function isFile(id) {
|
function isFile(id) {
|
||||||
return /^[0-9a-fA-F]{10,16}$/.test(id);
|
return /^[0-9a-fA-F]{10,16}$/.test(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function copyToClipboard(str) {
|
function copyToClipboard(str) {
|
||||||
try {
|
const aux = document.createElement('input');
|
||||||
await navigator.clipboard.writeText(str);
|
aux.setAttribute('value', str);
|
||||||
} catch {
|
aux.contentEditable = true;
|
||||||
// Older browsers or the clipboard API fails because of a missing permission
|
aux.readOnly = true;
|
||||||
const aux = document.createElement('input');
|
document.body.appendChild(aux);
|
||||||
aux.setAttribute('value', str);
|
if (navigator.userAgent.match(/iphone|ipad|ipod/i)) {
|
||||||
aux.contentEditable = true;
|
const range = document.createRange();
|
||||||
aux.readOnly = true;
|
range.selectNodeContents(aux);
|
||||||
document.body.appendChild(aux);
|
const sel = getSelection();
|
||||||
if (navigator.userAgent.match(/iphone|ipad|ipod/i)) {
|
sel.removeAllRanges();
|
||||||
const range = document.createRange();
|
sel.addRange(range);
|
||||||
range.selectNodeContents(aux);
|
aux.setSelectionRange(0, str.length);
|
||||||
const sel = getSelection();
|
} else {
|
||||||
sel.removeAllRanges();
|
aux.select();
|
||||||
sel.addRange(range);
|
|
||||||
aux.setSelectionRange(0, str.length);
|
|
||||||
} else {
|
|
||||||
aux.select();
|
|
||||||
}
|
|
||||||
const result = document.execCommand('copy');
|
|
||||||
document.body.removeChild(aux);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
const result = document.execCommand('copy');
|
||||||
|
document.body.removeChild(aux);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LOCALIZE_NUMBERS = !!(
|
const LOCALIZE_NUMBERS = !!(
|
||||||
|
@ -282,6 +287,7 @@ module.exports = {
|
||||||
copyToClipboard,
|
copyToClipboard,
|
||||||
arrayToB64,
|
arrayToB64,
|
||||||
b64ToArray,
|
b64ToArray,
|
||||||
|
loadShim,
|
||||||
isFile,
|
isFile,
|
||||||
openLinksInNewTab,
|
openLinksInNewTab,
|
||||||
browserName,
|
browserName,
|
||||||
|
|
|
@ -3,7 +3,7 @@ const isServer = typeof genmap === 'function';
|
||||||
let prefix = '';
|
let prefix = '';
|
||||||
let manifest = {};
|
let manifest = {};
|
||||||
try {
|
try {
|
||||||
//eslint-disable-next-line n/no-missing-require
|
//eslint-disable-next-line node/no-missing-require
|
||||||
manifest = require('../dist/manifest.json');
|
manifest = require('../dist/manifest.json');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// use middleware
|
// use middleware
|
||||||
|
|
|
@ -9,6 +9,7 @@ docker pull registry.gitlab.com/timvisee/send:latest
|
||||||
docker run -v $PWD/uploads:/uploads -p 1443:1443 \
|
docker run -v $PWD/uploads:/uploads -p 1443:1443 \
|
||||||
-e 'DETECT_BASE_URL=true' \
|
-e 'DETECT_BASE_URL=true' \
|
||||||
-e 'REDIS_HOST=localhost' \
|
-e 'REDIS_HOST=localhost' \
|
||||||
|
-e 'FILE_DIR=/uploads' \
|
||||||
registry.gitlab.com/timvisee/send:latest
|
registry.gitlab.com/timvisee/send:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ Config options expecting array values (e.g. `EXPIRE_TIMES_SECONDS`, `DOWNLOAD_CO
|
||||||
| `PORT` | Port the server will listen on (defaults to `1443`)
|
| `PORT` | Port the server will listen on (defaults to `1443`)
|
||||||
| `NODE_ENV` | Run in `development` mode (unsafe) or `production` mode (the default)
|
| `NODE_ENV` | Run in `development` mode (unsafe) or `production` mode (the default)
|
||||||
| `SEND_FOOTER_DMCA_URL` | A URL to a contact page for DMCA requests (empty / not shown by default)
|
| `SEND_FOOTER_DMCA_URL` | A URL to a contact page for DMCA requests (empty / not shown by default)
|
||||||
| `SENTRY_CLIENT`, `SENTRY_DSN` | Sentry Client ID and DNS for error tracking (optional, disabled by default)
|
| `SENTRY_CLIENT`, `SENTRY_DSN` | Sentry Client ID and DSN for error tracking (optional, disabled by default)
|
||||||
|
|
||||||
*Note: more options can be found here: https://github.com/timvisee/send/blob/master/server/config.js*
|
*Note: more options can be found here: https://github.com/timvisee/send/blob/master/server/config.js*
|
||||||
|
|
||||||
|
@ -96,6 +97,11 @@ See the table below for the variables and their default values.
|
||||||
| UI_CUSTOM_ASSETS_FACEBOOK | | A custom header image for Facebook |
|
| UI_CUSTOM_ASSETS_FACEBOOK | | A custom header image for Facebook |
|
||||||
| UI_CUSTOM_ASSETS_TWITTER | | A custom header image for Twitter |
|
| UI_CUSTOM_ASSETS_TWITTER | | A custom header image for Twitter |
|
||||||
| UI_CUSTOM_ASSETS_WORDMARK | | A custom wordmark (Text next to the logo) |
|
| UI_CUSTOM_ASSETS_WORDMARK | | A custom wordmark (Text next to the logo) |
|
||||||
|
| UI_CUSTOM_CSS | | Allows you to define a custom CSS file for custom styling |
|
||||||
|
| CUSTOM_FOOTER_TEXT | | Allows you to define a custom footer |
|
||||||
|
| CUSTOM_FOOTER_URL | | Allows you to define a custom URL in your footer |
|
||||||
|
|
||||||
|
Side note: If you define a custom URL and a custom footer, only the footer text will display, but will be hyperlinked to the URL.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
- https://github.com/whatwg/streams/tree/master/reference-implementation
|
- https://github.com/whatwg/streams/tree/master/reference-implementation
|
||||||
- Examples
|
- Examples
|
||||||
- https://github.com/mdn/dom-examples/tree/master/streams
|
- https://github.com/mdn/dom-examples/tree/master/streams
|
||||||
|
- Polyfill
|
||||||
|
- https://github.com/MattiasBuelens/web-streams-polyfill
|
||||||
|
|
||||||
# Encrypted Content Encoding
|
# Encrypted Content Encoding
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global window, document */
|
/* global window, document, fetch */
|
||||||
|
|
||||||
const MAXFILESIZE = 1024 * 1024 * 1024 * 2;
|
const MAXFILESIZE = 1024 * 1024 * 1024 * 2;
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "send",
|
"name": "send",
|
||||||
"description": "File Sharing Experiment",
|
"description": "File Sharing Experiment",
|
||||||
"version": "3.4.20",
|
"version": "3.4.23",
|
||||||
"author": "Mozilla (https://mozilla.org)",
|
"author": "Mozilla (https://mozilla.org)",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Tim Visee <3a4fb3964f@sinenomine.email> (https://timvisee.com)"
|
"Tim Visee <3a4fb3964f@sinenomine.email> (https://timvisee.com)"
|
||||||
|
@ -66,10 +66,13 @@
|
||||||
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||||
"@babel/preset-env": "^7.16.11",
|
"@babel/preset-env": "^7.16.11",
|
||||||
|
"@dannycoates/webcrypto-liner": "^0.1.37",
|
||||||
"@fullhuman/postcss-purgecss": "^4.1.3",
|
"@fullhuman/postcss-purgecss": "^4.1.3",
|
||||||
|
"@mattiasbuelens/web-streams-polyfill": "0.2.1",
|
||||||
"@sentry/browser": "^5.30.0",
|
"@sentry/browser": "^5.30.0",
|
||||||
|
"asmcrypto.js": "^0.22.0",
|
||||||
"babel-loader": "^8.2.4",
|
"babel-loader": "^8.2.4",
|
||||||
"babel-plugin-istanbul": "^6.1.1",
|
"babel-plugin-istanbul": "^5.2.0",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
"content-disposition": "^0.5.4",
|
"content-disposition": "^0.5.4",
|
||||||
"copy-webpack-plugin": "^6.4.0",
|
"copy-webpack-plugin": "^6.4.0",
|
||||||
|
@ -77,20 +80,25 @@
|
||||||
"crc": "^3.8.0",
|
"crc": "^3.8.0",
|
||||||
"cross-env": "^6.0.3",
|
"cross-env": "^6.0.3",
|
||||||
"css-loader": "^5.2.7",
|
"css-loader": "^5.2.7",
|
||||||
|
"css-mqpacker": "^7.0.0",
|
||||||
"cssnano": "^5.1.12",
|
"cssnano": "^5.1.12",
|
||||||
"eslint": "^8.21.0",
|
"eslint": "^6.6.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^6.15.0",
|
||||||
"eslint-plugin-mocha": "^10.1.0",
|
"eslint-plugin-mocha": "^6.2.1",
|
||||||
"eslint-plugin-n": "^15.2.4",
|
"eslint-plugin-node": "^10.0.0",
|
||||||
"eslint-plugin-security": "^1.5.0",
|
"eslint-plugin-security": "^1.4.0",
|
||||||
|
"expose-loader": "^0.7.5",
|
||||||
|
"extract-loader": "^3.2.0",
|
||||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||||
|
"fast-text-encoding": "^1.0.3",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"git-rev-sync": "^3.0.2",
|
"git-rev-sync": "^3.0.2",
|
||||||
|
"html-loader": "^0.5.5",
|
||||||
"http_ece": "^1.1.0",
|
"http_ece": "^1.1.0",
|
||||||
"husky": "^3.0.9",
|
"husky": "^3.0.9",
|
||||||
"intl-pluralrules": "^1.3.1",
|
"intl-pluralrules": "^1.3.1",
|
||||||
"lint-staged": "^9.4.2",
|
"lint-staged": "^9.4.2",
|
||||||
"mocha": "^6.2.2",
|
"mocha": "^10.1.0",
|
||||||
"morgan": "^1.9.1",
|
"morgan": "^1.9.1",
|
||||||
"nanobus": "^4.5.0",
|
"nanobus": "^4.5.0",
|
||||||
"nanohtml": "^1.9.0",
|
"nanohtml": "^1.9.0",
|
||||||
|
@ -105,6 +113,7 @@
|
||||||
"puppeteer": "^2.0.0",
|
"puppeteer": "^2.0.0",
|
||||||
"raw-loader": "^3.1.0",
|
"raw-loader": "^3.1.0",
|
||||||
"rimraf": "^3.0.0",
|
"rimraf": "^3.0.0",
|
||||||
|
"script-loader": "^0.7.2",
|
||||||
"sinon": "^7.5.0",
|
"sinon": "^7.5.0",
|
||||||
"string-hash": "^1.1.3",
|
"string-hash": "^1.1.3",
|
||||||
"stylelint": "^14.9.1",
|
"stylelint": "^14.9.1",
|
||||||
|
@ -131,8 +140,10 @@
|
||||||
"body-parser": "^1.20.0",
|
"body-parser": "^1.20.0",
|
||||||
"choo": "^7.0.0",
|
"choo": "^7.0.0",
|
||||||
"cldr-core": "^35.1.0",
|
"cldr-core": "^35.1.0",
|
||||||
"convict": "^6.2.3",
|
"configstore": "github:dannycoates/configstore#master",
|
||||||
|
"convict": "^6.2.4",
|
||||||
"convict-format-with-validator": "^6.2.0",
|
"convict-format-with-validator": "^6.2.0",
|
||||||
|
"double-ended-queue": "^2.1.0-0",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"helmet": "^3.23.3",
|
"helmet": "^3.23.3",
|
||||||
"mozlog": "^3.0.1",
|
"mozlog": "^3.0.1",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
rules:
|
rules:
|
||||||
n/shebang: off
|
node/shebang: off
|
||||||
security/detect-child-process: off
|
security/detect-child-process: off
|
||||||
|
|
||||||
no-console: off
|
no-console: off
|
||||||
|
|
|
@ -13,6 +13,8 @@ module.exports = {
|
||||||
FOOTER_CLI_URL: config.footer_cli_url,
|
FOOTER_CLI_URL: config.footer_cli_url,
|
||||||
FOOTER_DMCA_URL: config.footer_dmca_url,
|
FOOTER_DMCA_URL: config.footer_dmca_url,
|
||||||
FOOTER_SOURCE_URL: config.footer_source_url,
|
FOOTER_SOURCE_URL: config.footer_source_url,
|
||||||
|
CUSTOM_FOOTER_TEXT: config.custom_footer_text,
|
||||||
|
CUSTOM_FOOTER_URL: config.custom_footer_url,
|
||||||
COLORS: {
|
COLORS: {
|
||||||
PRIMARY: config.ui_color_primary,
|
PRIMARY: config.ui_color_primary,
|
||||||
ACCENT: config.ui_color_accent
|
ACCENT: config.ui_color_accent
|
||||||
|
|
|
@ -165,9 +165,19 @@ const conf = convict({
|
||||||
},
|
},
|
||||||
base_url: {
|
base_url: {
|
||||||
format: 'url',
|
format: 'url',
|
||||||
default: 'https://send.firefox.com',
|
default: 'https://send.example.com',
|
||||||
env: 'BASE_URL'
|
env: 'BASE_URL'
|
||||||
},
|
},
|
||||||
|
custom_title: {
|
||||||
|
format: String,
|
||||||
|
default: 'Send',
|
||||||
|
env: 'CUSTOM_TITLE'
|
||||||
|
},
|
||||||
|
custom_description: {
|
||||||
|
format: String,
|
||||||
|
default: 'Encrypt and send files with a link that automatically expires to ensure your important documents don’t stay online forever.',
|
||||||
|
env: 'CUSTOM_DESCRIPTION'
|
||||||
|
},
|
||||||
detect_base_url: {
|
detect_base_url: {
|
||||||
format: Boolean,
|
format: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
@ -243,6 +253,16 @@ const conf = convict({
|
||||||
default: 'https://github.com/timvisee/send',
|
default: 'https://github.com/timvisee/send',
|
||||||
env: 'SEND_FOOTER_SOURCE_URL'
|
env: 'SEND_FOOTER_SOURCE_URL'
|
||||||
},
|
},
|
||||||
|
custom_footer_text: {
|
||||||
|
format: String,
|
||||||
|
default: '',
|
||||||
|
env: 'CUSTOM_FOOTER_TEXT'
|
||||||
|
},
|
||||||
|
custom_footer_url: {
|
||||||
|
format: String,
|
||||||
|
default: '',
|
||||||
|
env: 'CUSTOM_FOOTER_URL'
|
||||||
|
},
|
||||||
ui_color_primary: {
|
ui_color_primary: {
|
||||||
format: String,
|
format: String,
|
||||||
default: '#0a84ff',
|
default: '#0a84ff',
|
||||||
|
@ -253,6 +273,11 @@ const conf = convict({
|
||||||
default: '#003eaa',
|
default: '#003eaa',
|
||||||
env: 'UI_COLOR_ACCENT'
|
env: 'UI_COLOR_ACCENT'
|
||||||
},
|
},
|
||||||
|
custom_locale: {
|
||||||
|
format: String,
|
||||||
|
default: '',
|
||||||
|
env: 'CUSTOM_LOCALE'
|
||||||
|
},
|
||||||
ui_custom_assets: {
|
ui_custom_assets: {
|
||||||
android_chrome_192px: {
|
android_chrome_192px: {
|
||||||
format: String,
|
format: String,
|
||||||
|
@ -303,6 +328,11 @@ const conf = convict({
|
||||||
format: String,
|
format: String,
|
||||||
default: '',
|
default: '',
|
||||||
env: 'UI_CUSTOM_ASSETS_WORDMARK'
|
env: 'UI_CUSTOM_ASSETS_WORDMARK'
|
||||||
|
},
|
||||||
|
custom_css: {
|
||||||
|
format: String,
|
||||||
|
default: '',
|
||||||
|
env: 'UI_CUSTOM_CSS'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@ const clientConstants = require('./clientConstants');
|
||||||
|
|
||||||
let sentry = '';
|
let sentry = '';
|
||||||
if (config.sentry_id) {
|
if (config.sentry_id) {
|
||||||
//eslint-disable-next-line n/no-missing-require
|
//eslint-disable-next-line node/no-missing-require
|
||||||
const version = require('../dist/version.json');
|
const version = require('../dist/version.json');
|
||||||
sentry = `
|
sentry = `
|
||||||
var SENTRY_CONFIG = {
|
var SENTRY_CONFIG = {
|
||||||
|
|
|
@ -3,6 +3,10 @@ const assets = require('../common/assets');
|
||||||
const initScript = require('./initScript');
|
const initScript = require('./initScript');
|
||||||
|
|
||||||
module.exports = function(state, body = '') {
|
module.exports = function(state, body = '') {
|
||||||
|
const custom_css = state.ui.assets.custom_css !== ''
|
||||||
|
? html`<link rel="stylesheet" type="text/css" href="${state.ui.assets.custom_css}" />`
|
||||||
|
: ''
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="${state.locale}">
|
<html lang="${state.locale}">
|
||||||
|
@ -40,6 +44,7 @@ module.exports = function(state, body = '') {
|
||||||
type="text/css"
|
type="text/css"
|
||||||
href="${assets.get('app.css')}"
|
href="${assets.get('app.css')}"
|
||||||
/>
|
/>
|
||||||
|
${custom_css}
|
||||||
<link
|
<link
|
||||||
rel="apple-touch-icon"
|
rel="apple-touch-icon"
|
||||||
sizes="180x180"
|
sizes="180x180"
|
||||||
|
|
|
@ -120,7 +120,7 @@ module.exports = function(app) {
|
||||||
);
|
);
|
||||||
app.post(`/api/info/:id${ID_REGEX}`, auth.owner, require('./info'));
|
app.post(`/api/info/:id${ID_REGEX}`, auth.owner, require('./info'));
|
||||||
app.get('/__version__', function(req, res) {
|
app.get('/__version__', function(req, res) {
|
||||||
// eslint-disable-next-line n/no-missing-require
|
// eslint-disable-next-line node/no-missing-require
|
||||||
res.sendFile(require.resolve('../../dist/version.json'));
|
res.sendFile(require.resolve('../../dist/version.json'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,18 @@ const layout = require('./layout');
|
||||||
const assets = require('../common/assets');
|
const assets = require('../common/assets');
|
||||||
const getTranslator = require('./locale');
|
const getTranslator = require('./locale');
|
||||||
const { getFxaConfig } = require('./fxa');
|
const { getFxaConfig } = require('./fxa');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
module.exports = async function(req) {
|
module.exports = async function(req) {
|
||||||
const locale = req.language || 'en-US';
|
const locale = (() => {
|
||||||
|
if (config.custom_locale != '' && fs.existsSync(path.join(__dirname,'../public/locales',config.custom_locale))) {
|
||||||
|
return config.custom_locale;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return req.language || 'en-US';
|
||||||
|
}
|
||||||
|
})();
|
||||||
let authConfig = null;
|
let authConfig = null;
|
||||||
let robots = 'none';
|
let robots = 'none';
|
||||||
if (req.route && req.route.path === '/') {
|
if (req.route && req.route.path === '/') {
|
||||||
|
@ -34,7 +43,8 @@ module.exports = async function(req) {
|
||||||
safari_pinned_tab: assets.get('safari-pinned-tab.svg'),
|
safari_pinned_tab: assets.get('safari-pinned-tab.svg'),
|
||||||
facebook: baseUrl + '/' + assets.get('send-fb.jpg'),
|
facebook: baseUrl + '/' + assets.get('send-fb.jpg'),
|
||||||
twitter: baseUrl + '/' + assets.get('send-twitter.jpg'),
|
twitter: baseUrl + '/' + assets.get('send-twitter.jpg'),
|
||||||
wordmark: assets.get('wordmark.svg') + '#logo'
|
wordmark: assets.get('wordmark.svg') + '#logo',
|
||||||
|
custom_css: ''
|
||||||
};
|
};
|
||||||
Object.keys(uiAssets).forEach(index => {
|
Object.keys(uiAssets).forEach(index => {
|
||||||
if (config.ui_custom_assets[index] !== '')
|
if (config.ui_custom_assets[index] !== '')
|
||||||
|
@ -47,9 +57,8 @@ module.exports = async function(req) {
|
||||||
locale,
|
locale,
|
||||||
capabilities: { account: false },
|
capabilities: { account: false },
|
||||||
translate: getTranslator(locale),
|
translate: getTranslator(locale),
|
||||||
title: 'Send',
|
title: config.custom_title,
|
||||||
description:
|
description: config.custom_description,
|
||||||
'Encrypt and send files with a link that automatically expires to ensure your important documents don’t stay online forever.',
|
|
||||||
baseUrl,
|
baseUrl,
|
||||||
ui: {
|
ui: {
|
||||||
colors: {
|
colors: {
|
||||||
|
|
|
@ -6,10 +6,10 @@ extends:
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- mocha
|
- mocha
|
||||||
- n
|
- node
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
n/no-unpublished-require: off
|
node/no-unpublished-require: off
|
||||||
|
|
||||||
mocha/handle-done-callback: error
|
mocha/handle-done-callback: error
|
||||||
mocha/no-exclusive-tests: error
|
mocha/no-exclusive-tests: error
|
||||||
|
|
|
@ -5,4 +5,4 @@ parserOptions:
|
||||||
sourceType: module
|
sourceType: module
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
n/no-unsupported-features: off
|
node/no-unsupported-features: off
|
|
@ -9,7 +9,7 @@ module.exports = function() {
|
||||||
const files = fs
|
const files = fs
|
||||||
.readdirSync(path.join(__dirname, 'tests'))
|
.readdirSync(path.join(__dirname, 'tests'))
|
||||||
.filter(p => /\.js$/.test(p));
|
.filter(p => /\.js$/.test(p));
|
||||||
const code = files.map(kv).join(';\n');
|
const code = "require('fast-text-encoding');\n" + files.map(kv).join(';\n');
|
||||||
return {
|
return {
|
||||||
code,
|
code,
|
||||||
dependencies: files.map(f => require.resolve('./tests/' + f)),
|
dependencies: files.map(f => require.resolve('./tests/' + f)),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// eslint-disable-next-line n/no-extraneous-require
|
// eslint-disable-next-line node/no-extraneous-require
|
||||||
const ip = require('ip');
|
const ip = require('ip');
|
||||||
const common = require('./wdio.common.conf');
|
const common = require('./wdio.common.conf');
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// eslint-disable-next-line n/no-extraneous-require
|
// eslint-disable-next-line node/no-extraneous-require
|
||||||
const ip = require('ip');
|
const ip = require('ip');
|
||||||
const common = require('./wdio.common.conf');
|
const common = require('./wdio.common.conf');
|
||||||
const dir =
|
const dir =
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// eslint-disable-next-line n/no-extraneous-require
|
// eslint-disable-next-line node/no-extraneous-require
|
||||||
const ip = require('ip');
|
const ip = require('ip');
|
||||||
const common = require('./wdio.common.conf');
|
const common = require('./wdio.common.conf');
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,10 @@ const web = {
|
||||||
path.resolve(__dirname, 'common'),
|
path.resolve(__dirname, 'common'),
|
||||||
// some dependencies need to get re-babeled because we
|
// some dependencies need to get re-babeled because we
|
||||||
// have different targets than their default configs
|
// have different targets than their default configs
|
||||||
|
path.resolve(
|
||||||
|
__dirname,
|
||||||
|
'node_modules/@dannycoates/webcrypto-liner'
|
||||||
|
),
|
||||||
path.resolve(__dirname, 'node_modules/@fluent'),
|
path.resolve(__dirname, 'node_modules/@fluent'),
|
||||||
path.resolve(__dirname, 'node_modules/intl-pluralrules')
|
path.resolve(__dirname, 'node_modules/intl-pluralrules')
|
||||||
],
|
],
|
||||||
|
@ -123,7 +127,8 @@ const web = {
|
||||||
path.resolve(__dirname, 'node_modules/crc'),
|
path.resolve(__dirname, 'node_modules/crc'),
|
||||||
path.resolve(__dirname, 'node_modules/@fluent'),
|
path.resolve(__dirname, 'node_modules/@fluent'),
|
||||||
path.resolve(__dirname, 'node_modules/@sentry'),
|
path.resolve(__dirname, 'node_modules/@sentry'),
|
||||||
path.resolve(__dirname, 'node_modules/tslib')
|
path.resolve(__dirname, 'node_modules/tslib'),
|
||||||
|
path.resolve(__dirname, 'node_modules/webcrypto-core')
|
||||||
],
|
],
|
||||||
loader: 'webpack-unassert-loader'
|
loader: 'webpack-unassert-loader'
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue