Compare commits

..

23 Commits

Author SHA1 Message Date
timvisee
c01d6b73ea Bump version to 3.4.11 2021-05-19 12:04:52 +02:00
timvisee
a394fd995e Update dependencies 2021-05-19 12:04:21 +02:00
timvisee
175712cfbd Add REDIS_USER and REDIS_DB configuration variables
See https://github.com/timvisee/send/issues/23#issuecomment-843925819
2021-05-19 12:01:01 +02:00
timvisee
e5d7378fd9 Merge branch 'pirate-patch-3' into master
See https://github.com/timvisee/send/pull/36
2021-05-19 11:50:54 +02:00
timvisee
20cf722b54 Correctly parse config string values from int array 2021-05-19 11:48:20 +02:00
timvisee
1d6872e279 Merge branch 'master' into pirate-patch-3 2021-05-19 11:31:14 +02:00
Tim Visée
a1ca355771 Merge branch 'deploy' into 'master'
Documentation : full deployment example in AWS with Ubuntu 20.04

See merge request timvisee/send!16
2021-05-19 09:17:13 +00:00
David Dumas
dc816d0e59 Documentation: full deployment example in AWS with Ubuntu 20.04 2021-05-19 09:17:13 +00:00
Nick Sweeting
d6ac469e1a remove signup-cta and tweak console log wording to remove anon user references 2021-05-19 05:13:47 -04:00
timvisee
62cfecd618 Merge branch 'pirate-patch-2' into master
See https://github.com/timvisee/send/pull/35
2021-05-19 10:18:44 +02:00
timvisee
9152d22913 Merge branch 'patch-2' of https://github.com/pirate/send into pirate-patch-2 2021-05-19 10:18:26 +02:00
timvisee
21b198fbd5 Merge branch 'pirate-patch-1' into master
See https://github.com/timvisee/send/pull/34
2021-05-19 10:13:25 +02:00
Nick Sweeting
0ffc960523 add comments 2021-05-19 01:52:37 -04:00
Nick Sweeting
77ea05a233 also handle arrays of strings 2021-05-19 01:46:12 -04:00
Nick Sweeting
a6162f7142 fix indentation 2021-05-19 01:41:22 -04:00
Nick Sweeting
4a6a3dfc36 coerce DOWNLOAD_COUNTS and EXPIRE_TIMES_SECONDS into positive integer arrays 2021-05-19 01:39:14 -04:00
Nick Sweeting
1e7efe3d98 fix signup-ctas blocking render 2021-05-19 00:43:08 -04:00
Nick Sweeting
46381fd516 Fix glitchy UI dropdown select for max downloads and expiration 2021-05-19 00:35:53 -04:00
Nick Sweeting
1fe74f2be0 deny search engines to limit discoverability of public instances 2021-05-18 22:49:16 -04:00
Nick Sweeting
35da83bf2a improve README configuration list, example usage, and quickstart 2021-05-18 22:13:57 -04:00
timvisee
bcfb9c5d09 Update dependencies 2021-05-17 11:48:48 +02:00
timvisee
4df2578bb1 Merge branch 'dependabot/npm_and_yarn/hosted-git-info-2.8.9' into master 2021-05-16 15:58:54 +02:00
dependabot[bot]
e4f2955eae Bump hosted-git-info from 2.8.8 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-11 22:45:30 +00:00
13 changed files with 808 additions and 390 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
node_modules
coverage
dist
.env
.idea
.DS_Store
.nyc_output

View File

@@ -49,6 +49,7 @@ Cynthia Pereira
Daniel Thorn
Daniela Arcese
Danny Coates
David Dumas
Davide
Derek Tamsen
Dhyey Thakore

View File

@@ -81,7 +81,7 @@ A file sharing experiment which allows you to send encrypted files to other user
## Requirements
- [Node.js 12.x](https://nodejs.org/)
- [Node.js 15.x](https://nodejs.org/)
- [Redis server](https://redis.io/) (optional for development)
- [AWS S3](https://aws.amazon.com/s3/) or compatible service (optional)
@@ -141,6 +141,8 @@ Find a list of public instances here: https://github.com/timvisee/send-instances
See also [docs/deployment.md](docs/deployment.md)
AWS example using Ubuntu Server `20.04` [docs/AWS.md](docs/AWS.md)
---
## Clients

View File

@@ -9,6 +9,7 @@ module.exports = function(app = choo({ hash: true })) {
app.route('/unsupported/:reason', body(require('./ui/unsupported')));
app.route('/error', body(require('./ui/error')));
app.route('/blank', body(require('./ui/blank')));
app.route('/robots.txt', function() {return 'User-agent: * Disallow: /'});
app.route('/oauth', function(state, emit) {
emit('authenticate', state.query.code, state.query.state);
});

View File

@@ -31,12 +31,11 @@ module.exports = function(state, emit) {
counts,
num => state.translate('downloadCount', { num }),
value => {
const max = state.user.maxDownloads;
state.archive.dlimit = Math.min(value, max);
if (value > max) {
emit('signup-cta', 'count');
} else {
emit('render');
const selected = parseInt(value);
state.archive.dlimit = selected;
emit('render');
if (selected > parseInt(state.user.maxDownloads || '0')) {
console.log('Chosen max download count is larger than the allowed limit', selected)
}
},
'expire-after-dl-count-select'
@@ -58,12 +57,11 @@ module.exports = function(state, emit) {
return state.translate(l10n.id, l10n);
},
value => {
const max = state.user.maxExpireSeconds;
state.archive.timeLimit = Math.min(value, max);
if (value > max) {
emit('signup-cta', 'time');
} else {
emit('render');
const selected = parseInt(value);
state.archive.timeLimit = selected;
emit('render');
if (selected > parseInt(state.user.maxExpireSeconds || '0')) {
console.log('Chosen download expiration is larger than the allowed limit', selected)
}
},
'expire-after-time-select'

View File

@@ -1,32 +1,28 @@
const html = require('choo/html');
module.exports = function(selected, options, translate, changed, htmlId) {
let x = selected;
function choose(event) {
if (event.target.value != selected) {
console.log('Selected new value from dropdown', htmlId, ':', selected, '->', event.target.value)
changed(event.target.value);
}
}
return html`
<select
id="${htmlId}"
class="appearance-none cursor-pointer border rounded bg-grey-10 hover:border-blue-50 focus:border-blue-50 pl-1 pr-8 py-1 my-1 h-8 dark:bg-grey-80"
data-selected="${selected}"
onchange="${choose}"
>
${options.map(
i =>
value =>
html`
<option value="${i}" ${i === selected ? 'selected' : ''}
>${translate(i)}</option
>
<option value="${value}" ${value == selected ? 'selected' : ''}>
${translate(value)}
</option>
`
)}
</select>
`;
function choose(event) {
const target = event.target;
const value = +target.value;
if (x !== value) {
x = value;
changed(value);
}
}
};

236
docs/AWS.md Normal file
View File

@@ -0,0 +1,236 @@
# Deployment to AWS
This document describes how to do a deployment of Send in AWS
## AWS requirements
### Security groups (2)
* ALB:
- inbound: allow traffic from anywhere on port 80 and 443
- ountbound: allow traffic to the instance security group on port `8080`
* Instance:
- inbound: allow SSH from your public IP or a bastion (changing the default SSH port is a good idea)
- inbound: allow traffic from the ALB security group on port `8080`
- ountbound: allow all traffic to anywhere
### Resources
* An S3 bucket (block all public access)
* A private EC2 instance running Ubuntu `20.04` (you can use the [Amazon EC2 AMI Locator](https://cloud-images.ubuntu.com/locator/ec2/) to find the latest)
Attach an IAM role to the instance with the following inline policy:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"*"
],
"Effect": "Allow"
},
{
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads"
],
"Resource": [
"arn:aws:s3:::<s3_bucket_name>"
],
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:ListMultipartUploadParts",
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectVersion"
],
"Resource": [
"arn:aws:s3:::<s3_bucket_name>/*"
],
"Effect": "Allow"
}
]
}
```
* A public ALB:
- Create a target group with the instance registered (HTTP on port `8080` and path `/`)
- Configure HTTP (port 80) to redirect to HTTPS (port 443)
- HTTPS (port 443) using the latest security policy and an ACM certificate like `send.mydomain.com`
* A Route53 public record, alias from `send.mydomain.com` to the ALB
## Software requirements
* Git
* NodeJS `15.x` LTS
* Local Redis server
### Prerequisite packages
```bash
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
```
### Add repositories
* NodeJS `15.x` LTS (checkout [package.json](../package.json)):
```bash
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -
echo 'deb [arch=amd64] https://deb.nodesource.com/node_15.x focal main' | sudo tee /etc/apt/sources.list.d/nodejs.list
```
* Git (latest)
```bash
sudo add-apt-repository ppa:git-core/ppa
```
* Redis (latest)
```bash
sudo add-apt-repository ppa:redislabs/redis
```
### Install required packages
```bash
sudo apt update
sudo apt install git nodejs redis-server telnet
```
### Redis server
#### Password (optional)
Generate a strong password:
```bash
makepasswd --chars=100
```
Edit Redis configuration file `/etc/redis/redis.conf`:
```bash
requirepass <redis_password>
```
_Note: documentation on securing Redis https://redis.io/topics/security_
#### Systemd
Enable and (re)start the Redis server service:
```bash
sudo systemctl enable redis-server
sudo systemctl restart redis-server
sudo systemctl status redis-server
```
## Website directory
Setup a directory for the data
```
sudo mkdir -pv /var/www/send
sudo chown www-data:www-data /var/www/send
sudo 750 /var/www/send
```
### NodeJS
Update npm:
```bash
sudo npm install -g npm
```
Checkout current NodeJS and npm versions:
```bash
node --version
npm --version
```
Clone repository, install JavaScript packages and compiles the assets:
```bash
sudo su -l www-data -s /bin/bash
cd /var/www/send
git clone https://gitlab.com/timvisee/send.git .
npm install
npm run build
exit
```
Create the file `/var/www/send/.env` used by Systemd with your environment variables
(checkout [config.js](../server/config.js) for more configuration environment variables):
```
BASE_URL='https://send.mydomain.com'
NODE_ENV='production'
PORT='8080'
REDIS_PASSWORD='<redis_password>'
S3_BUCKET='<s3_bucket_name>'
```
Lower files and folders permissions to user and group `www-data`:
```
sudo find /var/www/send -type d -exec chmod 750 {} \;
sudo find /var/www/send -type f -exec chmod 640 {} \;
sudo chmod 750 /var/www/send/node_modules/.bin/*
```
### Systemd
Create the file `/etc/systemd/system/send.service` with `root` user and `644` mode:
```
[Unit]
Description=Send
After=network.target
Requires=redis-server.service
Documentation=https://gitlab.com/timvisee/send
[Service]
Type=simple
ExecStart=/usr/bin/npm run prod
EnvironmentFile=/var/www/send/.env
WorkingDirectory=/var/www/send
User=www-data
Group=www-data
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
_Note: could be better tuner to secure the service by restricting system permissions,
check with `systemd-analyze security send`_
Enable and start the Send service, check logs:
```
sudo systemctl daemon-reload
sudo systemctl enable send
sudo systemctl start send
sudo systemctl status send
journalctl -fu send
```

View File

@@ -1,16 +1,20 @@
## Requirements
This document describes how to do a full deployment of Send on your own Linux server. You will need:
* A working (and ideally somewhat recent) installation of NodeJS and NPM
* GIT
* An Apache webserver
* A working (and ideally somewhat recent) installation of NodeJS and npm
* Git
* Apache webserver
* Optionally telnet, to be able to quickly check your installation
For Debian/Ubuntu systems this probably just means something like this:
For example in Debian/Ubuntu systems:
* apt install git apache2 nodejs npm telnet
```bash
sudo apt install git apache2 nodejs npm telnet
```
## Building
* We assume an already configured virtual-host on your webserver with an existing empty htdocs folder
* First, remove that htdocs folder - we will replace it with Send's version now
* git clone https://github.com/timvisee/send.git htdocs
@@ -19,51 +23,74 @@ For Debian/Ubuntu systems this probably just means something like this:
* npm run build
## Running
To have a permanently running version of Send as a background process:
* Create a file "run.sh" with:
```
* Create a file `run.sh` with:
```bash
#!/bin/bash
nohup su www-data -c "npm run prod" 2>/dev/null &
```
* chmod +x run.sh
* ./run.sh
* Execute the script:
```bash
chmod +x run.sh
./run.sh
```
Now the Send backend should be running on port 1443. You can check with:
* telnet localhost 1443
```bash
telnet localhost 1443
```
## Reverse Proxy
Of course, we don't want to expose the service on port 1443. Instead we want our normal webserver to forward all requests to Send ("Reverse proxy").
# Apache webserver
* a2enmod proxy
* a2enmod proxy_http
* a2enmod proxy_wstunnel
* a2enmod rewrite
* Enable Apache required modules:
In your Apache virtual host configuration file, insert this:
```bash
sudo a2enmod headers
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
sudo a2enmod rewrite
```
* Edit your Apache virtual host configuration file, insert this:
```
# Enable rewrite engine
RewriteEngine on
# Enable rewrite engine
RewriteEngine on
# Make sure the original domain name is forwarded to Send
# Otherwise the generated URLs will be wrong
ProxyPreserveHost on
# Make sure the original domain name is forwarded to Send
# Otherwise the generated URLs will be wrong
ProxyPreserveHost on
# Make sure the generated URL is https://
RequestHeader set X-Forwarded-Proto https
# Make sure the generated URL is https://
RequestHeader set X-Forwarded-Proto https
# If it's a normal file (e.g. PNG, CSS) just return it
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [L]
# If it's a normal file (e.g. PNG, CSS) just return it
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [L]
# If it's a websocket connection, redirect it to a Send WS connection
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:1443/$1 [P,L]
# If it's a websocket connection, redirect it to a Send WS connection
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:1443/$1 [P,L]
# Otherwise redirect it to a normal HTTP connection
RewriteRule ^/(.*)$ http://127.0.0.1:1443/$1 [P,QSA]
ProxyPassReverse "/" "http://127.0.0.1:1443"
# Otherwise redirect it to a normal HTTP connection
RewriteRule ^/(.*)$ http://127.0.0.1:1443/$1 [P,QSA]
ProxyPassReverse "/" "http://127.0.0.1:1443"
```
* Test configuration and restart Apache:
```bash
sudo apache2ctl configtest
sudo systemctl restart apache2
```

View File

@@ -1,45 +1,119 @@
## Setup
## Docker Quickstart
Use `registry.gitlab.com/timvisee/send:latest` from [`timvisee/send`'s registry](https://gitlab.com/timvisee/send/container_registry) for the latest Docker image.
Use `registry.gitlab.com/timvisee/send:latest` from [`timvisee/send`'s Gitlab image registry](https://gitlab.com/timvisee/send/container_registry) for the latest Docker image.
```bash
docker pull registry.gitlab.com/timvisee/send:latest
# example quickstart (point REDIS_HOST to an already-running redis server)
docker run -v $PWD/uploads:/uploads -p 1443:1443 \
-e 'DETECT_BASE_URL=true' \
-e 'REDIS_HOST=localhost' \
registry.gitlab.com/timvisee/send:latest
```
Or run `docker build -t send:latest .` to create an image locally or `docker-compose up` to run a full testable stack. *We don't recommend using docker-compose for production.*
Or clone this repo and run `docker build -t send:latest .` to build an image locally.
## Environment variables:
*Note: for Docker Compose, see: https://github.com/timvisee/send-docker-compose*
| Name | Description
## Environment Variables
All the available config options and their defaults can be found here: https://github.com/timvisee/send/blob/master/server/config.js
Config options should be set as unquoted environment variables. Boolean options should be `true`/`false`, time/duration should be integers (seconds), and filesize values should be integers (bytes).
Config options expecting array values (e.g. `EXPIRE_TIMES_SECONDS`, `DOWNLOAD_COUNTS`) should be in unquoted CSV format. UI dropdowns will default to the first value in the CSV, e.g. `DOWNLOAD_COUNTS=5,1,10,100` will show four dropdown options, with `5` selected by the default.
#### Server Configuration
| Name | Description |
|------------------|-------------|
| `BASE_URL` | The HTTPS URL where traffic will be served (e.g. `https://send.firefox.com`)
| `PORT` | Port the server will listen on (defaults to 1443).
| `NODE_ENV` | `"production"`
| `FILE_DIR` | Uploads directory for local storage
| `S3_BUCKET` | The S3 bucket name.
| `S3_ENDPOINT`| Optional custom S3 endpoint host.
| `S3_USE_PATH_STYLE_ENDPOINTS`| `true` or `false`
| `AWS_ACCESS_KEY_ID` | S3 access key ID
| `AWS_SECRET_ACCESS_KEY` | S3 secret access key ID
| `MAX_FILE_SIZE` | Maximum upload file size in bytes (defaults to 2147483648)
| `MAX_EXPIRE_SECONDS` | Maximum upload expiry time in seconds (defaults to 604800)
| `REDIS_HOST` | Host name of the Redis server.
| `SENTRY_CLIENT` | Sentry Client ID
| `SENTRY_DSN` | Sentry DSN
| `DETECT_BASE_URL` | Autodetect the base URL using browser if `BASE_URL` is unset (defaults to `false`)
| `PORT` | Port the server will listen on (defaults to `1443`)
| `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)
| `SENTRY_CLIENT`, `SENTRY_DSN` | Sentry Client ID and DNS for error tracking (optional, disabled by default)
## Example:
*Note: more options can be found here: https://github.com/timvisee/send/blob/master/server/config.js*
#### Upload and Download Limits
Configure the limits for uploads and downloads. Long expiration times are risky on public servers as people may use you as free hosting for copyrighted content or malware (which is why Mozilla shut down their `send` service). It's advised to only expose your service on a LAN/intranet, password protect it with a proxy/gateway, or make sure to set `SEND_FOOTER_DMCA_URL` above so you can respond to takedown requests.
| Name | Description |
|------------------|-------------|
| `MAX_FILE_SIZE` | Maximum upload file size in bytes (defaults to `2147483648` aka 2GB)
| `MAX_FILES_PER_ARCHIVE` | Maximum number of files per archive (defaults to `64`)
| `MAX_EXPIRE_SECONDS` | Maximum upload expiry time in seconds (defaults to `604800` aka 7 days)
| `MAX_DOWNLOADS` | Maximum number of downloads (defaults to `100`)
| `DOWNLOAD_COUNTS` | Download limit options to show in UI dropdown, e.g. `10,1,2,5,10,15,25,50,100,1000`
| `EXPIRE_TIMES_SECONDS` | Expire time options to show in UI dropdown, e.g. `3600,86400,604800,2592000,31536000`
*Note: more options can be found here: https://github.com/timvisee/send/blob/master/server/config.js*
#### Storage Backend Options
Pick how you want to store uploaded files and set these config options accordingly:
- Local filesystem (the default): set `FILE_DIR` to the local path used inside the container for storage (or leave the default)
- S3-compatible object store: set `S3_BUCKET`, `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` (and `S3_ENDPOINT` if using something other than AWS)
- Google Cloud Storage: set `GCS_BUCKET` to the name of a GCS bucket (auth should be set up using [Application Default Credentials](https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-nodejs))
Redis is used as the metadata database for the backend and is required no matter which storage method you use.
| Name | Description |
|------------------|-------------|
| `REDIS_HOST`, `REDIS_PORT`, `REDIS_USER`, `REDIS_PASSWORD`, `REDIS_DB` | Host name, port, and pass of the Redis server (defaults to `localhost`, `6379`, and no password)
| `FILE_DIR` | Directory for storage inside the Docker container (defaults to `/uploads`)
| `S3_BUCKET` | The S3 bucket name to use (only set if using S3 for storage)
| `S3_ENDPOINT` | An optional custom endpoint to use for S3 (defaults to AWS)
| `S3_USE_PATH_STYLE_ENDPOINT`| Whether to force [path style URLs](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html#s3ForcePathStyle-property) for S3 objects (defaults to `false`)
| `AWS_ACCESS_KEY_ID` | S3 access key ID (only set if using S3 for storage)
| `AWS_SECRET_ACCESS_KEY` | S3 secret access key ID (only set if using S3 for storage)
| `GCS_BUCKET` | Google Cloud Storage bucket (only set if using GCP for storage)
*Note: more options can be found here: https://github.com/timvisee/send/blob/master/server/config.js*
## Examples
**Run using an Amazon Elasticache for the Redis DB, Amazon S3 for the storage backend, and Sentry for error reporting.**
```bash
$ docker run --net=host -e 'NODE_ENV=production' \
$ docker run -p 1443:1443 \
-e 'S3_BUCKET=testpilot-p2p-dev' \
-e 'REDIS_HOST=dyf9s2r4vo3.bolxr4.0001.usw2.cache.amazonaws.com' \
-e 'SENTRY_CLIENT=https://51e23d7263e348a7a3b90a5357c61cb2@sentry.prod.mozaws.net/168' \
-e 'SENTRY_DSN=https://51e23d7263e348a7a3b90a5357c61cb2:65e23d7263e348a7a3b90a5357c61c44@sentry.prod.mozaws.net/168' \
-e 'BASE_URL=https://send.firefox.com' \
-e 'BASE_URL=https://send.example.com' \
registry.gitlab.com/timvisee/send:latest
```
## Docker compose
*Note: make sure to replace the example values above with your real values before running.*
**Run totally self-hosted using the current filesystem directry (`$PWD`) to store the Redis data and file uploads, with a `5GB` upload limit, 1 month expiry, and contact URL set.**
```bash
# create a network for the send backend and redis containers to talk to each other
$ docker network create timviseesend
# start the redis container
$ docker run --net=timviseesend -v $PWD/redis:/data redis-server --appendonly yes
# start the send backend container
$ docker run --net=timviseesend -v $PWD/uploads:/uploads -p 1443:1443 \
-e 'BASE_URL=http://localhost:1443' \
-e 'MAX_FILE_SIZE=5368709120' \
-e 'MAX_EXPIRE_SECONDS=2592000' \
-e 'SEND_FOOTER_DMCA_URL=https://example.com/dmca-contact-info' \
registry.gitlab.com/timvisee/send:latest
```
Then open http://localhost:1443 to view the UI. (change the `localhost` to your IP or hostname above to serve the UI to others)
To run with HTTPS, you will need to set up a reverse proxy with SSL termination in front of the backend. See Docker Compose below for an example setup.
## Docker Compose
For a Docker compose configuration example, see:

650
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "send",
"description": "File Sharing Experiment",
"version": "3.4.10",
"version": "3.4.11",
"author": "Mozilla (https://mozilla.org)",
"contributors": [
"Tim Visee <3a4fb3964f@sinenomine.email> (https://timvisee.com)"
@@ -64,10 +64,10 @@
"node": "^15.5.1"
},
"devDependencies": {
"@babel/core": "^7.14.0",
"@babel/core": "^7.14.3",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.14.1",
"@babel/preset-env": "^7.14.2",
"@dannycoates/webcrypto-liner": "^0.1.37",
"@fullhuman/postcss-purgecss": "^1.3.0",
"@mattiasbuelens/web-streams-polyfill": "0.2.1",
@@ -78,7 +78,7 @@
"base64-js": "^1.5.1",
"content-disposition": "^0.5.3",
"copy-webpack-plugin": "^5.1.2",
"core-js": "^3.12.0",
"core-js": "^3.12.1",
"crc": "^3.8.0",
"cross-env": "^6.0.3",
"css-loader": "^3.6.0",
@@ -137,7 +137,7 @@
"@fluent/langneg": "^0.3.0",
"@google-cloud/storage": "^5.8.5",
"@sentry/node": "^5.30.0",
"aws-sdk": "^2.902.0",
"aws-sdk": "^2.909.0",
"body-parser": "^1.19.0",
"choo": "^7.0.0",
"cldr-core": "^35.1.0",

View File

@@ -3,6 +3,26 @@ const { tmpdir } = require('os');
const path = require('path');
const { randomBytes } = require('crypto');
convict.addFormat({
name: 'positive-int-array',
coerce: ints => {
// can take: int[] | string[] | string (csv), returns -> int[]
const ints_arr = Array.isArray(ints) ? ints : ints.trim().split(',');
return ints_arr.map(int =>
typeof int === 'number'
? int
: parseInt(int.replace(/['"]+/g, '').trim(), 10)
);
},
validate: ints => {
// takes: int[], errors if any NaNs, negatives, or floats present
for (const int of ints) {
if (typeof int !== 'number' || isNaN(int) || int < 0 || int % 1 > 0)
throw new Error('must be a comma-separated list of positive integers');
}
}
});
const conf = convict({
s3_bucket: {
format: String,
@@ -25,7 +45,7 @@ const conf = convict({
env: 'GCS_BUCKET'
},
expire_times_seconds: {
format: Array,
format: 'positive-int-array',
default: [300, 3600, 86400, 604800],
env: 'EXPIRE_TIMES_SECONDS'
},
@@ -40,7 +60,7 @@ const conf = convict({
env: 'MAX_EXPIRE_SECONDS'
},
download_counts: {
format: Array,
format: 'positive-int-array',
default: [1, 2, 3, 4, 5, 20, 50, 100],
env: 'DOWNLOAD_COUNTS'
},
@@ -69,11 +89,21 @@ const conf = convict({
default: 6379,
env: 'REDIS_PORT'
},
redis_user: {
format: String,
default: '',
env: 'REDIS_USER'
},
redis_password: {
format: String,
default: '',
env: 'REDIS_PASSWORD'
},
redis_db: {
format: String,
default: '',
env: 'REDIS_DB'
},
redis_event_expire: {
format: Boolean,
default: false,

View File

@@ -21,8 +21,12 @@ module.exports = function(config) {
return config.redis_retry_delay;
}
};
if (config.redis_user != null && config.redis_user.length > 0)
client_config.user = config.redis_user;
if (config.redis_password != null && config.redis_password.length > 0)
client_config.password = config.redis_password;
if (config.redis_db != null && config.redis_db.length > 0)
client_config.db = config.redis_db;
const client = redis.createClient(client_config);
client.ttlAsync = promisify(client.ttl);