Compare commits
76 Commits
v3.4.20
...
chapril-v3
Author | SHA1 | Date |
---|---|---|
Romain H | 8f8f2b9909 | |
Romain H | 669eedbf03 | |
Romain H | 59a0c99142 | |
Christian P. MOMON | 55afcd2ce7 | |
Christian P. MOMON | 83e0ae6303 | |
Christian P. MOMON | d948e8efc7 | |
Christian P. MOMON | deb795625c | |
Christian P. MOMON | 898e9742c9 | |
Christian P. MOMON | 9cb706fa73 | |
timvisee | 6fff664947 | |
timvisee | 439ac0ab7c | |
timvisee | dee6b3e9cc | |
Teal Dulcet | dc9d072472 | |
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 | |
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 | |
timvisee | 643287e235 | |
AaronDewes | c619be58ae | |
AaronDewes | 9b8b11ffc3 | |
AaronDewes | 1725ff434e | |
AaronDewes | e1d6224570 | |
AaronDewes | 38746b86fd | |
AaronDewes | 64644b57e3 | |
timvisee | 625fdf5bca | |
AaronDewes | 951c613095 | |
AaronDewes | 16e78847a2 | |
HrBingR | 310271c10f | |
AaronDewes | 55344f8a9d | |
AaronDewes | 2b22e8cd05 | |
AaronDewes | 47ff32fc9f | |
AaronDewes | b598a1c090 | |
AaronDewes | 3ae9e6adeb | |
AaronDewes | 33e7e0f5ba | |
AaronDewes | ca3b5cf7ca | |
AaronDewes | 44a25e4156 | |
timvisee | 000854104f | |
Nam PHAM | 1a0ddf9a05 | |
dependabot[bot] | 0ac1eeed2c | |
dependabot[bot] | 2457545502 | |
dependabot[bot] | 75637807eb |
137
.gitlab-ci.yml
137
.gitlab-ci.yml
|
@ -1,105 +1,72 @@
|
|||
image: "node:15-slim"
|
||||
|
||||
stages:
|
||||
- test
|
||||
- artifact
|
||||
- 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
|
||||
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:
|
||||
- npm ci
|
||||
- npm run lint
|
||||
- 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:
|
||||
stage: release
|
||||
image: docker:latest
|
||||
dependencies:
|
||||
- artifact-docker
|
||||
services:
|
||||
- docker:dind
|
||||
only:
|
||||
- /^v(\d+\.)*\d+$/
|
||||
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:$CI_COMMIT_REF_NAME"
|
||||
IMG_NAME_LATEST: "registry.gitlab.com/timvisee/send:latest"
|
||||
before_script: []
|
||||
- api
|
||||
- branches
|
||||
- chat
|
||||
- merge_requests
|
||||
- pushes
|
||||
- schedules
|
||||
- tags
|
||||
- triggers
|
||||
- web
|
||||
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
|
||||
- docker tag $IMG_IMPORT_NAME $IMG_NAME_LATEST
|
||||
|
||||
# Publish tagged image
|
||||
- docker push $IMG_NAME
|
||||
- docker push $IMG_NAME_LATEST
|
||||
|
||||
- 'echo "Docker image artifact published, available as:" && echo " docker pull $IMG_NAME_LATEST" && echo " docker pull $IMG_NAME"'
|
||||
- docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
|
||||
- docker build -t send .
|
||||
- |
|
||||
if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then
|
||||
IMAGE_NAMES="$CI_REGISTRY_IMAGE/mr:$CI_MERGE_REQUEST_IID"
|
||||
elif [ "$CI_COMMIT_TAG" != "" ]; then
|
||||
IMAGE_NAMES="$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG $CI_REGISTRY_IMAGE:latest"
|
||||
else
|
||||
IMAGE_NAMES="$CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHORT_SHA"
|
||||
fi
|
||||
- |
|
||||
for image in $IMAGE_NAMES; do
|
||||
docker tag send $image
|
||||
docker push $image
|
||||
done
|
||||
- |
|
||||
echo "Container image pushed. You can pull it with";
|
||||
for image in $IMAGE_NAMES; do
|
||||
echo "docker pull $image"
|
||||
done
|
||||
|
|
|
@ -11,3 +11,5 @@ rules:
|
|||
selector-list-comma-newline-after: null
|
||||
value-list-comma-newline-after: null
|
||||
at-rule-no-unknown: null
|
||||
# Conflicts with prettier
|
||||
string-quotes: null
|
||||
|
|
|
@ -152,7 +152,7 @@ AWS example using Ubuntu Server `20.04`: [docs/AWS.md](docs/AWS.md)
|
|||
- Web: _this repository_
|
||||
- Command-line: [`ffsend`](https://github.com/timvisee/ffsend)
|
||||
- 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
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ export default class Archive {
|
|||
constructor(files = [], defaultTimeLimit = 86400, defaultDownloadLimit = 1) {
|
||||
this.files = Array.from(files);
|
||||
this.defaultTimeLimit = defaultTimeLimit;
|
||||
this.defaultDownloadLimit = defaultDownloadLimit;
|
||||
this.timeLimit = defaultTimeLimit;
|
||||
this.dlimit = defaultDownloadLimit;
|
||||
this.password = null;
|
||||
|
@ -76,7 +77,7 @@ export default class Archive {
|
|||
|
||||
clear() {
|
||||
this.files = [];
|
||||
this.dlimit = 1;
|
||||
this.dlimit = 100;
|
||||
this.timeLimit = this.defaultTimeLimit;
|
||||
this.password = null;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { FluentBundle } from '@fluent/bundle';
|
||||
import { FluentBundle, FluentResource } from '@fluent/bundle';
|
||||
|
||||
function makeBundle(locale, ftl) {
|
||||
const bundle = new FluentBundle(locale, { useIsolating: false });
|
||||
bundle.addMessages(ftl);
|
||||
bundle.addResource(new FluentResource(ftl));
|
||||
return bundle;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ export async function getTranslator(locale) {
|
|||
return function(id, data) {
|
||||
for (let bundle of bundles) {
|
||||
if (bundle.hasMessage(id)) {
|
||||
return bundle.format(bundle.getMessage(id), data);
|
||||
return bundle.formatPattern(bundle.getMessage(id).value, data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
41
app/main.css
41
app/main.css
|
@ -7,17 +7,14 @@ html {
|
|||
@tailwind components;
|
||||
|
||||
:not(input) {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
:root {
|
||||
--violet-gradient: linear-gradient(
|
||||
-180deg,
|
||||
rgba(144, 89, 255, 0.8) 0%,
|
||||
rgba(144, 89, 255, 0.4) 100%
|
||||
rgb(144 89 255 / 80%) 0%,
|
||||
rgb(144 89 255 / 40%) 100%
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -71,7 +68,7 @@ body {
|
|||
|
||||
.checkbox > label::before {
|
||||
/* @apply bg-grey-10; */
|
||||
@apply border;
|
||||
@apply border-default;
|
||||
@apply rounded-sm;
|
||||
|
||||
content: '';
|
||||
|
@ -204,19 +201,18 @@ progress::-webkit-progress-value {
|
|||
background-image: -webkit-linear-gradient(
|
||||
-45deg,
|
||||
transparent 20%,
|
||||
rgba(255, 255, 255, 0.4) 20%,
|
||||
rgba(255, 255, 255, 0.4) 40%,
|
||||
rgb(255 255 255 / 40%) 20%,
|
||||
rgb(255 255 255 / 40%) 40%,
|
||||
transparent 40%,
|
||||
transparent 60%,
|
||||
rgba(255, 255, 255, 0.4) 60%,
|
||||
rgba(255, 255, 255, 0.4) 80%,
|
||||
rgb(255 255 255 / 40%) 60%,
|
||||
rgb(255 255 255 / 40%) 80%,
|
||||
transparent 80%
|
||||
),
|
||||
-webkit-linear-gradient(left, var(--color-primary), var(--color-primary));
|
||||
/* stylelint-enable */
|
||||
border-radius: 2px;
|
||||
background-size: 21px 20px, 100% 100%, 100% 100%;
|
||||
-webkit-animation: animate-stripes 1s linear infinite;
|
||||
}
|
||||
|
||||
progress::-moz-progress-bar {
|
||||
|
@ -224,12 +220,12 @@ progress::-moz-progress-bar {
|
|||
background-image: -moz-linear-gradient(
|
||||
135deg,
|
||||
transparent 20%,
|
||||
rgba(255, 255, 255, 0.4) 20%,
|
||||
rgba(255, 255, 255, 0.4) 40%,
|
||||
rgb(255 255 255 / 40%) 20%,
|
||||
rgb(255 255 255 / 40%) 40%,
|
||||
transparent 40%,
|
||||
transparent 60%,
|
||||
rgba(255, 255, 255, 0.4) 60%,
|
||||
rgba(255, 255, 255, 0.4) 80%,
|
||||
rgb(255 255 255 / 40%) 60%,
|
||||
rgb(255 255 255 / 40%) 80%,
|
||||
transparent 80%
|
||||
),
|
||||
-moz-linear-gradient(left, var(--color-primary), var(--color-primary));
|
||||
|
@ -239,12 +235,6 @@ progress::-moz-progress-bar {
|
|||
animation: animate-stripes 1s linear infinite;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animate-stripes {
|
||||
100% {
|
||||
background-position: -21px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animate-stripes {
|
||||
100% {
|
||||
background-position: -21px 0;
|
||||
|
@ -313,7 +303,7 @@ select {
|
|||
|
||||
@screen md {
|
||||
.main > section {
|
||||
@apply border;
|
||||
@apply border-default;
|
||||
@apply border-grey-80;
|
||||
}
|
||||
}
|
||||
|
@ -323,13 +313,12 @@ select {
|
|||
|
||||
@responsive {
|
||||
.shadow-light {
|
||||
box-shadow: 0 0 8px 0 rgba(12, 12, 13, 0.1);
|
||||
box-shadow: 0 0 8px 0 rgb(12 12 13 / 10%);
|
||||
}
|
||||
|
||||
.shadow-big {
|
||||
box-shadow: 0 12px 18px 2px rgba(34, 0, 51, 0.04),
|
||||
0 6px 22px 4px rgba(7, 48, 114, 0.12),
|
||||
0 6px 10px -4px rgba(14, 13, 26, 0.12);
|
||||
box-shadow: 0 12px 18px 2px rgb(34 0 51 / 4%),
|
||||
0 6px 22px 4px rgb(7 48 114 / 12%), 0 6px 10px -4px rgb(14 13 26 / 12%);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,13 +83,13 @@ class Account extends Component {
|
|||
<input
|
||||
type="image"
|
||||
alt="${user.email}"
|
||||
class="w-8 h-8 rounded-full border text-primary md:text-white focus:outline"
|
||||
class="w-8 h-8 rounded-full border-default text-primary md:text-white focus:outline"
|
||||
src="${user.avatar}"
|
||||
onclick="${e => this.avatarClick(e)}"
|
||||
/>
|
||||
<ul
|
||||
id="accountMenu"
|
||||
class="invisible absolute top-0 right-0 mt-10 pt-2 pb-2 bg-white shadow-md whitespace-no-wrap outline-none z-50 dark:bg-grey-80"
|
||||
class="invisible absolute top-0 right-0 mt-10 pt-2 pb-2 bg-white shadow-md whitespace-nowrap outline-none z-50 dark:bg-grey-80"
|
||||
onblur="${e => this.hideMenu(e)}"
|
||||
>
|
||||
<li class="p-2 text-grey-60 dark:text-grey-50">${user.email}</li>
|
||||
|
|
|
@ -26,7 +26,7 @@ function expiryInfo(translate, archive) {
|
|||
}
|
||||
|
||||
function password(state) {
|
||||
const MAX_LENGTH = 32;
|
||||
const MAX_LENGTH = 4096;
|
||||
|
||||
return html`
|
||||
<div class="mb-2 px-1">
|
||||
|
@ -53,7 +53,7 @@ function password(state) {
|
|||
id="password-input"
|
||||
class="${state.archive.password
|
||||
? ''
|
||||
: 'invisible'} border rounded focus:border-primary leading-normal my-1 py-1 px-2 h-8 dark:bg-grey-80"
|
||||
: 'invisible'} border-default rounded-default focus:border-primary leading-normal my-1 py-1 px-2 h-8 dark:bg-grey-80"
|
||||
autocomplete="off"
|
||||
maxlength="${MAX_LENGTH}"
|
||||
type="password"
|
||||
|
@ -261,7 +261,7 @@ module.exports = function(state, emit, archive) {
|
|||
return html`
|
||||
<send-archive
|
||||
id="archive-${archive.id}"
|
||||
class="flex flex-col items-start rounded shadow-light bg-white p-4 w-full dark:bg-grey-90 dark:border dark:border-grey-70"
|
||||
class="flex flex-col items-start rounded-default shadow-light bg-white p-4 w-full dark:bg-grey-90 dark:border-default dark:border-grey-70"
|
||||
>
|
||||
${archiveInfo(
|
||||
archive,
|
||||
|
@ -335,7 +335,7 @@ module.exports.wip = function(state, emit) {
|
|||
fileInfo(f, remove(f, state.translate('deleteButtonHover')))
|
||||
),
|
||||
'flex-shrink bg-grey-10 rounded-t overflow-y-auto px-6 py-4 md:h-full md:max-h-half-screen dark:bg-black',
|
||||
'bg-white px-2 my-2 shadow-light rounded dark:bg-grey-90 dark:border dark:border-grey-80'
|
||||
'bg-white px-2 my-2 shadow-light rounded-default dark:bg-grey-90 dark:border-default dark:border-grey-80'
|
||||
)}
|
||||
<div
|
||||
class="flex-shrink-0 flex-grow flex items-end p-4 bg-grey-10 rounded-b mb-1 font-medium dark:bg-grey-90"
|
||||
|
@ -438,7 +438,7 @@ module.exports.uploading = function(state, emit) {
|
|||
return html`
|
||||
<send-upload-area
|
||||
id="${archive.id}"
|
||||
class="flex flex-col items-start rounded shadow-light bg-white p-4 w-full dark:bg-grey-90"
|
||||
class="flex flex-col items-start rounded-default shadow-light bg-white p-4 w-full dark:bg-grey-90"
|
||||
>
|
||||
${archiveInfo(archive)}
|
||||
<div class="text-xs opacity-75 w-full mt-2 mb-2">
|
||||
|
@ -488,7 +488,7 @@ module.exports.empty = function(state, emit) {
|
|||
`;
|
||||
return html`
|
||||
<send-upload-area
|
||||
class="flex flex-col items-center justify-center border-2 border-dashed border-grey-transparent rounded px-6 py-16 h-full w-full dark:border-grey-60"
|
||||
class="flex flex-col items-center justify-center border-2 border-dashed border-grey-transparent rounded-default px-6 py-16 h-full w-full dark:border-grey-60"
|
||||
onclick="${e => {
|
||||
if (e.target.tagName !== 'LABEL') {
|
||||
document.getElementById('file-upload').click();
|
||||
|
@ -563,7 +563,7 @@ module.exports.preview = function(state, emit) {
|
|||
<send-archive
|
||||
class="flex flex-col max-h-full bg-white p-4 w-full md:w-128 dark:bg-grey-90"
|
||||
>
|
||||
<div class="border rounded py-3 px-6 dark:border-grey-70">
|
||||
<div class="border-default rounded-default py-3 px-6 dark:border-grey-70">
|
||||
${archiveInfo(archive)} ${details}
|
||||
</div>
|
||||
<button
|
||||
|
@ -590,7 +590,7 @@ module.exports.downloading = function(state) {
|
|||
const progressPercent = percent(progress);
|
||||
return html`
|
||||
<send-archive
|
||||
class="flex flex-col bg-white rounded shadow-light p-4 w-full max-w-sm md:w-128 dark:bg-grey-90"
|
||||
class="flex flex-col bg-white rounded-default shadow-light p-4 w-full max-w-sm md:w-128 dark:bg-grey-90"
|
||||
>
|
||||
${archiveInfo(archive)}
|
||||
<div class="link-primary text-sm font-medium mt-2">
|
||||
|
|
|
@ -21,7 +21,7 @@ module.exports = function(name, url) {
|
|||
<input
|
||||
type="text"
|
||||
id="share-url"
|
||||
class="block w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80"
|
||||
class="block w-full my-4 border-default rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80"
|
||||
value="${url}"
|
||||
readonly="true"
|
||||
/>
|
||||
|
|
|
@ -17,7 +17,7 @@ module.exports = function(state, emit) {
|
|||
${state.translate('downloadDescription')}
|
||||
</p>
|
||||
<form
|
||||
class="flex flex-row flex-no-wrap w-full md:w-4/5"
|
||||
class="flex flex-row flex-nowrap w-full md:w-4/5"
|
||||
onsubmit="${checkPassword}"
|
||||
data-no-csrf
|
||||
>
|
||||
|
@ -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
|
||||
? 'border-red dark:border-red-40'
|
||||
: 'border-grey'} leading-loose px-2 py-1 dark:bg-grey-80"
|
||||
maxlength="32"
|
||||
maxlength="4096"
|
||||
autocomplete="off"
|
||||
placeholder="${state.translate('unlockInputPlaceholder')}"
|
||||
oninput="${inputChanged}"
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
const html = require('choo/html');
|
||||
const Component = require('choo/component');
|
||||
const version = require('../../package.json').version;
|
||||
/*const { browserName } = require('../utils');*/
|
||||
|
||||
class Footer extends Component {
|
||||
constructor(name, state) {
|
||||
|
@ -12,73 +14,18 @@ class Footer extends Component {
|
|||
}
|
||||
|
||||
createElement() {
|
||||
const translate = this.state.translate;
|
||||
|
||||
// Add additional links from configuration if available
|
||||
var links = [];
|
||||
if (this.state != undefined && this.state.WEB_UI != undefined) {
|
||||
const WEB_UI = this.state.WEB_UI;
|
||||
|
||||
if (WEB_UI.FOOTER_DONATE_URL != '') {
|
||||
links.push(html`
|
||||
<li class="m-2">
|
||||
<a href="${WEB_UI.FOOTER_DONATE_URL}" target="_blank">
|
||||
${translate('footerLinkDonate')}
|
||||
</a>
|
||||
</li>
|
||||
`);
|
||||
}
|
||||
if (WEB_UI.FOOTER_CLI_URL != '') {
|
||||
links.push(html`
|
||||
<li class="m-2">
|
||||
<a href="${WEB_UI.FOOTER_CLI_URL}" target="_blank">
|
||||
${translate('footerLinkCli')}
|
||||
</a>
|
||||
</li>
|
||||
`);
|
||||
}
|
||||
if (WEB_UI.FOOTER_DMCA_URL != '') {
|
||||
links.push(html`
|
||||
<li class="m-2">
|
||||
<a href="${WEB_UI.FOOTER_DMCA_URL}" target="_blank">
|
||||
${translate('footerLinkDmca')}
|
||||
</a>
|
||||
</li>
|
||||
`);
|
||||
}
|
||||
if (WEB_UI.FOOTER_SOURCE_URL != '') {
|
||||
links.push(html`
|
||||
<li class="m-2">
|
||||
<a href="${WEB_UI.FOOTER_SOURCE_URL}" target="_blank">
|
||||
${translate('footerLinkSource')}
|
||||
</a>
|
||||
</li>
|
||||
`);
|
||||
}
|
||||
} else {
|
||||
links.push(html`
|
||||
<li class="m-2">
|
||||
<a href="https://gitlab.com/timvisee/send" target="_blank">
|
||||
${translate('footerLinkSource')}
|
||||
</a>
|
||||
</li>
|
||||
`);
|
||||
}
|
||||
|
||||
return html`
|
||||
<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:justify-end justify-between"
|
||||
>
|
||||
<ul
|
||||
class="flex flex-col md:flex-row items-start md:items-center md:justify-start"
|
||||
<a
|
||||
href="https://admin.chapril.org/doku.php?id=admin:chatons:drop.chapril.org#personnalisation"
|
||||
rel="noreferrer noopener"
|
||||
alt="Version"
|
||||
target="_blank"
|
||||
>
|
||||
<li class="m-2">${translate('footerText')}</li>
|
||||
</ul>
|
||||
<ul
|
||||
class="flex flex-col md:flex-row items-start md:items-center md:justify-end"
|
||||
>
|
||||
${links}
|
||||
</ul>
|
||||
FirefoxSend chapril-${version}
|
||||
</a>
|
||||
</footer>
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const html = require('choo/html');
|
||||
const Component = require('choo/component');
|
||||
const Account = require('./account');
|
||||
const assets = require('../../common/assets');
|
||||
const { platform } = require('../utils');
|
||||
/*const assets = require('../../common/assets');*/
|
||||
/*const { platform } = require('../utils');*/
|
||||
|
||||
class Header extends Component {
|
||||
constructor(name, state, emit) {
|
||||
|
@ -18,45 +18,66 @@ class Header extends Component {
|
|||
}
|
||||
|
||||
createElement() {
|
||||
let assetMap = {};
|
||||
if (this.state.ui !== undefined) assetMap = this.state.ui.assets;
|
||||
else
|
||||
assetMap = {
|
||||
icon:
|
||||
this.state.WEB_UI.CUSTOM_ASSETS.icon !== ''
|
||||
? this.state.WEB_UI.CUSTOM_ASSETS.icon
|
||||
: assets.get('icon.svg'),
|
||||
wordmark:
|
||||
this.state.WEB_UI.CUSTOM_ASSETS.wordmark !== ''
|
||||
? this.state.WEB_UI.CUSTOM_ASSETS.wordmark
|
||||
: assets.get('wordmark.svg') + '#logo'
|
||||
};
|
||||
const title =
|
||||
platform() === 'android'
|
||||
? html`
|
||||
<a class="flex flex-row items-center">
|
||||
<img src="${assetMap.icon}" />
|
||||
<svg class="w-48">
|
||||
<use xlink:href="${assetMap.wordmark}" />
|
||||
</svg>
|
||||
</a>
|
||||
`
|
||||
: html`
|
||||
<a class="flex flex-row items-center" href="/">
|
||||
<img
|
||||
alt="${this.state.translate('title')}"
|
||||
src="${assetMap.icon}"
|
||||
/>
|
||||
<svg viewBox="66 0 340 64" class="w-48 md:w-64">
|
||||
<use xlink:href="${assetMap.wordmark}" />
|
||||
</svg>
|
||||
</a>
|
||||
`;
|
||||
return html`
|
||||
<header
|
||||
class="main-header relative flex-none flex flex-row items-center justify-between w-full px-6 md:px-8 h-16 md:h-24 z-20 bg-transparent"
|
||||
class="main-header relative flex-none flex flex-row items-center justify-between px-6 md:px-8 z-20 bg-transparent"
|
||||
>
|
||||
${title} ${this.account.render()}
|
||||
<!-- Chapril banner code: starting… -->
|
||||
<nav class="chapril-banniere-Nav">
|
||||
<div class="chapril-banniere-Logo" aria-hidden="true">
|
||||
<a href="https://www.chapril.org"
|
||||
><img alt="" src="/Chapril-banner/v2/chapril-banner-logo.png"
|
||||
/></a>
|
||||
</div>
|
||||
<div class="chapril-banniere-Menu" aria-hidden="true">
|
||||
<details>
|
||||
<summary>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</summary>
|
||||
<div><a href="https://www.chapril.org/">Accueil Chapril</a></div>
|
||||
<div>
|
||||
<a href="https://www.chapril.org/services.html"
|
||||
>Services libres</a
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://pouet.april.org/@aprilorg">Nous suivre</a>
|
||||
</div>
|
||||
<div><a href="https://www.chapril.org/cgu.html">CGU</a></div>
|
||||
<div>
|
||||
<a href="https://www.chapril.org/a-propos.html"
|
||||
>Mentions légales</a
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://www.chapril.org/contact.html"
|
||||
>Nous contacter</a
|
||||
>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<div class="chapril-banniere-Entree">
|
||||
<a href="https://www.chapril.org/">Accueil Chapril</a>
|
||||
</div>
|
||||
<div class="chapril-banniere-Entree">
|
||||
<a href="https://www.chapril.org/services.html">Services libres</a>
|
||||
</div>
|
||||
<div class="chapril-banniere-Entree">
|
||||
<a href="https://pouet.april.org/@aprilorg">Nous suivre</a>
|
||||
</div>
|
||||
<div class="chapril-banniere-Entree">
|
||||
<a href="https://www.chapril.org/cgu.html">CGU</a>
|
||||
</div>
|
||||
<div class="chapril-banniere-Entree">
|
||||
<a href="https://www.chapril.org/a-propos.html">Mentions légales</a>
|
||||
</div>
|
||||
<div class="chapril-banniere-Entree">
|
||||
<a href="https://www.chapril.org/contact.html">Nous contacter</a>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Chapril banner code: done. -->
|
||||
</header>
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ module.exports = function(state, emit) {
|
|||
'downloadTitle'
|
||||
)}</h1>
|
||||
<p
|
||||
class="w-full p-2 border border-yellow-50 rounded md:w-4/5 text-orange-60 bg-yellow-40 text-center leading-normal"
|
||||
class="w-full p-2 border-default border-yellow-50 rounded-default md:w-4/5 text-orange-60 bg-yellow-40 text-center leading-normal"
|
||||
>
|
||||
⚠️ ${state.translate('noStreamsWarning')} ⚠️
|
||||
</p>
|
||||
<form class="md:w-128" onsubmit=${submit}>
|
||||
<fieldset class="border rounded p-4 my-4" onchange=${optionChanged}>
|
||||
<fieldset class="border-default rounded-default p-4 my-4" onchange=${optionChanged}>
|
||||
<div class="flex items-center mb-2">
|
||||
<svg class="h-8 w-6 mr-3 flex-shrink-0 text-primary">
|
||||
<use xlink:href="${assets.get('blue_file.svg')}#icon"/>
|
||||
|
|
|
@ -18,7 +18,7 @@ module.exports = function(selected, options, translate, changed, htmlId) {
|
|||
return html`
|
||||
<select
|
||||
id="${htmlId}"
|
||||
class="appearance-none cursor-pointer border rounded bg-grey-10 hover:border-primary focus:border-primary pl-1 pr-8 py-1 my-1 h-8 dark:bg-grey-80"
|
||||
class="appearance-none cursor-pointer border-default rounded-default bg-grey-10 hover:border-primary focus:border-primary pl-1 pr-8 py-1 my-1 h-8 dark:bg-grey-80"
|
||||
data-selected="${selected}"
|
||||
onchange="${choose}"
|
||||
>
|
||||
|
|
|
@ -18,7 +18,7 @@ module.exports = function(name, url) {
|
|||
<input
|
||||
type="text"
|
||||
id="share-url"
|
||||
class="w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80"
|
||||
class="w-full my-4 border-default rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80"
|
||||
value="${url}"
|
||||
readonly="true"
|
||||
/>
|
||||
|
|
|
@ -35,7 +35,7 @@ module.exports = function() {
|
|||
<input
|
||||
id="email-input"
|
||||
type="email"
|
||||
class="hidden border rounded-lg w-full px-2 py-1 h-12 mb-3 text-lg text-grey-70 leading-loose dark:bg-grey-80 dark:text-white"
|
||||
class="hidden border-default rounded-lg w-full px-2 py-1 h-12 mb-3 text-lg text-grey-70 leading-loose dark:bg-grey-80 dark:text-white"
|
||||
placeholder=${state.translate('emailPlaceholder')}
|
||||
/>
|
||||
<input
|
||||
|
|
|
@ -27,7 +27,7 @@ module.exports = function(state, emit) {
|
|||
<main class="main">
|
||||
${state.modal && modal(state, emit)}
|
||||
<section
|
||||
class="flex flex-col items-center justify-center text-center bg-white m-6 px-6 py-8 border border-grey-30 md:border-none md:px-12 md:py-16 shadow w-full md:h-full dark:bg-grey-90"
|
||||
class="flex flex-col items-center justify-center text-center bg-white m-6 px-6 py-8 border-default border-grey-30 md:border-none md:px-12 md:py-16 shadow-default w-full md:h-full dark:bg-grey-90"
|
||||
>
|
||||
<h1 class="text-3xl font-bold">${strings.header}</h1>
|
||||
<p class="mt-4 mb-8 max-w-md leading-normal">${strings.description}</p>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 588 B After Width: | Height: | Size: 408 B |
Binary file not shown.
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 972 B |
|
@ -96,6 +96,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_TWITTER | | A custom header image for Twitter |
|
||||
| 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
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
48
package.json
48
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "send",
|
||||
"description": "File Sharing Experiment",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.23",
|
||||
"author": "Mozilla (https://mozilla.org)",
|
||||
"contributors": [
|
||||
"Tim Visee <3a4fb3964f@sinenomine.email> (https://timvisee.com)"
|
||||
|
@ -67,7 +67,7 @@
|
|||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/preset-env": "^7.16.11",
|
||||
"@dannycoates/webcrypto-liner": "^0.1.37",
|
||||
"@fullhuman/postcss-purgecss": "^1.3.0",
|
||||
"@fullhuman/postcss-purgecss": "^4.1.3",
|
||||
"@mattiasbuelens/web-streams-polyfill": "0.2.1",
|
||||
"@sentry/browser": "^5.30.0",
|
||||
"asmcrypto.js": "^0.22.0",
|
||||
|
@ -75,13 +75,13 @@
|
|||
"babel-plugin-istanbul": "^5.2.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"content-disposition": "^0.5.4",
|
||||
"copy-webpack-plugin": "^5.1.2",
|
||||
"copy-webpack-plugin": "^6.4.0",
|
||||
"core-js": "^3.21.1",
|
||||
"crc": "^3.8.0",
|
||||
"cross-env": "^6.0.3",
|
||||
"css-loader": "^3.6.0",
|
||||
"css-loader": "^5.2.7",
|
||||
"css-mqpacker": "^7.0.0",
|
||||
"cssnano": "^4.1.11",
|
||||
"cssnano": "^5.1.12",
|
||||
"eslint": "^6.6.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
"eslint-plugin-mocha": "^6.2.1",
|
||||
|
@ -91,22 +91,23 @@
|
|||
"extract-loader": "^3.2.0",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"fast-text-encoding": "^1.0.3",
|
||||
"file-loader": "^4.2.0",
|
||||
"git-rev-sync": "^1.12.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"git-rev-sync": "^3.0.2",
|
||||
"html-loader": "^0.5.5",
|
||||
"http_ece": "^1.1.0",
|
||||
"husky": "^3.0.9",
|
||||
"intl-pluralrules": "^1.3.1",
|
||||
"lint-staged": "^9.4.2",
|
||||
"mocha": "^6.2.2",
|
||||
"mocha": "^10.1.0",
|
||||
"morgan": "^1.9.1",
|
||||
"nanobus": "^4.5.0",
|
||||
"nanohtml": "^1.9.0",
|
||||
"nanotiming": "^7.3.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"nyc": "^14.1.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.7.1",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-loader": "^4.2.0",
|
||||
"postcss-preset-env": "^7.7.2",
|
||||
"prettier": "^1.19.1",
|
||||
"proxyquire": "^2.1.3",
|
||||
"puppeteer": "^2.0.0",
|
||||
|
@ -115,13 +116,13 @@
|
|||
"script-loader": "^0.7.2",
|
||||
"sinon": "^7.5.0",
|
||||
"string-hash": "^1.1.3",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint-config-standard": "^19.0.0",
|
||||
"stylelint-no-unsupported-browser-features": "^4.1.4",
|
||||
"svgo": "^1.3.2",
|
||||
"svgo-loader": "^2.2.2",
|
||||
"tailwindcss": "^1.9.6",
|
||||
"val-loader": "^1.1.1",
|
||||
"stylelint": "^14.9.1",
|
||||
"stylelint-config-standard": "^26.0.0",
|
||||
"stylelint-no-unsupported-browser-features": "^5.0.3",
|
||||
"svgo": "^2.8.0",
|
||||
"svgo-loader": "^3.0.1",
|
||||
"tailwindcss": "^2",
|
||||
"val-loader": "^2.1.2",
|
||||
"webpack": "4.38.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-dev-middleware": "^3.7.3",
|
||||
|
@ -131,22 +132,21 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@dannycoates/express-ws": "^5.0.3",
|
||||
"@fluent/bundle": "^0.13.0",
|
||||
"@fluent/langneg": "^0.3.0",
|
||||
"@google-cloud/storage": "^5.19.0",
|
||||
"@sentry/node": "^5.30.0",
|
||||
"@fluent/bundle": "^0.17.1",
|
||||
"@fluent/langneg": "^0.6.2",
|
||||
"@google-cloud/storage": "^6.2.3",
|
||||
"@sentry/node": "^7.7.0",
|
||||
"aws-sdk": "^2.1109.0",
|
||||
"body-parser": "^1.20.0",
|
||||
"choo": "^7.0.0",
|
||||
"cldr-core": "^35.1.0",
|
||||
"configstore": "github:dannycoates/configstore#master",
|
||||
"convict": "^6.2.2",
|
||||
"convict": "^6.2.4",
|
||||
"convict-format-with-validator": "^6.2.0",
|
||||
"double-ended-queue": "^2.1.0-0",
|
||||
"express": "^4.17.3",
|
||||
"helmet": "^3.23.3",
|
||||
"mkdirp": "^0.5.6",
|
||||
"mozlog": "^2.2.0",
|
||||
"mozlog": "^3.0.1",
|
||||
"node-fetch": "^2.6.7",
|
||||
"redis": "^3.1.1",
|
||||
"redis-mock": "^0.47.0",
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
class TailwindExtractor {
|
||||
static extract(content) {
|
||||
return content.match(/[A-Za-z0-9-_:/]+/g) || [];
|
||||
}
|
||||
}
|
||||
const TailwindExtractor = content => {
|
||||
return content.match(/[A-Za-z0-9-_:/]+/g) || [];
|
||||
};
|
||||
|
||||
const options = {
|
||||
plugins: [
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#chapril-banner {
|
||||
/* position: fixed; */
|
||||
|
||||
/* top: 0; */
|
||||
height: 42px !important;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #fafafa;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #bdbdbd;
|
||||
}
|
||||
|
||||
#chapril-banner-zone {
|
||||
width: 100%;
|
||||
|
||||
/* max-width: 950px; */
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
|
||||
/* border: solid 1px red; */
|
||||
}
|
||||
|
||||
#chapril-banner-zone > div {
|
||||
float: left;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
#chapril-banner-menu > ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
text-align: justify;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#chapril-banner-menu > ul > li {
|
||||
float: left;
|
||||
margin: 0 10px 0 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
font-family: 'DejaVu Sans', Verdana, Geneva, sans-serif !important;
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
#chapril-banner-menu > ul > li:hover {
|
||||
background-color: #dadada;
|
||||
}
|
||||
|
||||
#chapril-banner-menu > ul > li > a {
|
||||
height: 42px;
|
||||
color: #555000;
|
||||
font-size: 12px;
|
||||
text-decoration: none !important;
|
||||
line-height: 42px;
|
||||
border: none !important;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
#chapril-banner-aprillogo {
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
#chapril-banner-aprillogo > a > img {
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
#chapril-banner-zone > div > a > img {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.send-promo {
|
||||
display: none;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 9.4 KiB |
|
@ -48,7 +48,7 @@ passwordSetError = Ce mot de passe n’a pas pu être défini
|
|||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = Partage de fichiers simple et privé
|
||||
introDescription = { -send-brand } vous permet de partager des fichiers chiffrés de bout en bout ainsi qu’un lien qui expire automatiquement. Ainsi, vous pouvez garder ce que vous partagez en privé et vous assurer que vos contenus ne restent pas en ligne pour toujours.
|
||||
introDescription = DropChaprilOrg vous permet de partager des fichiers chiffrés de bout en bout ainsi qu’un lien qui expire automatiquement. Ainsi, vous pouvez garder ce que vous partagez en privé et vous assurer que vos contenus ne restent pas en ligne pour toujours.
|
||||
notifyUploadEncryptDone = Votre fichier est chiffré et prêt à l’envoi
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = Expire après { $downloadCount } ou { $timespan }
|
||||
|
|
|
@ -13,6 +13,8 @@ module.exports = {
|
|||
FOOTER_CLI_URL: config.footer_cli_url,
|
||||
FOOTER_DMCA_URL: config.footer_dmca_url,
|
||||
FOOTER_SOURCE_URL: config.footer_source_url,
|
||||
CUSTOM_FOOTER_TEXT: config.custom_footer_text,
|
||||
CUSTOM_FOOTER_URL: config.custom_footer_url,
|
||||
COLORS: {
|
||||
PRIMARY: config.ui_color_primary,
|
||||
ACCENT: config.ui_color_accent
|
||||
|
|
|
@ -49,7 +49,7 @@ const conf = convict({
|
|||
},
|
||||
expire_times_seconds: {
|
||||
format: 'positive-int-array',
|
||||
default: [300, 3600, 86400, 604800],
|
||||
default: [300, 3600, 86400, 172800, 432000, 604800],
|
||||
env: 'EXPIRE_TIMES_SECONDS'
|
||||
},
|
||||
default_expire_seconds: {
|
||||
|
@ -59,7 +59,7 @@ const conf = convict({
|
|||
},
|
||||
max_expire_seconds: {
|
||||
format: Number,
|
||||
default: 86400 * 7,
|
||||
default: 432000,
|
||||
env: 'MAX_EXPIRE_SECONDS'
|
||||
},
|
||||
download_counts: {
|
||||
|
@ -165,9 +165,19 @@ const conf = convict({
|
|||
},
|
||||
base_url: {
|
||||
format: 'url',
|
||||
default: 'https://send.firefox.com',
|
||||
default: 'https://send.example.com',
|
||||
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: {
|
||||
format: Boolean,
|
||||
default: false,
|
||||
|
@ -243,6 +253,16 @@ const conf = convict({
|
|||
default: 'https://github.com/timvisee/send',
|
||||
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: {
|
||||
format: String,
|
||||
default: '#0a84ff',
|
||||
|
@ -253,6 +273,11 @@ const conf = convict({
|
|||
default: '#003eaa',
|
||||
env: 'UI_COLOR_ACCENT'
|
||||
},
|
||||
custom_locale: {
|
||||
format: String,
|
||||
default: '',
|
||||
env: 'CUSTOM_LOCALE'
|
||||
},
|
||||
ui_custom_assets: {
|
||||
android_chrome_192px: {
|
||||
format: String,
|
||||
|
@ -303,6 +328,11 @@ const conf = convict({
|
|||
format: String,
|
||||
default: '',
|
||||
env: 'UI_CUSTOM_ASSETS_WORDMARK'
|
||||
},
|
||||
custom_css: {
|
||||
format: String,
|
||||
default: '',
|
||||
env: 'UI_CUSTOM_CSS'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3,6 +3,10 @@ const assets = require('../common/assets');
|
|||
const initScript = require('./initScript');
|
||||
|
||||
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`
|
||||
<!DOCTYPE html>
|
||||
<html lang="${state.locale}">
|
||||
|
@ -35,11 +39,17 @@ module.exports = function(state, body = '') {
|
|||
--color-primary-accent: ${state.ui.colors.accent};
|
||||
}
|
||||
</style>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="/Chapril-banner/v2/chapril-banner.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="${assets.get('app.css')}"
|
||||
/>
|
||||
${custom_css}
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { FluentBundle } = require('@fluent/bundle');
|
||||
const { FluentBundle, FluentResource } = require('@fluent/bundle');
|
||||
const localesPath = path.resolve(__dirname, '../public/locales');
|
||||
const locales = fs.readdirSync(localesPath);
|
||||
|
||||
function makeBundle(locale) {
|
||||
const bundle = new FluentBundle(locale, { useIsolating: false });
|
||||
bundle.addMessages(
|
||||
fs.readFileSync(path.resolve(localesPath, locale, 'send.ftl'), 'utf8')
|
||||
bundle.addResource(
|
||||
new FluentResource(
|
||||
fs.readFileSync(path.resolve(localesPath, locale, 'send.ftl'), 'utf8')
|
||||
)
|
||||
);
|
||||
return [locale, bundle];
|
||||
}
|
||||
|
@ -19,8 +21,11 @@ module.exports = function getTranslator(locale) {
|
|||
const bundle = bundles.get(locale) || defaultBundle;
|
||||
return function(id, data) {
|
||||
if (bundle.hasMessage(id)) {
|
||||
return bundle.format(bundle.getMessage(id), data);
|
||||
return bundle.formatPattern(bundle.getMessage(id).value, data);
|
||||
}
|
||||
return defaultBundle.format(defaultBundle.getMessage(id), data);
|
||||
return defaultBundle.formatPattern(
|
||||
defaultBundle.getMessage(id).value,
|
||||
data
|
||||
);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const assert = require('assert');
|
||||
const crypto = require('crypto');
|
||||
const storage = require('../storage');
|
||||
const config = require('../config');
|
||||
const fxa = require('../fxa');
|
||||
|
||||
module.exports = {
|
||||
|
@ -70,10 +71,11 @@ module.exports = {
|
|||
const token = authHeader.split(' ')[1];
|
||||
req.user = await fxa.verify(token);
|
||||
}
|
||||
if (req.user) {
|
||||
next();
|
||||
} else {
|
||||
|
||||
if (config.fxa_required && !req.user) {
|
||||
res.sendStatus(401);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,9 +3,18 @@ const layout = require('./layout');
|
|||
const assets = require('../common/assets');
|
||||
const getTranslator = require('./locale');
|
||||
const { getFxaConfig } = require('./fxa');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
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 robots = 'none';
|
||||
if (req.route && req.route.path === '/') {
|
||||
|
@ -34,7 +43,8 @@ module.exports = async function(req) {
|
|||
safari_pinned_tab: assets.get('safari-pinned-tab.svg'),
|
||||
facebook: baseUrl + '/' + assets.get('send-fb.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 => {
|
||||
if (config.ui_custom_assets[index] !== '')
|
||||
|
@ -47,7 +57,7 @@ module.exports = async function(req) {
|
|||
locale,
|
||||
capabilities: { account: false },
|
||||
translate: getTranslator(locale),
|
||||
title: 'Send',
|
||||
title: 'DropChaprilOrg',
|
||||
description:
|
||||
'Encrypt and send files with a link that automatically expires to ensure your important documents don’t stay online forever.',
|
||||
baseUrl,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const promisify = require('util').promisify;
|
||||
const mkdirp = require('mkdirp');
|
||||
|
||||
const stat = promisify(fs.stat);
|
||||
|
||||
|
@ -9,7 +8,9 @@ class FSStorage {
|
|||
constructor(config, log) {
|
||||
this.log = log;
|
||||
this.dir = config.file_dir;
|
||||
mkdirp.sync(this.dir);
|
||||
fs.mkdirSync(this.dir, {
|
||||
recursive: true
|
||||
});
|
||||
}
|
||||
|
||||
async length(id) {
|
||||
|
|
|
@ -23,6 +23,7 @@ const colors = {
|
|||
};
|
||||
|
||||
module.exports = {
|
||||
purge: false,
|
||||
theme: {
|
||||
colors: colors,
|
||||
screens: {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable no-undef, no-process-exit */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const mkdirp = require('mkdirp');
|
||||
const puppeteer = require('puppeteer');
|
||||
const webpack = require('webpack');
|
||||
const config = require('../../webpack.config');
|
||||
|
@ -44,7 +43,9 @@ const server = app.listen(async function() {
|
|||
const coverage = await page.evaluate(() => __coverage__);
|
||||
if (coverage) {
|
||||
const dir = path.resolve(__dirname, '../../.nyc_output');
|
||||
mkdirp.sync(dir);
|
||||
fs.mkdirSync(dir, {
|
||||
recursive: true
|
||||
});
|
||||
fs.writeFileSync(
|
||||
path.resolve(dir, 'frontend.json'),
|
||||
JSON.stringify(coverage)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
const path = require('path');
|
||||
const mkdirp = require('mkdirp');
|
||||
const fs = require('fs');
|
||||
const rimraf = require('rimraf');
|
||||
const dir = path.join(__dirname, 'integration', 'downloads');
|
||||
|
||||
mkdirp.sync(dir);
|
||||
fs.mkdirSync(dir, {
|
||||
recursive: true
|
||||
});
|
||||
rimraf.sync(`${dir}${path.sep}*`);
|
||||
|
||||
exports.config = {
|
||||
|
|
|
@ -42,7 +42,8 @@ const serviceWorker = {
|
|||
test: /\.(png|jpg)$/,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[contenthash:8].[ext]'
|
||||
name: '[name].[contenthash:8].[ext]',
|
||||
esModule: false
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -51,16 +52,26 @@ const serviceWorker = {
|
|||
{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[contenthash:8].[ext]'
|
||||
name: '[name].[contenthash:8].[ext]',
|
||||
esModule: false
|
||||
}
|
||||
},
|
||||
{
|
||||
loader: 'svgo-loader',
|
||||
options: {
|
||||
plugins: [
|
||||
{ removeViewBox: false }, // true causes stretched images
|
||||
{ convertStyleToAttrs: true }, // for CSP, no unsafe-eval
|
||||
{ removeTitle: true } // for smallness
|
||||
{
|
||||
name: 'removeViewBox',
|
||||
active: false // true causes stretched images
|
||||
},
|
||||
{
|
||||
name: 'convertStyleToAttrs',
|
||||
active: true // for CSP, no unsafe-eval
|
||||
},
|
||||
{
|
||||
name: 'removeTitle',
|
||||
active: true // for smallness
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +138,8 @@ const web = {
|
|||
test: /\.(png|jpg)$/,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[contenthash:8].[ext]'
|
||||
name: '[name].[contenthash:8].[ext]',
|
||||
esModule: false
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -136,17 +148,30 @@ const web = {
|
|||
{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[contenthash:8].[ext]'
|
||||
name: '[name].[contenthash:8].[ext]',
|
||||
esModule: false
|
||||
}
|
||||
},
|
||||
{
|
||||
loader: 'svgo-loader',
|
||||
options: {
|
||||
plugins: [
|
||||
{ cleanupIDs: false },
|
||||
{ removeViewBox: false }, // true causes stretched images
|
||||
{ convertStyleToAttrs: true }, // for CSP, no unsafe-eval
|
||||
{ removeTitle: true } // for smallness
|
||||
{
|
||||
name: 'cleanupIDs',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
name: 'removeViewBox',
|
||||
active: false // true causes stretched images
|
||||
},
|
||||
{
|
||||
name: 'convertStyleToAttrs',
|
||||
active: true // for CSP, no unsafe-eval
|
||||
},
|
||||
{
|
||||
name: 'removeTitle',
|
||||
active: true // for smallness
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +185,8 @@ const web = {
|
|||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
importLoaders: 1
|
||||
importLoaders: 1,
|
||||
esModule: false
|
||||
}
|
||||
},
|
||||
'postcss-loader'
|
||||
|
@ -184,12 +210,14 @@ const web = {
|
|||
]
|
||||
},
|
||||
plugins: [
|
||||
new CopyPlugin([
|
||||
{
|
||||
context: 'public',
|
||||
from: '*.*'
|
||||
}
|
||||
]),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
context: 'public',
|
||||
from: '*.*'
|
||||
}
|
||||
]
|
||||
}),
|
||||
new webpack.EnvironmentPlugin(['NODE_ENV']),
|
||||
new webpack.IgnorePlugin(/\.\.\/dist/), // used in common/*.js
|
||||
new ExtractTextPlugin({
|
||||
|
|
Loading…
Reference in New Issue