Compare commits

...

51 Commits

Author SHA1 Message Date
Tim Visée 6ad2885a16 Merge branch 'aron9861623-master-patch-24529' into 'master'
Fixed docker.md first example

See merge request timvisee/send!32
2023-06-09 13:31:51 +00:00
Aron Tecsi 70662888b1 Fixed docker.md first example 2023-06-09 11:19:42 +00:00
timvisee 9f09a79986
Merge branch 'emilstahl-patch-1' into master
See https://github.com/timvisee/send/pull/149
2023-02-27 21:45:59 +01:00
Emil Stahl db64c0467a
Small typo 2023-02-27 21:02:53 +01:00
Tim Visée ca52f84aa5 Merge branch 'master' into 'master'
Add build for arm64v8

See merge request timvisee/send!27
2023-02-22 11:40:25 +00:00
timvisee 6fff664947
Bump version to 3.4.23 2023-02-14 13:42:39 +01:00
timvisee 439ac0ab7c
Update dependencies 2023-02-14 13:41:10 +01:00
timvisee dee6b3e9cc
Merge branch 'tdulcet-passphrase' into master
See https://github.com/timvisee/send/pull/147
2023-02-14 13:38:30 +01:00
Teal Dulcet dc9d072472 Increased password length limit to support passphrases. 2023-02-14 04:36:19 -08:00
simepy 91773832c1 Updated from timvisee/send master 2023-02-03 14:29:30 +01:00
timvisee 65730db0db
Bump version to 3.4.22 2023-01-16 17:23:07 +01:00
timvisee a86221b1cc
Update dependencies 2023-01-16 17:00:14 +01:00
dependabot[bot] bcc53f73c6
Bump decode-uri-component from 0.2.0 to 0.2.2
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-11 11:27:01 +00:00
dependabot[bot] b0444f488b
Bump convict from 6.2.3 to 6.2.4
Bumps [convict](https://github.com/mozilla/node-convict) from 6.2.3 to 6.2.4.
- [Release notes](https://github.com/mozilla/node-convict/releases)
- [Changelog](https://github.com/mozilla/node-convict/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mozilla/node-convict/commits)

---
updated-dependencies:
- dependency-name: convict
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-10 22:22:09 +00:00
Tim Visée 70a11e5300 Merge branch 'reset-dlimit-to-default' into 'master'
Reset download limit to default after uploading files

See merge request timvisee/send!30
2023-01-10 20:50:13 +00:00
Jun Omae f62a99882d Reset download limit to default after uplaoding files 2023-01-06 17:42:45 +09:00
timvisee 309c7d63ac
Change GitLab CI test image to node 16, add missing packages for testing 2022-12-20 20:04:45 +01:00
dependabot[bot] 1d75366f66
Bump loader-utils from 1.4.1 to 1.4.2
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.2/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-18 00:43:28 +00:00
timvisee 0a849fb7c6
Revert "Bump node-forge and webpack-dev-server"
This reverts commit 88725df09d.
2022-11-14 19:43:09 +01:00
dependabot[bot] 88725df09d
Bump node-forge and webpack-dev-server
Bumps [node-forge](https://github.com/digitalbazaar/forge) to 1.3.1 and updates ancestor dependency [webpack-dev-server](https://github.com/webpack/webpack-dev-server). These dependencies need to be updated together.


Updates `node-forge` from 0.10.0 to 1.3.1
- [Release notes](https://github.com/digitalbazaar/forge/releases)
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/0.10.0...v1.3.1)

Updates `webpack-dev-server` from 3.11.3 to 4.11.1
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v3.11.3...v4.11.1)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-type: indirect
- dependency-name: webpack-dev-server
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-14 18:35:44 +00:00
dependabot[bot] 5a92e7e5e7
Bump minimatch and mocha
Bumps [minimatch](https://github.com/isaacs/minimatch) to 3.1.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `minimatch` from 3.0.4 to 3.1.2
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

Updates `mocha` from 6.2.3 to 10.1.0
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.2.3...v10.1.0)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-14 18:32:13 +00:00
dependabot[bot] 71541fc2b6
Bump loader-utils from 1.4.0 to 1.4.1
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.1/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.1)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-09 03:16:30 +00:00
Simon PERA c524804c63 Add build for arm64v8 2022-10-25 19:08:27 +02:00
timvisee 5b4c0d2540
Merge branch 'JoshAtticus-patch-1' into master
See https://github.com/timvisee/send/pull/115
2022-10-05 16:05:01 +02:00
Josh e7f3c91d0b
Update config.js 2022-09-19 15:46:47 +08:00
Josh 8bb198b73e
Remove firefox link 2022-09-17 12:33:03 +08:00
Tim Visée 9e188bc76c Merge branch 'registry-credentials' into 'master'
Refactor CI

See merge request timvisee/send!26
2022-09-14 14:37:33 +00:00
Marian Hähnlein 1353a54c49
Refactor CI 2022-09-12 13:53:00 +02:00
Tim Visée 4ae007167d Merge branch 'custom-css-undefined' into 'master'
Change default value for custom css to empty string

See merge request timvisee/send!25
2022-09-09 12:34:16 +00:00
Marian Hähnlein 660f36e584
Change default value for custom css to empty string 2022-09-08 14:16:00 +02:00
timvisee 3dede083cd
Bump version to 3.4.21 2022-09-04 12:48:04 +02:00
timvisee 26e81455ff
Update dependencies 2022-09-04 12:47:40 +02:00
timvisee 4ceac20623
Revert "Remove some polyfills"
This reverts commit 64644b57e3.
2022-09-04 12:26:12 +02:00
timvisee 073accfe65
Revert "Update eslint & plugins"
This reverts commit 38746b86fd.
2022-09-04 12:26:10 +02:00
timvisee 6306a433e8
Revert "More dependency cleanups"
This reverts commit e1d6224570.
2022-09-04 12:26:09 +02:00
timvisee 1da317bcc1
Revert "Further dependency cleanup"
This reverts commit 1725ff434e.
2022-09-04 12:26:07 +02:00
timvisee 08f597405c
Revert "Remove double-ended-queue"
This reverts commit 9b8b11ffc3.
2022-09-04 12:26:05 +02:00
timvisee c624766edc
Revert "Remove asmcrypto.js"
This reverts commit c619be58ae.
2022-09-04 12:26:03 +02:00
Tim Visée e030c46a9c Merge branch 'fix-csp' into 'master'
Fix CSP

Closes #29

See merge request timvisee/send!24
2022-08-22 15:27:03 +00:00
Marian Hähnlein d081affa38
Move injection of custom CSS from client to server 2022-08-19 13:17:59 +02:00
Marian Hähnlein 71372fcbc1
Replace tabs with spaces to maintain consistency 2022-08-19 13:11:30 +02:00
HrBingR 671390ca24 Added the ability for a user to define and set a custom locale
New environment variable CUSTOM_LOCALE allows a user to define a locale per the /public/locales directory (this should be listed in the docs, will create a pull request for that too).

If the environment variable is blank or invalid it reverts to previous behaviour of system + default locale. Fully tested the above as follows:

CUSTOM_LOCALE = 'nl' < This works correctly, translating to nl.
CUSTOM_LOCALE = 'HelloThere' < This reverts to previous behavior
CUSTOM_LOCALE = '' < Also reverts
#CUSTOM_LOCALE = < Also reverts
2022-08-13 02:25:19 +02:00
HrBingR 9221b86660
Merge branch 'timvisee:master' into master 2022-08-13 02:20:33 +02:00
HrBingR fd2e954b3e Updated docs to include custom CSS and custom footer. 2022-08-12 21:57:14 +02:00
timvisee c528ad3147
Merge branch 'HrBingR-master' into master
See https://github.com/timvisee/send/pull/103
2022-08-12 12:35:56 +02:00
HrBingR df9c7ea734
Merge branch 'timvisee:master' into master 2022-08-11 23:06:47 +02:00
HrBingR e32ea7d0aa Added the ability to define a custom footer via environment variables
Added the CUSTOM_FOOTER_TEXT and CUSTOM_FOOTER_URL environment variables.

If undefined, the default translated footer will display.

If only CUSTOM_FOOTER_TEXT is defined, only this defined text will display in place of the normal footer text.

If only CUSTOM_FOOTER_URL is defined then the defined URL will display.

If both variables are defined, the defined text will display as a link to the defined URL.
2022-08-11 23:04:45 +02:00
timvisee 55ad08fd96
Merge branch 'HrBingR-master' into master
See https://github.com/timvisee/send/pull/100
2022-08-11 10:07:14 +02:00
timvisee 96d53e4118
Merge branch 'master' of github.com:HrBingR/send into HrBingR-master 2022-08-11 10:06:45 +02:00
HrBingR bce861bcaf Added if check to see if user is using custom CSS 2022-08-10 22:55:51 +02:00
HrBingR 310271c10f Added new environment variables for custom css, custom title, and custom description.
Fully tested using the Dockerfile, example can be found on https://fileshare.thenextweb.co.za
2022-08-08 00:37:17 +02:00
35 changed files with 10125 additions and 7079 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -6,4 +6,4 @@ parserOptions:
sourceType: module sourceType: module
rules: rules:
n/no-unsupported-features: off node/no-unsupported-features: off

View File

@ -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;
} }

View File

@ -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
}; };

View File

@ -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']
); );
} }

View File

@ -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';

View File

@ -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) {

View File

@ -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));

View File

@ -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">

View File

@ -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}"

View File

@ -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"

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,4 @@
/* global window, document */ /* global window, document, fetch */
const MAXFILESIZE = 1024 * 1024 * 1024 * 2; const MAXFILESIZE = 1024 * 1024 * 1024 * 2;

16785
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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",

View File

@ -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

View File

@ -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

View File

@ -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 dont 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'
} }
} }
}); });

View File

@ -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 = {

View File

@ -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"

View File

@ -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'));
}); });

View File

@ -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 dont stay online forever.',
baseUrl, baseUrl,
ui: { ui: {
colors: { colors: {

View File

@ -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

View File

@ -5,4 +5,4 @@ parserOptions:
sourceType: module sourceType: module
rules: rules:
n/no-unsupported-features: off node/no-unsupported-features: off

View File

@ -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)),

View File

@ -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');

View File

@ -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 =

View File

@ -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');

View File

@ -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'
} }