Compare commits
No commits in common. "master" and "feature/max-artifact-size" have entirely different histories.
master
...
feature/ma
17 changed files with 23 additions and 145 deletions
26
.drone.yml
26
.drone.yml
|
@ -74,13 +74,12 @@ steps:
|
|||
- ls -al
|
||||
- cd web/fling
|
||||
- npm install && npm run build
|
||||
- npm install --no-cache @fling/flingclient # make sure flingclient is not cached
|
||||
- tar czf fling-web-$VERSION.tar.gz build/
|
||||
- curl --user "$NEXUS_USER:$NEXUS_PASSWORD"
|
||||
--upload-file ./fling-web-$VERSION.tar.gz
|
||||
https://nexus.friedl.net/repository/build-artifacts/fling-web-$VERSION.tar.gz
|
||||
|
||||
- name: publish branch
|
||||
- name: publish
|
||||
image: plugins/docker
|
||||
settings:
|
||||
username:
|
||||
|
@ -93,29 +92,6 @@ steps:
|
|||
tags: 0.1.0-snapshot
|
||||
build_args:
|
||||
- VERSION=0.1.0-snapshot
|
||||
when:
|
||||
branch:
|
||||
exclude:
|
||||
- master
|
||||
|
||||
- name: publish master
|
||||
image: plugins/docker
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
dockerfile: container/Dockerfile
|
||||
context: ./container
|
||||
repo: arminfriedl/fling
|
||||
tags:
|
||||
- 0.1.0-snapshot
|
||||
- latest
|
||||
build_args:
|
||||
- VERSION=0.1.0-snapshot
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
|
||||
volumes:
|
||||
- name: m2-cache
|
||||
|
|
68
README.md
68
README.md
|
@ -1,68 +0,0 @@
|
|||
**12.01.2021: Fling has moved to the attic**
|
||||
|
||||
Fling was a good learning experiment for a non-trivial React app with a REST
|
||||
backend. However, it never really got any traction and I'm not using it anymore.
|
||||
Other projects are more important to me and maintaining Fling does not make any
|
||||
sense. As of now docker containers are deleted and the artifacts are not
|
||||
distributed anymore. You are free to fork and build your own version but no more
|
||||
work will be done in this repository.
|
||||
|
||||
Alternatives:
|
||||
- If you are looking for mature self-hosted file sharing solution,
|
||||
[ownCloud](https://owncloud.com/) is in many ways similar to Fling and then
|
||||
some.
|
||||
- If you want an even simpler solution for sharing files over http,
|
||||
[dirl](https://github.com/arminfriedl/dirl) might meet your needs.
|
||||
|
||||
# Fling
|
||||
Fling is a self-hosted file share. It is simple like USB without missing out on
|
||||
the good parts of a web app:
|
||||
- Just drop files on a Fling and share the URL
|
||||
- Choose your own name for your share-URL
|
||||
- Share a direct download link
|
||||
- Let others upload files
|
||||
- Protect your fling by a password - no registration required
|
||||
- Let a fling expire after a date or a number of clicks
|
||||
|
||||
# API
|
||||
Fling is distributed as both, a backend service and a web interface. You can use
|
||||
the backend on its own with any [HTTP client](examples).
|
||||
|
||||
Per default Fling publishes a Swagger UI page and an OpenAPI spec. You can find
|
||||
them here:
|
||||
|
||||
``` http
|
||||
http://<host>:<port>/swagger-ui.html
|
||||
http://<host>:<port>/v3/api-docs
|
||||
```
|
||||
|
||||
If starting the fling container locally, the default `<host>:<port>` is
|
||||
http://localhost:3000. You can also find a recent version of it via
|
||||
https://fling.friedl.net/swagger-ui.html and
|
||||
https://fling.friedl.net/v3/api-docs.
|
||||
|
||||
# Starting Fling from Docker
|
||||
A Fling container is provided at https://hub.docker.com/repository/docker/arminfriedl/fling.
|
||||
|
||||
1. Run `docker run --rm -p3000:3000 arminfriedl/fling`
|
||||
2. Go to the default http://localhost:3000
|
||||
3. Log in with `adminName:adminPassword`.
|
||||
|
||||
## Configuring Fling
|
||||
The Fling container can be configured by environment variables.
|
||||
|
||||
The web interface configuration ([config.js](web/fling/public/config.js)/[config.js.template](container/var/www/fling/config.js.template)) will be
|
||||
filled by `envsubst` when the container starts up.
|
||||
``` sh
|
||||
# The base URL of the Fling API service
|
||||
FLING_API_BASE=http://localhost:3000
|
||||
# Log level of the application
|
||||
FLING_LOG_LEVEL=warn
|
||||
# Max. upload size in bytes. Checked on client side.
|
||||
FLING_FILESIZE=209715200
|
||||
```
|
||||
|
||||
The Fling service configuration is a standard spring configuration. It can be
|
||||
set by environement variables or any other [configuration externalization supported by spring boot]
|
||||
(https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config)).
|
||||
Refer to the [application-prod.yml](service/fling/src/main/resources/application-prod.yml) for configuration options.
|
|
@ -2,11 +2,7 @@ FROM alpine:latest
|
|||
|
||||
ARG VERSION
|
||||
|
||||
ENV FLING_API_BASE http://localhost:3000
|
||||
ENV FLING_LOG_LEVEL warn
|
||||
ENV FLING_FILESIZE 209715200
|
||||
|
||||
RUN apk add --update --no-cache nginx openjdk11-jre gettext && \
|
||||
RUN apk add --update --no-cache nginx openjdk11-jre && \
|
||||
mkdir -p /var/fling/files && \
|
||||
mkdir -p /tmp/fling && \
|
||||
wget -O /tmp/fling/service.jar "https://nexus.friedl.net/service/rest/v1/search/assets/download?sort=version&maven.groupId=net.friedl&maven.artifactId=fling&maven.baseVersion=$(echo -n $VERSION | tr [:lower:] [:upper:])&maven.extension=jar" && \
|
||||
|
@ -18,8 +14,7 @@ RUN apk add --update --no-cache nginx openjdk11-jre gettext && \
|
|||
mv /tmp/fling/service.jar ./service.jar
|
||||
|
||||
COPY ./etc/nginx/conf.d /etc/nginx/conf.d
|
||||
COPY ./var/www/fling/config.js.template /var/www/fling/config.js.template
|
||||
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
COPY ./entrypoint.sh ./usr/local/bin/entrypoint.sh
|
||||
|
||||
VOLUME /var/fling/
|
||||
|
||||
|
|
|
@ -6,6 +6,4 @@ mkdir /var/run/nginx # nginx fails with /var/run/nginx/nginx.pid not found in al
|
|||
|
||||
nginx
|
||||
|
||||
cat /var/www/fling/config.js.template | envsubst > /var/www/fling/config.js
|
||||
|
||||
java ${FL_JVM_OPTS} -jar service.jar
|
||||
|
|
|
@ -61,23 +61,6 @@ server {
|
|||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# handle openapi requests by openapi servlet
|
||||
location /swagger-ui {
|
||||
proxy_pass http://localhost:8080;
|
||||
|
||||
proxy_set_header X-Forwarded-Host $host:$server_port;
|
||||
proxy_set_header X-Forwarded-Server $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Required for web sockets to function
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# always respond with index.html for unknown paths
|
||||
# (routing is client side)
|
||||
location / {
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
window['flingconfig'] = {
|
||||
API_BASE: "${FLING_API_BASE}",
|
||||
LOG_LEVEL: "${FLING_LOG_LEVEL}",
|
||||
FILESIZE: "${FLING_FILESIZE}"
|
||||
}
|
|
@ -20,8 +20,7 @@ fling:
|
|||
archive.filesystem.archive-path: "/var/fling/files"
|
||||
security:
|
||||
allowed-origins:
|
||||
- "https://fling.friedl.net"
|
||||
- "http://localhost:3000"
|
||||
- "https://friedl.net"
|
||||
- "http://localhost:3000"
|
||||
- "http://localhost:5000"
|
||||
- "http://10.0.2.2:5000"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
REACT_APP_API=http://localhost:3000
|
||||
REACT_APP_API=https://fling.friedl.net
|
||||
REACT_APP_LOGLEVEL=warn
|
||||
REACT_APP_FILESIZE=209715200
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
window['flingconfig'] = {
|
||||
API_BASE: "http://localhost:8080",
|
||||
LOG_LEVEL: "warn",
|
||||
FILESIZE: 209715200
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/fling.ico">
|
||||
<script src="%PUBLIC_URL%/config.js"></script>
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tag above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
|
|
|
@ -22,7 +22,7 @@ function FlingArtifactControl(props) {
|
|||
// the browser downloads the file fine, it also reloads the page, hence
|
||||
// loosing all logs and state
|
||||
let frame = document.createElement("iframe");
|
||||
let url = `${window['flingconfig'].API_BASE.replace(/\/+$/, '')}/api/artifacts/${props.artifact.id}/data?derivedToken=${token}`;
|
||||
let url = `${process.env.REACT_APP_API.replace(/\/+$/, '')}/api/artifacts/${props.artifact.id}/data?derivedToken=${token}`;
|
||||
log.trace(`Generated download url: ${url}`);
|
||||
frame.src = url;
|
||||
iframeContainer.current.appendChild(frame);
|
||||
|
|
|
@ -23,6 +23,12 @@ export default function Navbar() {
|
|||
Fling
|
||||
</a>
|
||||
</section>
|
||||
<section className="navbar-center">
|
||||
<div className="input-group input-inline">
|
||||
<input className="form-input input-sm" type="text" placeholder="Search" />
|
||||
<button className="btn btn-sm btn-link input-group-btn"><i className="icon icon-search"/></button>
|
||||
</div>
|
||||
</section>
|
||||
<section className="navbar-section navbar-control">
|
||||
<button className="btn btn-sm btn-link" onClick={handleOnClick}><i className="icon icon-plus"/> New</button>
|
||||
<a className="btn btn-sm btn-link" href="/admin/login"><i className="icon icon-shutdown"/> Logout</a>
|
||||
|
|
|
@ -82,7 +82,7 @@ export default function Upload() {
|
|||
stopEvent(ev);
|
||||
ev.persist();
|
||||
|
||||
let maxSize = window['flingconfig'].FILESIZE;
|
||||
let maxSize = process.env.REACT_APP_FILESIZE;
|
||||
let evFiles = fileListToArray(ev.dataTransfer.files);
|
||||
|
||||
for (let i = evFiles.length - 1; i >= 0; i--) {
|
||||
|
@ -211,7 +211,7 @@ export default function Upload() {
|
|||
</div>
|
||||
<div className="upload-command-line m-2">
|
||||
<span className="total-upload">Total Size: {totalSize()}</span>
|
||||
<span className="total-upload">{`Max: ${prettifyBytes(window['flingconfig'].FILESIZE)}`}</span>
|
||||
<span className="total-upload">{`Max: ${prettifyBytes(process.env.REACT_APP_FILESIZE)}`}</span>
|
||||
<button className="btn btn-primary btn-upload" onClick={handleUpload}>Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,7 +16,7 @@ export default function FlingUser(props) {
|
|||
let authClient = new AuthClient();
|
||||
authClient.deriveToken({ singleUse: true })
|
||||
.then(token => {
|
||||
let url = `${window['flingconfig'].API_BASE.replace(/\/+$/, '')}/api/fling/${props.fling.id}/data?derivedToken=${token}`;
|
||||
let url = `${process.env.REACT_APP_API.replace(/\/+$/, '')}/api/fling/${props.fling.id}/data?derivedToken=${token}`;
|
||||
log.trace(`Generated download url for link: ${url}`);
|
||||
setDownloadUrl(url);
|
||||
})
|
||||
|
@ -28,7 +28,7 @@ export default function FlingUser(props) {
|
|||
// the browser downloads the file fine, it also reloads the page, hence
|
||||
// loosing all logs and state
|
||||
let frame = document.createElement("iframe");
|
||||
let url = `${window['flingconfig'].API_BASE.replace(/\/+$/, '')}/api/fling/${props.fling.id}/data?derivedToken=${token}`;
|
||||
let url = `${process.env.REACT_APP_API.replace(/\/+$/, '')}/api/fling/${props.fling.id}/data?derivedToken=${token}`;
|
||||
log.trace(`Generated download url: ${url}`);
|
||||
frame.src = url;
|
||||
iframeContainer.current.appendChild(frame);
|
||||
|
|
|
@ -123,7 +123,7 @@ function Upload(props) {
|
|||
stopEvent(ev);
|
||||
ev.persist();
|
||||
|
||||
let maxSize = window['flingconfig'].FILESIZE;
|
||||
let maxSize = process.env.REACT_APP_FILESIZE;
|
||||
let evFiles = fileListToArray(ev.dataTransfer.files);
|
||||
|
||||
for (let i = evFiles.length - 1; i >= 0; i--) {
|
||||
|
@ -252,7 +252,7 @@ function Upload(props) {
|
|||
</div>
|
||||
<div className="upload-command-line m-2">
|
||||
<span className="total-upload">Total Size: {totalSize()}</span>
|
||||
<span className="total-upload">{`Max: ${prettifyBytes(window['flingconfig'].FILESIZE)}`}</span>
|
||||
<span className="total-upload">{`Max: ${prettifyBytes(process.env.REACT_APP_FILESIZE)}`}</span>
|
||||
<button className="btn btn-primary btn-upload" onClick={handleUpload}>Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -290,7 +290,7 @@ export default function FlingUserList(props) {
|
|||
// the browser downloads the file fine, it also reloads the page, hence
|
||||
// loosing all logs and state
|
||||
let frame = document.createElement("iframe");
|
||||
let url = `${window['flingconfig'].API_BASE.replace(/\/+$/, '')}/api/fling/${props.fling.id}/data?derivedToken=${token}`;
|
||||
let url = `${process.env.REACT_APP_API.replace(/\/+$/, '')}/api/fling/${props.fling.id}/data?derivedToken=${token}`;
|
||||
log.trace(`Generated download url: ${url}`);
|
||||
frame.src = url;
|
||||
setInProgress(false);
|
||||
|
|
|
@ -21,8 +21,8 @@ import * as serviceWorker from './serviceWorker';
|
|||
|
||||
/* Logging Setup */
|
||||
log.setDefaultLevel(log.levels.TRACE);
|
||||
if (window['flingconfig'].LOG_LEVEL) {
|
||||
log.setLevel(window['flingconfig'].LOG_LEVEL);
|
||||
if (process.env.REACT_APP_LOGLEVEL) {
|
||||
log.setLevel(process.env.REACT_APP_LOGLEVEL);
|
||||
}
|
||||
|
||||
/* Store setup */
|
||||
|
|
|
@ -9,7 +9,7 @@ import * as fc from '@fling/flingclient';
|
|||
*/
|
||||
let clientConfig = (token) => {
|
||||
let config = new fc.ApiClient();
|
||||
config.basePath = window['flingconfig'].API_BASE.replace(/\/+$/, '');
|
||||
config.basePath = process.env.REACT_APP_API.replace(/\/+$/, '');
|
||||
|
||||
token = token || sessionStorage.getItem('token');
|
||||
if (token) { config.authentications['bearer'].accessToken = token; }
|
||||
|
|
Loading…
Reference in a new issue