├── demo-ui
├── public
│ ├── testFs
│ │ ├── thisIsAnEmptyFile
│ │ ├── thisIsADir
│ │ │ ├── anotherDir
│ │ │ │ └── empty
│ │ │ ├── txt.txt
│ │ │ └── thisIsAlsoAMeme.jpg
│ │ ├── thisIsATXTWithNoExtension
│ │ ├── thisIsALongNameThatIsVeryVeryLongReallyLong.txt
│ │ ├── thisIsAMeme.jpg
│ │ ├── thisIsAPDF.pdf
│ │ ├── thisIsAudio.mp3
│ │ ├── thisIsABigPic.jpg
│ │ ├── thisIsAVideo.mp4
│ │ ├── thisIsUnicode汉字卡片.jpg
│ │ ├── thisIsHTML.html
│ │ └── thisIsASourceFile.go
│ ├── favicon.png
│ ├── mocks
│ │ ├── ls3.json
│ │ ├── features.json
│ │ ├── ls1.json
│ │ ├── ls2.json
│ │ └── ls0.json
│ ├── icons
│ │ ├── 16x16
│ │ │ ├── text-x-generic.svg
│ │ │ ├── video-x-generic.svg
│ │ │ ├── audio-x-generic.svg
│ │ │ ├── image-x-generic.svg
│ │ │ ├── application-octet-stream.svg
│ │ │ ├── file-manager.svg
│ │ │ └── application-pdf.svg
│ │ └── 48x48
│ │ │ ├── text-x-generic.svg
│ │ │ ├── audio-x-generic.svg
│ │ │ ├── video-x-generic.svg
│ │ │ ├── application-pdf.svg
│ │ │ └── image-x-generic.svg
│ └── index.html
├── src
│ ├── global.d.ts
│ ├── SVG
│ │ ├── IconDownload.svelte
│ │ ├── IconList.svelte
│ │ ├── IconSortSizeAsc.svelte
│ │ ├── IconSortSizeDesc.svelte
│ │ ├── IconGrid.svelte
│ │ ├── IconSortAlphAsc.svelte
│ │ ├── IconSortAlphDesc.svelte
│ │ ├── IconNewFolder.svelte
│ │ ├── IconSortDateDesc.svelte
│ │ ├── IconLogout.svelte
│ │ ├── IconReload.svelte
│ │ ├── IconSortDateAsc.svelte
│ │ ├── IconPaste.svelte
│ │ ├── IconUnpaste.svelte
│ │ ├── IconUpload.svelte
│ │ ├── IconShare.svelte
│ │ ├── IconLink.svelte
│ │ └── IconInvalidLink.svelte
│ ├── Utils.svelte
│ ├── main.ts
│ ├── Snippets
│ │ ├── TextShower.svelte
│ │ └── Breadcrumb.svelte
│ ├── FileManager
│ │ ├── Grid.svelte
│ │ ├── GridCell.svelte
│ │ ├── ListRow.svelte
│ │ └── List.svelte
│ ├── Preview
│ │ ├── Preview.svelte
│ │ ├── FullSize.svelte
│ │ └── FullScreen.svelte
│ ├── MimeTypes.svelte
│ ├── global.css
│ └── Auth.svelte
├── tsconfig.json
├── package.json
└── rollup.config.js
├── web-ui
├── src
│ ├── global.d.ts
│ ├── SVG
│ │ ├── IconDownload.svelte
│ │ ├── IconList.svelte
│ │ ├── IconSortSizeAsc.svelte
│ │ ├── IconSortSizeDesc.svelte
│ │ ├── IconGrid.svelte
│ │ ├── IconSortAlphAsc.svelte
│ │ ├── IconSortAlphDesc.svelte
│ │ ├── IconNewFolder.svelte
│ │ ├── IconSortDateAsc.svelte
│ │ ├── IconSortDateDesc.svelte
│ │ ├── IconLogout.svelte
│ │ ├── IconReload.svelte
│ │ ├── IconPaste.svelte
│ │ ├── IconUnpaste.svelte
│ │ ├── IconUpload.svelte
│ │ ├── IconShare.svelte
│ │ ├── IconLink.svelte
│ │ └── IconInvalidLink.svelte
│ ├── Utils.svelte
│ ├── main.ts
│ ├── Snippets
│ │ ├── TextShower.svelte
│ │ └── Breadcrumb.svelte
│ ├── FileManager
│ │ ├── Grid.svelte
│ │ ├── GridCell.svelte
│ │ ├── ListRow.svelte
│ │ └── List.svelte
│ ├── Preview
│ │ ├── Preview.svelte
│ │ ├── FullSize.svelte
│ │ └── FullScreen.svelte
│ ├── MimeTypes.svelte
│ ├── global.css
│ └── Auth.svelte
├── public
│ ├── favicon.png
│ ├── icons
│ │ ├── 16x16
│ │ │ ├── text-x-generic.svg
│ │ │ ├── video-x-generic.svg
│ │ │ ├── audio-x-generic.svg
│ │ │ ├── image-x-generic.svg
│ │ │ ├── application-octet-stream.svg
│ │ │ ├── file-manager.svg
│ │ │ └── application-pdf.svg
│ │ └── 48x48
│ │ │ ├── text-x-generic.svg
│ │ │ ├── audio-x-generic.svg
│ │ │ ├── video-x-generic.svg
│ │ │ ├── application-pdf.svg
│ │ │ └── image-x-generic.svg
│ └── index.html
├── tsconfig.json
├── build_notes.md
├── package.json
└── rollup.config.js
├── version.json
├── ROADMAP.md
├── src
├── static
│ ├── favicon.png
│ ├── icons
│ │ ├── 16x16
│ │ │ ├── text-x-generic.svg
│ │ │ ├── video-x-generic.svg
│ │ │ ├── audio-x-generic.svg
│ │ │ ├── image-x-generic.svg
│ │ │ ├── application-octet-stream.svg
│ │ │ ├── file-manager.svg
│ │ │ └── application-pdf.svg
│ │ └── 48x48
│ │ │ ├── text-x-generic.svg
│ │ │ ├── audio-x-generic.svg
│ │ │ ├── video-x-generic.svg
│ │ │ ├── application-pdf.svg
│ │ │ └── image-x-generic.svg
│ └── index.html
├── go.mod
├── files
│ ├── file_users_windows.go
│ ├── file_users.go
│ ├── mimetypes.go
│ └── files.go
├── commons
│ └── commons.go
├── crypgo
│ └── crypgo.go
└── go.sum
├── .gitignore
├── Dockerfile
├── CONTRIBUTING.md
├── Makefile
└── Changelog.md
/demo-ui/public/testFs/thisIsAnEmptyFile:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsADir/anotherDir/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsADir/txt.txt:
--------------------------------------------------------------------------------
1 | ciao
2 |
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsATXTWithNoExtension:
--------------------------------------------------------------------------------
1 | ciao
2 |
--------------------------------------------------------------------------------
/demo-ui/src/global.d.ts:
--------------------------------------------------------------------------------
1 | ///
--------------------------------------------------------------------------------
/web-ui/src/global.d.ts:
--------------------------------------------------------------------------------
1 | ///
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsALongNameThatIsVeryVeryLongReallyLong.txt:
--------------------------------------------------------------------------------
1 | Ciao
--------------------------------------------------------------------------------
/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "v0.8.0",
3 | "releaseCode": 29
4 | }
--------------------------------------------------------------------------------
/ROADMAP.md:
--------------------------------------------------------------------------------
1 | #### [Moved to Wiki](https://github.com/proofrock/pupcloud/wiki/Roadmap)
--------------------------------------------------------------------------------
/src/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/src/static/favicon.png
--------------------------------------------------------------------------------
/demo-ui/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/demo-ui/public/favicon.png
--------------------------------------------------------------------------------
/web-ui/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/web-ui/public/favicon.png
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsAMeme.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/demo-ui/public/testFs/thisIsAMeme.jpg
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsAPDF.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/demo-ui/public/testFs/thisIsAPDF.pdf
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsAudio.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/demo-ui/public/testFs/thisIsAudio.mp3
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsABigPic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/demo-ui/public/testFs/thisIsABigPic.jpg
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsAVideo.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/demo-ui/public/testFs/thisIsAVideo.mp4
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsUnicode汉字卡片.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/demo-ui/public/testFs/thisIsUnicode汉字卡片.jpg
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsADir/thisIsAlsoAMeme.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proofrock/pupcloud/HEAD/demo-ui/public/testFs/thisIsADir/thisIsAlsoAMeme.jpg
--------------------------------------------------------------------------------
/demo-ui/public/mocks/ls3.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": [
3 | "thisIsADir",
4 | "anotherDir",
5 | "a3rdDir"
6 | ],
7 | "items": []
8 | }
--------------------------------------------------------------------------------
/src/static/icons/16x16/text-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/16x16/text-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web-ui/public/icons/16x16/text-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/static/icons/16x16/video-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/16x16/video-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/static/icons/16x16/audio-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web-ui/public/icons/16x16/video-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/16x16/audio-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web-ui/public/icons/16x16/audio-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web-ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/svelte/tsconfig.json",
3 | "include": [
4 | "src/**/*"
5 | ],
6 | "exclude": [
7 | "node_modules/*",
8 | "__sapper__/*",
9 | "public/*"
10 | ],
11 | "compilerOptions": {
12 | "sourceMap": true,
13 | }
14 | }
--------------------------------------------------------------------------------
/demo-ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/svelte/tsconfig.json",
3 | "include": [
4 | "src/**/*"
5 | ],
6 | "exclude": [
7 | "node_modules/*",
8 | "__sapper__/*",
9 | "public/*"
10 | ],
11 | "compilerOptions": {
12 | "sourceMap": true,
13 | }
14 | }
--------------------------------------------------------------------------------
/demo-ui/public/mocks/features.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "v0.8.0",
3 | "title": "🐶 Pupcloud Demo",
4 | "readOnly": false,
5 | "maxReqSize": 1048576,
6 | "hasPassword": false,
7 | "sharing": {
8 | "allowRW": true,
9 | "profiles": [
10 | "John",
11 | "Mary",
12 | "Loreena"
13 | ]
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/static/icons/16x16/image-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/16x16/image-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web-ui/public/icons/16x16/image-x-generic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconDownload.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconDownload.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | pupcloud
4 | /bin
5 | /testFs
6 | /.vscode
7 | /.idea
8 | /TODO.md
9 |
10 | /web-ui/node_modules/
11 | /web-ui/public/build/
12 |
13 | /demo-ui/node_modules/
14 |
15 | # Binaries for programs and plugins
16 | *.exe
17 | *.exe~
18 | *.dll
19 | *.so
20 | *.dylib
21 |
22 | # Test binary, built with `go test -c`
23 | *.test
24 |
25 | # Output of the go coverage tool, specifically when used with LiteIDE
26 | *.out
27 |
28 | # Dependency directories (remove the comment below to include it)
29 | # vendor/
30 |
--------------------------------------------------------------------------------
/demo-ui/src/Utils.svelte:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/web-ui/src/Utils.svelte:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/16x16/application-octet-stream.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/static/icons/16x16/application-octet-stream.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web-ui/public/icons/16x16/application-octet-stream.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine:edge AS build
2 |
3 | RUN apk update
4 | RUN apk upgrade
5 | RUN apk add --update go git make
6 | WORKDIR /app
7 | ENV GOPATH /app
8 | RUN git clone https://github.com/proofrock/pupcloud
9 | WORKDIR /app/pupcloud
10 | RUN make build-static
11 |
12 | FROM alpine:latest
13 |
14 | ENV PUID=1000
15 | ENV PGID=1000
16 | EXPOSE 12321
17 | VOLUME /data
18 |
19 | COPY --from=build /app/pupcloud/bin/pupcloud /
20 |
21 | RUN addgroup -g $PGID pup
22 | RUN adduser -u $PUID -G pup -D pup
23 |
24 | USER pup:pup
25 |
26 | ENTRYPOINT ["/pupcloud", "-r", "/data"]
27 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconList.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconList.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconSortSizeAsc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconSortSizeDesc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconSortSizeAsc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconSortSizeDesc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconGrid.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconGrid.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconSortAlphAsc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconSortAlphDesc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconSortAlphAsc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconSortAlphDesc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/src/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/proofrock/pupcloud
2 |
3 | go 1.18
4 |
5 | require (
6 | github.com/gofiber/fiber/v2 v2.33.0
7 | github.com/otiai10/copy v1.7.0
8 | github.com/spf13/pflag v1.0.5
9 | golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122
10 | golang.org/x/exp v0.0.0-20220428152302-39d4317da171
11 | )
12 |
13 | require (
14 | github.com/andybalholm/brotli v1.0.4 // indirect
15 | github.com/klauspost/compress v1.15.3 // indirect
16 | github.com/valyala/bytebufferpool v1.0.0 // indirect
17 | github.com/valyala/fasthttp v1.36.0 // indirect
18 | github.com/valyala/tcplisten v1.0.0 // indirect
19 | golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
20 | )
21 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconNewFolder.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconNewFolder.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/public/mocks/ls1.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": [
3 | "thisIsADir"
4 | ],
5 | "items": [
6 | {
7 | "mimeType": "#directory",
8 | "name": "anotherDir",
9 | "size": -1,
10 | "chDate": 1645859613,
11 | "owner": "mano (1000)",
12 | "group": "mano (1000)",
13 | "permissions": "drwxr-xr-x"
14 | },
15 | {
16 | "mimeType": "text/plain",
17 | "name": "txt.txt",
18 | "size": 5,
19 | "chDate": 1632594862,
20 | "owner": "mano (1000)",
21 | "group": "mano (1000)",
22 | "permissions": "-rw-r--r--"
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconSortDateDesc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconSortDateAsc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconSortDateDesc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconLogout.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconReload.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconSortDateAsc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconLogout.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconReload.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconPaste.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/src/static/icons/16x16/file-manager.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconPaste.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/16x16/file-manager.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/web-ui/public/icons/16x16/file-manager.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/demo-ui/public/mocks/ls2.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": [
3 | "thisIsADir",
4 | "anotherDir"
5 | ],
6 | "items": [
7 | {
8 | "mimeType": "#directory",
9 | "name": "a3rdDir",
10 | "size": -1,
11 | "chDate": 1645297788,
12 | "owner": "mano (1000)",
13 | "group": "mano (1000)",
14 | "permissions": "drwxr-xr-x"
15 | },
16 | {
17 | "mimeType": "text/plain",
18 | "name": "empty",
19 | "size": 0,
20 | "chDate": 1645859613,
21 | "owner": "mano (1000)",
22 | "group": "mano (1000)",
23 | "permissions": "-rw-r--r--"
24 | }
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconUnpaste.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconUnpaste.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconUpload.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconUpload.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/build_notes.md:
--------------------------------------------------------------------------------
1 | ## Change port of `run dev`
2 |
3 | In `package.json`:
4 |
5 | ```json
6 | "scripts": {
7 | [...]
8 | "start": "sirv public --no-clear --port 17178 --host",
9 | ```
10 |
11 | ## Rollup: avoid typescript map warning
12 |
13 | https://stackoverflow.com/questions/63128597/how-to-get-rid-of-the-rollup-plugin-typescript-rollup-sourcemap-option-must
14 |
15 | Change to `rollup.config.js`:
16 |
17 | ```
18 | - output: {
19 | - sourcemap: true,
20 | + output: {
21 | + sourcemap: !production,
22 | ```
23 |
24 | **NOTE**: this disables source maps in production. Not what you want?
25 |
26 | ## Include css framework
27 |
28 | https://stackoverflow.com/questions/56483209/import-css-in-node-modules-to-svelte
29 |
30 | In `App.svelte`:
31 |
32 | ```
33 | import "../node_modules/axentix/dist/axentix.min.css";
34 | ```
35 |
36 | Where js module is needed:
37 |
38 | ```
39 | import { Dropdown, destroy } from "axentix";
40 | ```
41 |
--------------------------------------------------------------------------------
/demo-ui/src/main.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 |
18 | import Auth from "./Auth.svelte";
19 |
20 | const app = new Auth({
21 | target: document.getElementById("app"),
22 | });
23 |
24 | export default app;
25 |
--------------------------------------------------------------------------------
/web-ui/src/main.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 |
18 | import Auth from "./Auth.svelte";
19 |
20 | const app = new Auth({
21 | target: document.getElementById("app"),
22 | });
23 |
24 | export default app;
25 |
--------------------------------------------------------------------------------
/src/files/file_users_windows.go:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 | package files
18 |
19 | // Windows doesn't have this concept
20 | func getUserAndGroup(path string) (string, string) {
21 | return "n.a.", "n.a."
22 | }
23 |
--------------------------------------------------------------------------------
/web-ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pupcloud",
3 | "version": "0.8.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "rollup -c",
7 | "dev": "rollup -c -w",
8 | "start": "sirv public --no-clear --port 17178 --host",
9 | "check": "svelte-check --tsconfig ./tsconfig.json"
10 | },
11 | "devDependencies": {
12 | "@rollup/plugin-commonjs": "^17.0.0",
13 | "@rollup/plugin-node-resolve": "^11.0.0",
14 | "@rollup/plugin-typescript": "^8.0.0",
15 | "@tsconfig/svelte": "^2.0.0",
16 | "rollup": "^2.3.4",
17 | "rollup-plugin-css-only": "^3.1.0",
18 | "rollup-plugin-livereload": "^2.0.0",
19 | "rollup-plugin-svelte": "^7.0.0",
20 | "rollup-plugin-terser": "^7.0.2",
21 | "svelte": "^3.0.0",
22 | "svelte-check": "^2.0.0",
23 | "svelte-preprocess": "^4.0.0",
24 | "tslib": "^2.0.0",
25 | "typescript": "^4.0.0"
26 | },
27 | "dependencies": {
28 | "axentix": "^2.0.1",
29 | "hammerjs": "^2.0.8",
30 | "sirv-cli": "^2.0.0",
31 | "sweetalert2": "^11.4.4"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/demo-ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pupcloud",
3 | "version": "0.8.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "rollup -c",
7 | "dev": "rollup -c -w",
8 | "start": "sirv public --no-clear --port 17178 --host",
9 | "check": "svelte-check --tsconfig ./tsconfig.json"
10 | },
11 | "devDependencies": {
12 | "@rollup/plugin-commonjs": "^17.0.0",
13 | "@rollup/plugin-node-resolve": "^11.0.0",
14 | "@rollup/plugin-typescript": "^8.0.0",
15 | "@tsconfig/svelte": "^2.0.0",
16 | "rollup": "^2.3.4",
17 | "rollup-plugin-css-only": "^3.1.0",
18 | "rollup-plugin-livereload": "^2.0.0",
19 | "rollup-plugin-svelte": "^7.0.0",
20 | "rollup-plugin-terser": "^7.0.2",
21 | "svelte": "^3.0.0",
22 | "svelte-check": "^2.0.0",
23 | "svelte-preprocess": "^4.0.0",
24 | "tslib": "^2.0.0",
25 | "typescript": "^4.0.0"
26 | },
27 | "dependencies": {
28 | "axentix": "^2.0.1",
29 | "hammerjs": "^2.0.8",
30 | "sirv-cli": "^2.0.0",
31 | "sweetalert2": "^11.4.4"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue,
4 | email, or any other method with the owners of this repository before making a change.
5 |
6 | Please note we have a code of conduct, please follow it in all your interactions with the project.
7 |
8 | ## Pull Request Process
9 |
10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a
11 | build.
12 | 2. Update the README.md with details of changes to the interface, this includes new environment
13 | variables, exposed ports, useful file locations and container parameters.
14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this
15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
17 | do not have permission to do that, you may request the second reviewer to merge it for you.
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconShare.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconShare.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconLink.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconLink.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/demo-ui/src/SVG/IconInvalidLink.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
17 |
--------------------------------------------------------------------------------
/web-ui/src/SVG/IconInvalidLink.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
17 |
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsHTML.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Pupcloud
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/demo-ui/src/Snippets/TextShower.svelte:
--------------------------------------------------------------------------------
1 |
31 |
32 |
35 |
--------------------------------------------------------------------------------
/web-ui/src/Snippets/TextShower.svelte:
--------------------------------------------------------------------------------
1 |
31 |
32 |
35 |
--------------------------------------------------------------------------------
/src/static/icons/16x16/application-pdf.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web-ui/public/icons/16x16/application-pdf.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/16x16/application-pdf.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Pupcloud
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/demo-ui/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Pupcloud
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/web-ui/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Pupcloud
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/files/file_users.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 |
3 | /*
4 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
5 | *
6 | * PupCloud is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PupCloud is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with PupCloud. If not, see .
18 | */
19 | package files
20 |
21 | import (
22 | "fmt"
23 | "os"
24 | "os/user"
25 | "strconv"
26 | "syscall"
27 | )
28 |
29 | // Adapted from https://pirivan.gitlab.io/post/how-to-retrieve-file-ownership-information-in-golang/
30 | func getUserAndGroup(path string) (string, string) {
31 | fileInfo, err := os.Stat(path)
32 | if err != nil {
33 | return "--", "--"
34 | }
35 |
36 | stat, ok := fileInfo.Sys().(*syscall.Stat_t)
37 | if !ok {
38 | return "--", "--"
39 | }
40 |
41 | usr, err := user.LookupId(strconv.FormatUint(uint64(stat.Uid), 10))
42 | if err != nil {
43 | return "--", "--"
44 | }
45 | group, err := user.LookupGroupId(strconv.FormatUint(uint64(stat.Gid), 10))
46 | if err != nil {
47 | return "--", "--"
48 | }
49 |
50 | return fmt.Sprintf("%s (%s)", usr.Username, usr.Uid),
51 | fmt.Sprintf("%s (%s)", group.Name, group.Gid)
52 | }
53 |
--------------------------------------------------------------------------------
/demo-ui/src/FileManager/Grid.svelte:
--------------------------------------------------------------------------------
1 |
33 |
34 |
35 | {#each itemList as item, i (item.uuid)}
36 |
38 |
40 |
41 |
42 | {/each}
43 |
44 |
--------------------------------------------------------------------------------
/web-ui/src/FileManager/Grid.svelte:
--------------------------------------------------------------------------------
1 |
33 |
34 |
35 | {#each itemList as item, i (item.uuid)}
36 |
38 |
40 |
41 |
42 | {/each}
43 |
44 |
--------------------------------------------------------------------------------
/src/static/icons/48x48/text-x-generic.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/48x48/text-x-generic.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/web-ui/public/icons/48x48/text-x-generic.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/demo-ui/src/Preview/Preview.svelte:
--------------------------------------------------------------------------------
1 |
41 |
42 | {#if mode == 0}
43 |
44 | {:else if mode == 1}
45 |
46 | {:else}
47 |
48 | {/if}
49 |
--------------------------------------------------------------------------------
/web-ui/src/Preview/Preview.svelte:
--------------------------------------------------------------------------------
1 |
41 |
42 | {#if mode == 0}
43 |
44 | {:else if mode == 1}
45 |
46 | {:else}
47 |
48 | {/if}
49 |
--------------------------------------------------------------------------------
/demo-ui/src/Preview/FullSize.svelte:
--------------------------------------------------------------------------------
1 |
46 |
47 |
54 |
55 |
56 |
58 |
--------------------------------------------------------------------------------
/web-ui/src/Preview/FullSize.svelte:
--------------------------------------------------------------------------------
1 |
46 |
47 |
54 |
55 |
56 |
58 |
--------------------------------------------------------------------------------
/demo-ui/src/MimeTypes.svelte:
--------------------------------------------------------------------------------
1 |
63 |
--------------------------------------------------------------------------------
/web-ui/src/MimeTypes.svelte:
--------------------------------------------------------------------------------
1 |
63 |
--------------------------------------------------------------------------------
/src/files/mimetypes.go:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 |
18 | package files
19 |
20 | import (
21 | "mime"
22 | "net/http"
23 | "os"
24 | "path/filepath"
25 | "strings"
26 | "sync"
27 | )
28 |
29 | const mimeTypeTextPlain = "text/plain"
30 |
31 | var fileNames sync.Map
32 | var fileExts sync.Map
33 |
34 | func init() {
35 | fileNames.Store("Dockerfile", mimeTypeTextPlain)
36 | fileNames.Store("Makefile", mimeTypeTextPlain)
37 | fileNames.Store("LICENSE", mimeTypeTextPlain)
38 | fileNames.Store(".gitignore", mimeTypeTextPlain)
39 |
40 | fileExts.Store("txt", mimeTypeTextPlain)
41 | fileExts.Store("md", "text/markdown")
42 | }
43 |
44 | // Adapted from https://golangcode.com/get-the-content-type-of-file/
45 | func getFileContentType(path string) string {
46 | base := filepath.Base(path)
47 | ext := strings.ToLower(filepath.Ext(path))
48 |
49 | // First, local resolution
50 | if val, ok := fileNames.Load(base); ok {
51 | return val.(string)
52 | }
53 | if val, ok := fileExts.Load(ext); ok {
54 | return val.(string)
55 | }
56 |
57 | // Lookup with Go extensions resolutor
58 | if ext != "" {
59 | contentType := mime.TypeByExtension(ext)
60 | if contentType != "" {
61 | return contentType
62 | }
63 | }
64 |
65 | // If inconclusive, look up by contents
66 | file, err := os.Open(path)
67 | if err != nil {
68 | return mimeTypeTextPlain
69 | }
70 | defer file.Close()
71 |
72 | buffer := make([]byte, 512)
73 |
74 | _, err = file.Read(buffer)
75 | if err != nil {
76 | return mimeTypeTextPlain
77 | }
78 |
79 | contentType := http.DetectContentType(buffer)
80 |
81 | return contentType
82 | }
83 |
--------------------------------------------------------------------------------
/demo-ui/rollup.config.js:
--------------------------------------------------------------------------------
1 | import svelte from 'rollup-plugin-svelte';
2 | import commonjs from '@rollup/plugin-commonjs';
3 | import resolve from '@rollup/plugin-node-resolve';
4 | import livereload from 'rollup-plugin-livereload';
5 | import { terser } from 'rollup-plugin-terser';
6 | import sveltePreprocess from 'svelte-preprocess';
7 | import typescript from '@rollup/plugin-typescript';
8 | import css from 'rollup-plugin-css-only';
9 |
10 | const production = !process.env.ROLLUP_WATCH;
11 |
12 | function serve() {
13 | let server;
14 |
15 | function toExit() {
16 | if (server) server.kill(0);
17 | }
18 |
19 | return {
20 | writeBundle() {
21 | if (server) return;
22 | server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
23 | stdio: ['ignore', 'inherit', 'inherit'],
24 | shell: true
25 | });
26 |
27 | process.on('SIGTERM', toExit);
28 | process.on('exit', toExit);
29 | }
30 | };
31 | }
32 |
33 | export default {
34 | input: 'src/main.ts',
35 | output: {
36 | sourcemap: true,
37 | format: 'iife',
38 | name: 'app',
39 | file: 'public/build/bundle.js'
40 | },
41 | plugins: [
42 | svelte({
43 | preprocess: sveltePreprocess({ sourceMap: !production }),
44 | compilerOptions: {
45 | // enable run-time checks when not in production
46 | dev: !production
47 | }
48 | }),
49 | // we'll extract any component CSS out into
50 | // a separate file - better for performance
51 | css({ output: 'bundle.css' }),
52 |
53 | // If you have external dependencies installed from
54 | // npm, you'll most likely need these plugins. In
55 | // some cases you'll need additional configuration -
56 | // consult the documentation for details:
57 | // https://github.com/rollup/plugins/tree/master/packages/commonjs
58 | resolve({
59 | browser: true,
60 | dedupe: ['svelte']
61 | }),
62 | commonjs(),
63 | typescript({
64 | sourceMap: !production,
65 | inlineSources: !production
66 | }),
67 |
68 | // In dev mode, call `npm run start` once
69 | // the bundle has been generated
70 | !production && serve(),
71 |
72 | // Watch the `public` directory and refresh the
73 | // browser on changes when not in production
74 | !production && livereload('public'),
75 |
76 | // If we're building for production (npm run build
77 | // instead of npm run dev), minify
78 | production && terser()
79 | ],
80 | watch: {
81 | clearScreen: false
82 | }
83 | };
84 |
--------------------------------------------------------------------------------
/web-ui/rollup.config.js:
--------------------------------------------------------------------------------
1 | import svelte from 'rollup-plugin-svelte';
2 | import commonjs from '@rollup/plugin-commonjs';
3 | import resolve from '@rollup/plugin-node-resolve';
4 | import livereload from 'rollup-plugin-livereload';
5 | import { terser } from 'rollup-plugin-terser';
6 | import sveltePreprocess from 'svelte-preprocess';
7 | import typescript from '@rollup/plugin-typescript';
8 | import css from 'rollup-plugin-css-only';
9 |
10 | const production = !process.env.ROLLUP_WATCH;
11 |
12 | function serve() {
13 | let server;
14 |
15 | function toExit() {
16 | if (server) server.kill(0);
17 | }
18 |
19 | return {
20 | writeBundle() {
21 | if (server) return;
22 | server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
23 | stdio: ['ignore', 'inherit', 'inherit'],
24 | shell: true
25 | });
26 |
27 | process.on('SIGTERM', toExit);
28 | process.on('exit', toExit);
29 | }
30 | };
31 | }
32 |
33 | export default {
34 | input: 'src/main.ts',
35 | output: {
36 | sourcemap: !production,
37 | format: 'iife',
38 | name: 'app',
39 | file: 'public/build/bundle.js'
40 | },
41 | plugins: [
42 | svelte({
43 | preprocess: sveltePreprocess({ sourceMap: !production }),
44 | compilerOptions: {
45 | // enable run-time checks when not in production
46 | dev: !production
47 | }
48 | }),
49 | // we'll extract any component CSS out into
50 | // a separate file - better for performance
51 | css({ output: 'bundle.css' }),
52 |
53 | // If you have external dependencies installed from
54 | // npm, you'll most likely need these plugins. In
55 | // some cases you'll need additional configuration -
56 | // consult the documentation for details:
57 | // https://github.com/rollup/plugins/tree/master/packages/commonjs
58 | resolve({
59 | browser: true,
60 | dedupe: ['svelte']
61 | }),
62 | commonjs(),
63 | typescript({
64 | sourceMap: !production,
65 | inlineSources: !production
66 | }),
67 |
68 | // In dev mode, call `npm run start` once
69 | // the bundle has been generated
70 | !production && serve(),
71 |
72 | // Watch the `public` directory and refresh the
73 | // browser on changes when not in production
74 | !production && livereload('public'),
75 |
76 | // If we're building for production (npm run build
77 | // instead of npm run dev), minify
78 | production && terser()
79 | ],
80 | watch: {
81 | clearScreen: false
82 | }
83 | };
84 |
--------------------------------------------------------------------------------
/web-ui/src/FileManager/GridCell.svelte:
--------------------------------------------------------------------------------
1 |
32 |
33 |
34 |
35 |
36 |
{item.size}
37 |
38 |
39 |
40 |
41 |
42 | {#if !!item.icon[1]}
43 |
![{item.icon[0]}](icons/48x48/{item.icon[0]}.svg)
44 | {#if item.icon[1] == "link"}
45 |
46 | {:else}
47 |
48 | {/if}
49 | {:else}
50 |
![{item.icon[0]}](icons/48x48/{item.icon[0]}.svg)
51 | {/if}
52 |
53 |
54 |
{item.name}
55 |
56 |
57 |
--------------------------------------------------------------------------------
/demo-ui/src/FileManager/GridCell.svelte:
--------------------------------------------------------------------------------
1 |
32 |
33 |
34 |
35 |
36 |
{item.size}
37 |
38 |
39 |
40 |
41 |
42 | {#if !!item.icon[1]}
43 |
![{item.icon[0]}](icons/48x48/{item.icon[0]}.svg)
44 | {#if item.icon[1] == "link"}
45 |
46 | {:else}
47 |
48 | {/if}
49 | {:else}
50 |
![{item.icon[0]}](icons/48x48/{item.icon[0]}.svg)
51 | {/if}
52 |
53 |
54 |
{item.name}
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/static/icons/48x48/audio-x-generic.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/48x48/audio-x-generic.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/web-ui/public/icons/48x48/audio-x-generic.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/src/commons/commons.go:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 | package commons
18 |
19 | import (
20 | "bytes"
21 | "encoding/binary"
22 | "fmt"
23 | "github.com/proofrock/pupcloud/crypgo"
24 | "os"
25 | )
26 |
27 | type ErrorRes struct {
28 | Code int `json:"code"`
29 | Message string `json:"msg"`
30 | }
31 |
32 | func Abort(msg string) {
33 | fmt.Fprint(os.Stderr, msg, "\n")
34 | os.Exit(1)
35 | }
36 |
37 | func DirExists(filename string) bool {
38 | info, err := os.Stat(filename)
39 | return !os.IsNotExist(err) && info.IsDir()
40 | }
41 |
42 | func boolToBytes(b bool) byte {
43 | if b {
44 | return 1
45 | }
46 | return 0
47 | }
48 |
49 | func intToBytes(number uint32) []byte {
50 | var arr [4]byte
51 | binary.BigEndian.PutUint32(arr[0:4], number)
52 | return arr[:]
53 | }
54 |
55 | func bytesToInt(data []byte) uint32 {
56 | return binary.BigEndian.Uint32(data)
57 | }
58 |
59 | func EncryptSharingURL(profile, pwd, path, root string, readOnly bool, date *uint32) (string, error) {
60 | var b bytes.Buffer
61 | b.Write([]byte{boolToBytes(readOnly)})
62 | b.WriteString(path)
63 | b.Write([]byte{byte(0x00)})
64 | b.Write([]byte{boolToBytes(date != nil)})
65 | if date != nil {
66 | b.Write(intToBytes(*date))
67 | }
68 | return crypgo.EncryptBytes(pwd, b.Bytes(), []byte(profile+"|"+root))
69 | }
70 |
71 | func DecryptSharingURL(profile, pwd, root, encoded string) (path string, readOnly bool, date *uint32, err error) {
72 | plain, err := crypgo.DecryptBytes(pwd, encoded, []byte(profile+"|"+root))
73 | if err != nil {
74 | return
75 | }
76 |
77 | b := bytes.NewBuffer(plain)
78 |
79 | _readOnly, _ := b.ReadByte()
80 | readOnly = _readOnly == 1
81 |
82 | pathBytes, _ := b.ReadBytes(byte(0x00))
83 | path = string(pathBytes[:len(pathBytes)-1])
84 |
85 | if _hasDate, _ := b.ReadByte(); _hasDate == 1 {
86 | bDate := make([]byte, 4)
87 | b.Read(bDate)
88 | _date := bytesToInt(bDate)
89 | date = &_date
90 | }
91 |
92 | return
93 | }
94 |
--------------------------------------------------------------------------------
/demo-ui/src/FileManager/ListRow.svelte:
--------------------------------------------------------------------------------
1 |
36 |
37 |
58 |
59 |
60 |
61 |
62 |
63 | {item.icon[2]}{item.name}
65 |
66 |
67 | {item.icon[2]}{item.name}
69 |
70 | |
71 | {item.size} |
72 | {item.chDate} |
73 |
74 |
75 |
76 |
77 | |
78 |
79 |
--------------------------------------------------------------------------------
/web-ui/src/FileManager/ListRow.svelte:
--------------------------------------------------------------------------------
1 |
36 |
37 |
58 |
59 |
60 |
61 |
62 |
63 | {item.icon[2]}{item.name}
65 |
66 |
67 | {item.icon[2]}{item.name}
69 |
70 | |
71 | {item.size} |
72 | {item.chDate} |
73 |
74 |
75 |
76 |
77 | |
78 |
79 |
--------------------------------------------------------------------------------
/demo-ui/src/global.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 |
18 | /*
19 | Demo-5 in
20 | https://stackoverflow.com/questions/26150963/how-to-make-this-css-hamburger-menu-entirely-clickable/26151061#26151061
21 | */
22 | .menu {
23 | width: 16px;
24 | height: 14px;
25 | position: relative;
26 | display: inline-block;
27 | top: 3px;
28 | background-size: 5px 5px;
29 | background-image: -webkit-linear-gradient(rgba(0, 0, 0, 1) 50%, transparent 50%, transparent);
30 | background-image: -moz-linear-gradient(rgba(0, 0, 0, 1) 50%, transparent 50%, transparent);
31 | background-image: linear-gradient(rgba(0, 0, 0, 1) 50%, transparent 50%, transparent);
32 | }
33 |
34 | .triangle {
35 | position: relative;
36 | top: 12px;
37 | border-left: 6px solid transparent;
38 | border-right: 6px solid transparent;
39 | border-top: 6px solid black;
40 | }
41 |
42 | .blanket {
43 | position: fixed;
44 | width: 100%;
45 | height: 100%;
46 | left: 0px;
47 | top: 0px;
48 | background: #444444;
49 | z-index: 0;
50 | padding: 0px;
51 | }
52 |
53 | .blanket-clear {
54 | background: #888888;
55 | }
56 |
57 | .blanket-very-clear {
58 | background: #CCCCCC;
59 | }
60 |
61 | .centered-slide {
62 | position: absolute;
63 | top: 50%;
64 | left: 50%;
65 | transform: translate(-50%, -50%);
66 | }
67 |
68 | footer {
69 | position: fixed;
70 | bottom: 0;
71 | z-index: 65532 !important;
72 | }
73 |
74 | nav {
75 | z-index: 65532 !important;
76 | }
77 |
78 | .ax-overlay {
79 | z-index: 65533 !important;
80 | }
81 |
82 | .modal {
83 | z-index: 65534 !important;
84 | }
85 |
86 | .swal2-container {
87 | z-index: 65535 !important;
88 | }
89 |
90 | .pup-a {
91 | font-weight: bold;
92 | text-decoration: underline dotted;
93 | }
94 |
95 | .pup-a-nobold {
96 | text-decoration: underline dotted;
97 | }
98 |
99 | .ellipsis {
100 | white-space: nowrap;
101 | overflow: hidden;
102 | text-overflow: ellipsis;
103 | }
104 |
105 | .wid220 {
106 | width: 220px;
107 | }
108 |
109 | .noSelect {
110 | user-select: none;
111 | }
112 |
--------------------------------------------------------------------------------
/web-ui/src/global.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 |
18 | /*
19 | Demo-5 in
20 | https://stackoverflow.com/questions/26150963/how-to-make-this-css-hamburger-menu-entirely-clickable/26151061#26151061
21 | */
22 | .menu {
23 | width: 16px;
24 | height: 14px;
25 | position: relative;
26 | display: inline-block;
27 | top: 3px;
28 | background-size: 5px 5px;
29 | background-image: -webkit-linear-gradient(rgba(0, 0, 0, 1) 50%, transparent 50%, transparent);
30 | background-image: -moz-linear-gradient(rgba(0, 0, 0, 1) 50%, transparent 50%, transparent);
31 | background-image: linear-gradient(rgba(0, 0, 0, 1) 50%, transparent 50%, transparent);
32 | }
33 |
34 | .triangle {
35 | position: relative;
36 | top: 12px;
37 | border-left: 6px solid transparent;
38 | border-right: 6px solid transparent;
39 | border-top: 6px solid black;
40 | }
41 |
42 | .blanket {
43 | position: fixed;
44 | width: 100%;
45 | height: 100%;
46 | left: 0px;
47 | top: 0px;
48 | background: #444444;
49 | z-index: 0;
50 | padding: 0px;
51 | }
52 |
53 | .blanket-clear {
54 | background: #888888;
55 | }
56 |
57 | .blanket-very-clear {
58 | background: #CCCCCC;
59 | }
60 |
61 | .centered-slide {
62 | position: absolute;
63 | top: 50%;
64 | left: 50%;
65 | transform: translate(-50%, -50%);
66 | }
67 |
68 | footer {
69 | position: fixed;
70 | bottom: 0;
71 | z-index: 65532 !important;
72 | }
73 |
74 | nav {
75 | z-index: 65532 !important;
76 | }
77 |
78 | .ax-overlay {
79 | z-index: 65533 !important;
80 | }
81 |
82 | .modal {
83 | z-index: 65534 !important;
84 | }
85 |
86 | .swal2-container {
87 | z-index: 65535 !important;
88 | }
89 |
90 | .pup-a {
91 | font-weight: bold;
92 | text-decoration: underline dotted;
93 | }
94 |
95 | .pup-a-nobold {
96 | text-decoration: underline dotted;
97 | }
98 |
99 | .ellipsis {
100 | white-space: nowrap;
101 | overflow: hidden;
102 | text-overflow: ellipsis;
103 | }
104 |
105 | .wid220 {
106 | width: 220px;
107 | }
108 |
109 | .noSelect {
110 | user-select: none;
111 | }
112 |
--------------------------------------------------------------------------------
/demo-ui/public/testFs/thisIsASourceFile.go:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 | package main
18 |
19 | import (
20 | "fmt"
21 | "mime"
22 | "net/http"
23 | "os"
24 | "os/user"
25 | "path/filepath"
26 | "strconv"
27 | "strings"
28 | "syscall"
29 | )
30 |
31 | const MIME_TYPE_TEXT_PLAIN = "text/plain"
32 |
33 | // Adapted from https://golangcode.com/get-the-content-type-of-file/
34 | func getFileContentType(path string) string {
35 | // First, quick lookup by extension
36 | ext := filepath.Ext(path)
37 | if ext != "" {
38 | // IDK why, but .txt is not translated by Go :-(
39 | if strings.EqualFold(ext, ".txt") {
40 | return MIME_TYPE_TEXT_PLAIN
41 | }
42 | contentType := mime.TypeByExtension(ext)
43 | if contentType != "" {
44 | return contentType
45 | }
46 | }
47 |
48 | // If inconclusive, look up by contents
49 | file, err := os.Open(path)
50 | if err != nil {
51 | return MIME_TYPE_TEXT_PLAIN
52 | }
53 | defer file.Close()
54 |
55 | buffer := make([]byte, 512)
56 |
57 | _, err = file.Read(buffer)
58 | if err != nil {
59 | return MIME_TYPE_TEXT_PLAIN
60 | }
61 |
62 | contentType := http.DetectContentType(buffer)
63 |
64 | return contentType
65 | }
66 |
67 | // Adapted from https://pirivan.gitlab.io/post/how-to-retrieve-file-ownership-information-in-golang/
68 | func getUserAndGroup(path string) (string, string) {
69 | fileInfo, err := os.Stat(path)
70 | if err != nil {
71 | return "--", "--"
72 | }
73 |
74 | stat, ok := fileInfo.Sys().(*syscall.Stat_t)
75 | if !ok {
76 | return "--", "--"
77 | }
78 |
79 | usr, err := user.LookupId(strconv.FormatUint(uint64(stat.Uid), 10))
80 | if err != nil {
81 | return "--", "--"
82 | }
83 | group, err := user.LookupGroupId(strconv.FormatUint(uint64(stat.Gid), 10))
84 | if err != nil {
85 | return "--", "--"
86 | }
87 |
88 | return fmt.Sprintf("%s (%s)", usr.Username, usr.Uid),
89 | fmt.Sprintf("%s (%s)", group.Name, group.Gid)
90 | }
91 |
92 | func getFileInfoForHTTP(path string) (present bool, contentType string, length int64) {
93 | info, err := os.Stat(path)
94 | if os.IsNotExist(err) || info.IsDir() {
95 | return false, "", 0
96 | }
97 |
98 | length = info.Size()
99 |
100 | return true, getFileContentType(path), length
101 | }
102 |
--------------------------------------------------------------------------------
/src/static/icons/48x48/video-x-generic.svg:
--------------------------------------------------------------------------------
1 |
19 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/48x48/video-x-generic.svg:
--------------------------------------------------------------------------------
1 |
19 |
--------------------------------------------------------------------------------
/web-ui/public/icons/48x48/video-x-generic.svg:
--------------------------------------------------------------------------------
1 |
19 |
--------------------------------------------------------------------------------
/src/static/icons/48x48/application-pdf.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/48x48/application-pdf.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/web-ui/public/icons/48x48/application-pdf.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/demo-ui/src/Snippets/Breadcrumb.svelte:
--------------------------------------------------------------------------------
1 |
42 |
43 |
44 |
45 | 📍
46 | {#if path.length > 0}
47 |
root
48 | {/if} /
49 | {#each path as pItem, idx}
50 | {#if idx < path.length - 1}
51 |
52 |
{pItem.replace('/', '')}
53 | {:else}
54 |
{pItem.replace('/', '')}
55 | {/if} /
56 | {/each}
57 |
58 |
59 |
60 | 📍
61 |
62 |
63 | {#if path.length > 0}
64 |
65 | root
66 |
67 | {:else}
68 |
69 | root
70 |
71 | {/if}
72 | {#each path as pItem, idx}
73 | {#if idx < path.length - 1}
74 |
75 | / {pItem.replace("/", "")}
77 |
78 | {:else}
79 |
80 | / {pItem.replace("/", "")}
81 |
82 | {/if}
83 | {/each}
84 |
85 |
86 |
--------------------------------------------------------------------------------
/web-ui/src/Snippets/Breadcrumb.svelte:
--------------------------------------------------------------------------------
1 |
42 |
43 |
44 |
45 | 📍
46 | {#if path.length > 0}
47 |
root
48 | {/if} /
49 | {#each path as pItem, idx}
50 | {#if idx < path.length - 1}
51 |
52 |
{pItem.replace('/', '')}
53 | {:else}
54 |
{pItem.replace('/', '')}
55 | {/if} /
56 | {/each}
57 |
58 |
59 |
60 | 📍
61 |
62 |
63 | {#if path.length > 0}
64 |
65 | root
66 |
67 | {:else}
68 |
69 | root
70 |
71 | {/if}
72 | {#each path as pItem, idx}
73 | {#if idx < path.length - 1}
74 |
75 | / {pItem.replace("/", "")}
77 |
78 | {:else}
79 |
80 | / {pItem.replace("/", "")}
81 |
82 | {/if}
83 | {/each}
84 |
85 |
86 |
--------------------------------------------------------------------------------
/src/crypgo/crypgo.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2022-, Germano Rizzo
3 |
4 | Permission to use, copy, modify, and/or distribute this software for any
5 | purpose with or without fee is hereby granted, provided that the above
6 | copyright notice and this permission notice appear in all copies.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 | */
16 |
17 | // copied here because I want to drop reliance on zstd, it's not used in this context and it complicates the build
18 | // It uses "normal" ChaCha20Poly1305, for shorter results; it also removes header and compression bytes, here they
19 | // aren't needed (further shortening the result).
20 |
21 | package crypgo
22 |
23 | import (
24 | "crypto/rand"
25 | "crypto/sha256"
26 | "encoding/base64"
27 | "encoding/hex"
28 | "golang.org/x/crypto/chacha20poly1305"
29 | "golang.org/x/crypto/scrypt"
30 | )
31 |
32 | const ivSize = chacha20poly1305.NonceSize
33 | const keySize = chacha20poly1305.KeySize
34 |
35 | const scryptSaltSize = 8
36 | const scryptN = 1024
37 | const scryptR = 8
38 | const scryptP = 1
39 |
40 | func Sha256(str string) string {
41 | hash := sha256.Sum256([]byte(str))
42 | return hex.EncodeToString(hash[:])
43 | }
44 |
45 | func pwdToKey(salt []byte, password string) ([]byte, error) {
46 | dk, err := scrypt.Key([]byte(password), salt, scryptN, scryptR, scryptP, keySize)
47 | if err != nil {
48 | return nil, err
49 | }
50 | return dk, nil
51 | }
52 |
53 | func EncryptBytes(password string, plainBytes, addData []byte) (string, error) {
54 | iv := make([]byte, ivSize)
55 | rand.Read(iv)
56 |
57 | salt := iv[:scryptSaltSize]
58 |
59 | key, err := pwdToKey(salt, password)
60 | if err != nil {
61 | return "", err
62 | }
63 |
64 | c, err := chacha20poly1305.New(key)
65 | if err != nil {
66 | return "", err
67 | }
68 | cypherBytes := c.Seal(nil, iv, plainBytes, addData)
69 |
70 | outBytes := append(iv, cypherBytes...)
71 |
72 | return base64.RawURLEncoding.EncodeToString(outBytes), nil
73 | }
74 |
75 | // This function receives a password and a cypher text (as produced by one of the *EncryptBytes methods)
76 | // and decodes the original plaintext (if the password is the one used for encryption).
77 | //
78 | // It will return it or an eventual error, and closes all related resources.
79 | // XChaCha20-Poly1305's authentication tag is used to detect any decryption error. It also
80 | // transparently decompress data, if needed.
81 | func DecryptBytes(password string, base64CipherText string, addData []byte) ([]byte, error) {
82 | inBytes, err := base64.RawURLEncoding.DecodeString(base64CipherText)
83 | if err != nil {
84 | return make([]byte, 0), err
85 | }
86 |
87 | iv := inBytes[:ivSize]
88 | salt := inBytes[:scryptSaltSize]
89 | cypherBytes := inBytes[ivSize:]
90 |
91 | key, err := pwdToKey(salt, password)
92 | if err != nil {
93 | return make([]byte, 0), err
94 | }
95 |
96 | c, err := chacha20poly1305.New(key)
97 | if err != nil {
98 | return make([]byte, 0), err
99 | }
100 | plainBytes, err := c.Open(nil, iv, cypherBytes, addData)
101 |
102 | if err != nil {
103 | return make([]byte, 0), err
104 | }
105 |
106 | return plainBytes, nil
107 | }
108 |
--------------------------------------------------------------------------------
/web-ui/src/FileManager/List.svelte:
--------------------------------------------------------------------------------
1 |
70 |
71 |
72 |
73 |
74 | | {@html getCaret(WHERES.NAME, sorter)}
75 | Name
76 | |
77 | {@html getCaret(WHERES.SIZE, sorter)}Size |
78 | {@html getCaret(WHERES.DATE, sorter)}Mod. Date
79 | |
80 |
81 | {#each itemList as item (item.uuid)}
82 |
83 | {/each}
84 |
85 |
86 |
--------------------------------------------------------------------------------
/demo-ui/src/FileManager/List.svelte:
--------------------------------------------------------------------------------
1 |
70 |
71 |
72 |
73 |
74 | | {@html getCaret(WHERES.NAME, sorter)}
75 | Name
76 | |
77 | {@html getCaret(WHERES.SIZE, sorter)}Size |
78 | {@html getCaret(WHERES.DATE, sorter)}Mod. Date
79 | |
80 |
81 | {#each itemList as item (item.uuid)}
82 |
83 | {/each}
84 |
85 |
86 |
--------------------------------------------------------------------------------
/src/files/files.go:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PupCloud, Copyright (c) 2022-2078, Germano Rizzo
3 | *
4 | * PupCloud is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PupCloud is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PupCloud. If not, see .
16 | */
17 |
18 | package files
19 |
20 | import (
21 | "github.com/gofiber/fiber/v2"
22 | "github.com/proofrock/pupcloud/commons"
23 | "io/ioutil"
24 | "os"
25 | "path/filepath"
26 | )
27 |
28 | func FileExists(filename string) bool {
29 | info, err := os.Lstat(filename)
30 | return !os.IsNotExist(err) && !info.IsDir()
31 | }
32 |
33 | func cleanPath(path string, followLinks bool) (string, error) {
34 | var err error
35 | if followLinks {
36 | path, err = filepath.EvalSymlinks(path)
37 | if err != nil {
38 | return "", err
39 | }
40 | } else {
41 | path = filepath.Clean(path)
42 | }
43 | return path, nil
44 | }
45 |
46 | type Item struct {
47 | IsLink bool `json:"isLink"`
48 | MimeType string `json:"mimeType"`
49 | Name string `json:"name"`
50 | Size int64 `json:"size"`
51 | ChDate int64 `json:"chDate"`
52 | Owner string `json:"owner"`
53 | Group string `json:"group"`
54 | Permissions string `json:"permissions"`
55 | }
56 |
57 | func LsFile(path string, followLinks bool) *Item {
58 | info, errStating := os.Lstat(path)
59 | if os.IsNotExist(errStating) {
60 | return nil
61 | }
62 |
63 | var ret Item
64 | ret.Name = filepath.Base(path)
65 | ret.IsLink = false
66 |
67 | if info.IsDir() {
68 | ret.MimeType = "#directory"
69 | ret.Size = -1
70 | } else if info.Mode()&os.ModeSymlink != 0 {
71 | ret.IsLink = true
72 | if !followLinks {
73 | ret.MimeType = "#link"
74 | ret.Size = -1
75 | } else {
76 | resolved, errResolving := cleanPath(path, true)
77 | if errResolving != nil {
78 | ret.MimeType = "#unresolved"
79 | ret.Size = -1
80 | } else {
81 | target := LsFile(resolved, true)
82 | if target == nil {
83 | ret.MimeType = "#unresolved"
84 | } else {
85 | ret.MimeType = target.MimeType
86 | ret.Size = target.Size
87 | }
88 | }
89 | }
90 | } else {
91 | ret.MimeType = getFileContentType(path)
92 | ret.Size = info.Size()
93 | }
94 |
95 | ret.ChDate = info.ModTime().Unix()
96 |
97 | ret.Owner, ret.Group = getUserAndGroup(path)
98 | ret.Permissions = info.Mode().String()
99 |
100 | return &ret
101 | }
102 |
103 | func LsDir(path string, followLinks bool) ([]Item, *commons.ErrorRes) {
104 | var err error
105 | if followLinks {
106 | path, err = cleanPath(path, followLinks)
107 | if err != nil {
108 | return nil, &commons.ErrorRes{Code: fiber.StatusBadRequest, Message: err.Error()}
109 | }
110 | }
111 |
112 | file, errPath := os.Lstat(path)
113 | if errPath != nil || !file.IsDir() {
114 | return nil, &commons.ErrorRes{Code: fiber.StatusNotFound, Message: "Path not found"}
115 | }
116 |
117 | files, err := ioutil.ReadDir(path)
118 | ret := make([]Item, 0)
119 | for _, f := range files {
120 | item := LsFile(filepath.Join(path, f.Name()), followLinks)
121 | if item != nil {
122 | ret = append(ret, *item)
123 | }
124 | }
125 | return ret, nil
126 | }
127 |
--------------------------------------------------------------------------------
/demo-ui/public/mocks/ls0.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": [],
3 | "items": [
4 | {
5 | "mimeType": "#directory",
6 | "name": "thisIsADir",
7 | "size": -1,
8 | "chDate": 1645859590,
9 | "owner": "mano (1000)",
10 | "group": "mano (1000)",
11 | "permissions": "drwxr-xr-x"
12 | },
13 | {
14 | "mimeType": "text/plain",
15 | "name": "thisIsALongNameThatIsVeryVeryLongReallyLong.txt",
16 | "size": 4,
17 | "chDate": 1645859445,
18 | "owner": "mano (1000)",
19 | "group": "mano (1000)",
20 | "permissions": "-rw-r--r--"
21 | },
22 | {
23 | "mimeType": "image/jpeg",
24 | "name": "thisIsAMeme.jpg",
25 | "size": 46789,
26 | "chDate": 1645859490,
27 | "owner": "mano (1000)",
28 | "group": "mano (1000)",
29 | "permissions": "-rw-r--r--"
30 | },
31 | {
32 | "mimeType": "application/pdf",
33 | "name": "thisIsAPDF.pdf",
34 | "size": 3028,
35 | "chDate": 1645859526,
36 | "owner": "mano (1000)",
37 | "group": "mano (1000)",
38 | "permissions": "-rw-r--r--"
39 | },
40 | {
41 | "mimeType": "text/plain; charset=utf-8",
42 | "name": "thisIsASourceFile.go",
43 | "size": 2511,
44 | "chDate": 1645859469,
45 | "owner": "mano (1000)",
46 | "group": "mano (1000)",
47 | "permissions": "-rw-r--r--"
48 | },
49 | {
50 | "mimeType": "application/octet-stream",
51 | "name": "thisIsATXTWithNoExtension",
52 | "size": 5,
53 | "chDate": 1645859563,
54 | "owner": "mano (1000)",
55 | "group": "mano (1000)",
56 | "permissions": "-rw-r--r--"
57 | },
58 | {
59 | "mimeType": "video/mp4",
60 | "name": "thisIsAVideo.mp4",
61 | "size": 574823,
62 | "chDate": 1645859516,
63 | "owner": "mano (1000)",
64 | "group": "mano (1000)",
65 | "permissions": "-rw-r--r--"
66 | },
67 | {
68 | "mimeType": "text/plain",
69 | "name": "thisIsAnEmptyFile",
70 | "size": 0,
71 | "chDate": 1645859506,
72 | "owner": "mano (1000)",
73 | "group": "mano (1000)",
74 | "permissions": "-rw-r--r--"
75 | },
76 | {
77 | "mimeType": "audio/mpeg",
78 | "name": "thisIsAudio.mp3",
79 | "size": 764176,
80 | "chDate": 1645859459,
81 | "owner": "mano (1000)",
82 | "group": "mano (1000)",
83 | "permissions": "-rw-r--r--"
84 | },
85 | {
86 | "mimeType": "text/html; charset=utf-8",
87 | "name": "thisIsHTML.html",
88 | "size": 1086,
89 | "chDate": 1645859481,
90 | "owner": "mano (1000)",
91 | "group": "mano (1000)",
92 | "permissions": "-rw-r--r--"
93 | },
94 | {
95 | "mimeType": "image/jpeg",
96 | "name": "thisIsUnicode汉字卡片.jpg",
97 | "size": 54828,
98 | "chDate": 1645859545,
99 | "owner": "mano (1000)",
100 | "group": "mano (1000)",
101 | "permissions": "-rw-r--r--"
102 | },
103 | {
104 | "mimeType": "image/jpeg",
105 | "name": "thisIsABigPic.jpg",
106 | "size": 618098,
107 | "chDate": 1645859545,
108 | "owner": "mano (1000)",
109 | "group": "mano (1000)",
110 | "permissions": "-rw-r--r--"
111 | }
112 | ]
113 | }
114 |
--------------------------------------------------------------------------------
/web-ui/src/Preview/FullScreen.svelte:
--------------------------------------------------------------------------------
1 |
97 |
98 |
104 |
105 |
106 |
![{files[fileIdx].name} {files[fileIdx].name}]({files[fileIdx].getWS(false)})
109 |
110 |
--------------------------------------------------------------------------------
/demo-ui/src/Preview/FullScreen.svelte:
--------------------------------------------------------------------------------
1 |
97 |
98 |
104 |
105 |
106 |
![{files[fileIdx].name} {files[fileIdx].name}]({files[fileIdx].getWS(false)})
109 |
110 |
--------------------------------------------------------------------------------
/src/go.sum:
--------------------------------------------------------------------------------
1 | github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
2 | github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
3 | github.com/gofiber/fiber/v2 v2.33.0 h1:U9om15fapDkQ2sd9JQMfZLOs52bagsMAoTomQDqyJtg=
4 | github.com/gofiber/fiber/v2 v2.33.0/go.mod h1:CMy5ZLiXkn6qwthrl03YMyW1NLfj0rhxz2LKl4t7ZTY=
5 | github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
6 | github.com/klauspost/compress v1.15.3 h1:wmfu2iqj9q22SyMINp1uQ8C2/V4M1phJdmH9fG4nba0=
7 | github.com/klauspost/compress v1.15.3/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
8 | github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
9 | github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
10 | github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
11 | github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
12 | github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
13 | github.com/otiai10/mint v1.3.3 h1:7JgpsBaN0uMkyju4tbYHu0mnM55hNKVYLsXmwr15NQI=
14 | github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
15 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
16 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
17 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
18 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
19 | github.com/valyala/fasthttp v1.35.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
20 | github.com/valyala/fasthttp v1.36.0 h1:NhqfO/cB7Ajn1czkKnWkMHyPYr5nyND14ZGPk23g0/c=
21 | github.com/valyala/fasthttp v1.36.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
22 | github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
23 | github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
24 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
25 | golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 h1:NvGWuYG8dkDHFSKksI1P9faiVJ9rayE6l0+ouWVIDs8=
26 | golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
27 | golang.org/x/exp v0.0.0-20220428152302-39d4317da171 h1:TfdoLivD44QwvssI9Sv1xwa5DcL5XQr4au4sZ2F2NV4=
28 | golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
29 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
30 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
31 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
32 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
33 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
34 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
35 | golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
36 | golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
37 | golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
38 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
39 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
40 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
41 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
42 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
43 |
--------------------------------------------------------------------------------
/web-ui/src/Auth.svelte:
--------------------------------------------------------------------------------
1 |
110 |
111 | {#if config != null}
112 |
113 | {:else}
114 |
115 | {/if}
116 |
--------------------------------------------------------------------------------
/demo-ui/src/Auth.svelte:
--------------------------------------------------------------------------------
1 |
110 |
111 | {#if config != null}
112 |
113 | {:else}
114 |
115 | {/if}
116 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: list docker
2 | list:
3 | @LC_ALL=C $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
4 |
5 | cleanup-ui:
6 | - rm -r web-ui/node_modules
7 | - rm -r web-ui/public/build
8 |
9 | cleanup-demo-ui:
10 | - rm -r demo-ui/node_modules
11 |
12 | cleanup-build:
13 | - rm -r bin
14 | - rm src/pupcloud
15 |
16 | cleanup:
17 | - make cleanup-ui
18 | - make cleanup-demo-ui
19 | - make cleanup-build
20 |
21 | build-ui:
22 | make cleanup-ui
23 | cd web-ui && npm install && npm run build
24 | - rm -r src/static/*
25 | cp -r web-ui/public/* src/static/
26 |
27 | build-demo-ui:
28 | make cleanup-demo-ui
29 | - rm -r demo-ui/node_modules
30 | - rm -r demo-ui/public/build
31 | cd demo-ui && npm install && npm run build
32 |
33 | build-prepare:
34 | make cleanup
35 | mkdir bin
36 |
37 | build:
38 | make build-prepare
39 | cd src; CGO=0 go build -o ../bin/pupcloud
40 |
41 | zbuild:
42 | make build
43 | cd bin; 7zr a -mx9 -t7z pupcloud-v0.8.0-`uname -s|tr '[:upper:]' '[:lower:]'`-`uname -m`.7z pupcloud
44 |
45 | build-static:
46 | make build-prepare
47 | cd src; CGO=0 go build -a -tags netgo,osusergo -ldflags '-w -extldflags "-static"' -o ../bin/pupcloud
48 |
49 | zbuild-static:
50 | make build-static
51 | cd bin; 7zr a -mx9 -t7z pupcloud-v0.8.0-`uname -s|tr '[:upper:]' '[:lower:]'`-`uname -m`.7z pupcloud
52 |
53 | zbuild-all:
54 | make build-prepare
55 | make build-ui
56 | cd src; CGO=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo,osusergo -ldflags '-w -extldflags "-static"'
57 | cd src; tar czf ../bin/pupcloud-v0.8.0-linux-amd64.tar.gz pupcloud
58 | rm src/pupcloud
59 | cd src; CGO=0 GOOS=linux GOARCH=arm go build -a -tags netgo,osusergo -ldflags '-w -extldflags "-static"'
60 | cd src; tar czf ../bin/pupcloud-v0.8.0-linux-arm.tar.gz pupcloud
61 | rm src/pupcloud
62 | cd src; CGO=0 GOOS=linux GOARCH=arm64 go build -a -tags netgo,osusergo -ldflags '-w -extldflags "-static"'
63 | cd src; tar czf ../bin/pupcloud-v0.8.0-linux-arm64.tar.gz pupcloud
64 | rm src/pupcloud
65 | cd src; CGO=0 GOOS=darwin GOARCH=amd64 go build
66 | cd src; zip -9 ../bin/pupcloud-v0.8.0-darwin-amd64.zip pupcloud
67 | rm src/pupcloud
68 | cd src; CGO=0 GOOS=darwin GOARCH=arm64 go build
69 | cd src; zip -9 ../bin/pupcloud-v0.8.0-darwin-arm64.zip pupcloud
70 | rm src/pupcloud
71 | cd src; CGO=0 GOOS=windows GOARCH=amd64 go build
72 | cd src; zip -9 ../bin/pupcloud-v0.8.0-win-amd64.zip pupcloud.exe
73 | rm src/pupcloud.exe
74 | cd src; CGO=0 GOOS=windows GOARCH=arm64 go build
75 | cd src; zip -9 ../bin/pupcloud-v0.8.0-win-arm64.zip pupcloud.exe
76 | rm src/pupcloud.exe
77 | cd src; CGO=0 GOOS=freebsd GOARCH=amd64 go build
78 | cd src; tar czf ../bin/pupcloud-v0.8.0-freebsd-arm64.tar.gz pupcloud
79 | rm src/pupcloud
80 |
81 | run:
82 | make build-ui
83 | make build
84 | bin/pupcloud -r demo-ui/public/testFs/ -E
85 |
86 | run-demo-ui:
87 | make cleanup-demo-ui
88 | cd demo-ui && npm install && npm run dev
89 |
90 | docker:
91 | sudo docker build --no-cache -t local_pupcloud:latest .
92 |
93 | docker-publish:
94 | ## Prepare system with:
95 | ## (verify which is latest at https://hub.docker.com/r/docker/binfmt/tags)
96 | sudo docker run --privileged --rm docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64
97 | sudo docker buildx build --no-cache -t germanorizzo/pupcloud:v0.8.0-amd64 .
98 | sudo docker buildx build --no-cache --platform linux/arm/v7 -t germanorizzo/pupcloud:v0.8.0-arm .
99 | sudo docker buildx build --no-cache --platform linux/arm64/v8 -t germanorizzo/pupcloud:v0.8.0-arm64 .
100 | sudo docker push germanorizzo/pupcloud:v0.8.0-amd64
101 | sudo docker push germanorizzo/pupcloud:v0.8.0-arm
102 | sudo docker push germanorizzo/pupcloud:v0.8.0-arm64
103 | sudo docker manifest create -a germanorizzo/pupcloud:v0.8.0 germanorizzo/pupcloud:v0.8.0-amd64 germanorizzo/pupcloud:v0.8.0-arm germanorizzo/pupcloud:v0.8.0-arm64
104 | sudo docker manifest push germanorizzo/pupcloud:v0.8.0
105 | sudo docker manifest create -a germanorizzo/pupcloud:latest germanorizzo/pupcloud:v0.8.0-amd64 germanorizzo/pupcloud:v0.8.0-arm germanorizzo/pupcloud:v0.8.0-arm64
106 | sudo docker manifest push germanorizzo/pupcloud:latest
107 |
--------------------------------------------------------------------------------
/Changelog.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## Main features history
4 |
5 | | Feature | Version |
6 | |--------------------------------------------|---------|
7 | | Basic navigation | v0.1.x |
8 | | File preview/gallery | v0.1.x |
9 | | Authentication | v0.2.x |
10 | | Write operations (delete, copy, rename...) | v0.3.x |
11 | | Read-only mode | v0.3.x |
12 | | File upload | v0.4.x |
13 | | Folder sharing | v0.5.x |
14 | | Follow symlinks | v0.6.x |
15 |
16 | ## v0.8.0
17 |
18 | - Readonly mode is now the default, `-E` to make it read-write [#16]
19 | - Every CLI parameter can be specified as an env variable [addresses #10]
20 | - Added parameter `--share-profiles` to specify profiles as comma-separated [addresses #14]
21 | - Fixed back button management [addresses #15]
22 | - Copying the sharing link to clipboard wouldn't work if not in a secure context [#19]
23 | - Improvements to better support reverse proxies with subpaths [#18, #22]
24 | - Added path to the browser tab's title, so that it figures in the history list
25 | - Reduced number of columns in grid view for xl screens
26 | - Fix: Only the first sharing profile was selectable [#21]
27 | - Fix: Logout button wouldn't show when using a "normal" password [#23]
28 | - Ditch 7z format for distribution, use .tar.gz & zip instead (according to the OS)
29 | - Updates to libraries
30 | - Binaries for win/arm64 and freebsd/amd64
31 |
32 | ## v0.7.2
33 |
34 | - [#1] Support for browser's back/forward buttons navigation
35 | - [#11] Webservices allows paths with '..'
36 | - Docker cross-compiling for amd64, arm, arm64 and multiplatform manifest
37 |
38 | ## v0.7.1
39 |
40 | - [#2] Can't enter directory made by pupcloud
41 | - [#4] When cd to a dir fails, dir name gets appended to the breadcrumb "forever"
42 | - [#5] Provide systemd example/docs (in proofrock/pupcloud-docs)
43 | - [#6] More functional footer
44 | - [#7] Click on title to go to root
45 | - [#8] Listview's whole row should be clickable
46 | - [#9] Listviews' columns should be clickable to change sorting
47 | - Library upgrades
48 |
49 | ## v0.7.0
50 |
51 | - Plain-text password for auth (`-P`)
52 | - breaking change: old `-P` is now `-H` (for hashed password)
53 | - Shorter sharing links and better detection of failures (root changes after sharing, ...)
54 | - breaking change: you'll need to re-generate any sharing link you had from previous versions
55 | - Cross-compilation support (removed CGO dependency)
56 | - Manual mimetype resolution for problematic files
57 |
58 | ## v0.6.4
59 |
60 | - IPV6 support
61 | - "splash footer" disappears after 1,5s
62 |
63 | ## v0.6.1 - 0.6.3
64 |
65 | - fixes
66 | - library updates
67 |
68 | ## v0.6.0
69 |
70 | - Ability to follow symbolic links (`--follow-symlinks`)
71 | - Preview now switches between slideshow, full-screen and full size
72 | - Swipe support in slideshow screen, on mobile
73 | - It's now forbidden to run as root (unless `--allow-root`)
74 | - Logout (if password is required)
75 | - Session invalidation when preconditions fail after login (root deletion, expiration...)
76 | - Go 1.18
77 | - Minor fixes and improvements
78 |
79 | ## v0.5.0
80 |
81 | - Folder sharing
82 | - UserID/GroupID support in docker
83 | - Ability to specify max upload size on the CLI
84 | - Many fixes, refactorings and performance improvements
85 |
86 | ## v0.4.2
87 |
88 | - Fixed z-indexes
89 | - Improved performances when listing a huge number of items
90 | - Upgrade to libs
91 |
92 | ## v0.4.1
93 |
94 | - Fix: paste didn't work
95 | - Reload button
96 |
97 | ## v0.4.0
98 |
99 | - File upload
100 | - CSRF protection
101 |
102 | ## v0.3.0
103 |
104 | - "Write" operations
105 | - Cut/Copy/Paste
106 | - Delete
107 | - Rename
108 | - Create Folder
109 | - Read-only mode (`--readonly`)
110 | - Support for Windows
111 | - Minor UI fixes
112 |
113 | ## v0.2.0
114 |
115 | - Authentication (`-P`);
116 | - Updates to library (particularly Axentix and Fiber);
117 | - Workaround for dropdown triggers (`...`) being rendered over the dropdown
118 | itself.
119 |
120 | ## v0.1.2
121 |
122 | - Fixes to HTML layout.
123 |
124 | ## v0.1.1
125 |
126 | - Stable demo site;
127 | - Fixes to Dockerfile.
128 |
129 | ## v0.1.0
130 |
131 | - First version;
132 | - Navigation, preview, download of files.
133 |
--------------------------------------------------------------------------------
/src/static/icons/48x48/image-x-generic.svg:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/web-ui/public/icons/48x48/image-x-generic.svg:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/demo-ui/public/icons/48x48/image-x-generic.svg:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------