mirror of
https://github.com/Forceu/Gokapi.git
synced 2025-12-30 13:29:34 -06:00
Added option to change the name in the setup, show filename in title for downloads, use sessionStorage instead of localStorage for e2e decryption, replaced expiry image with dynamic SVG
This commit is contained in:
24
.readthedocs.yaml
Normal file
24
.readthedocs.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
# You can also specify other tool versions:
|
||||
# nodejs: "19"
|
||||
# rust: "1.64"
|
||||
# golang: "1.19"
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
# Optionally declare the Python requirements required to build your docs
|
||||
python:
|
||||
system_packages: true
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
|
||||
// versionGokapi is the current version in readable form.
|
||||
// Other version numbers can be modified in /build/go-generate/updateVersionNumbers.go
|
||||
const versionGokapi = "1.7.1"
|
||||
const versionGokapi = "1.7.2"
|
||||
|
||||
// The following calls update the version numbers, update documentation, minify Js/CSS and build the WASM modules
|
||||
//go:generate go run "../../build/go-generate/updateVersionNumbers.go"
|
||||
|
||||
@@ -147,4 +147,3 @@ By default, all files are included in the executable. If you want to change the
|
||||
3. Make changes to the folders. ``static`` contains images, CSS files and JavaScript. ``templates`` contains the HTML code.
|
||||
4. Restart the server. If the folders exist, the server will use the local files instead of the embedded files.
|
||||
5. Optional: To embed the files permanently, copy the modified files back to the original folders and recompile with ``go build Gokapi/cmd/gokapi``.
|
||||
|
||||
|
||||
@@ -60,6 +60,9 @@ func Load() {
|
||||
if envMaxMem != "" {
|
||||
serverSettings.MaxMemory = Environment.MaxMemory
|
||||
}
|
||||
if serverSettings.PublicName == "" {
|
||||
serverSettings.PublicName = "Gokapi"
|
||||
}
|
||||
helper.CreateDir(serverSettings.DataDir)
|
||||
filesystem.Init(serverSettings.DataDir)
|
||||
log.Init(Environment.DataDir)
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
// CurrentConfigVersion is the version of the configuration structure. Used for upgrading
|
||||
const CurrentConfigVersion = 13
|
||||
const CurrentConfigVersion = 14
|
||||
|
||||
// DoUpgrade checks if an old version is present and updates it to the current version if required
|
||||
func DoUpgrade(settings *models.Configuration, env *environment.Environment) bool {
|
||||
@@ -66,6 +66,10 @@ func updateConfig(settings *models.Configuration, env *environment.Environment)
|
||||
}
|
||||
}
|
||||
}
|
||||
// < v1.7.2
|
||||
if settings.ConfigVersion < 14 {
|
||||
settings.PublicName = "Gokapi"
|
||||
}
|
||||
}
|
||||
|
||||
func legacyFileToCurrentFile(input []byte) models.File {
|
||||
|
||||
@@ -114,6 +114,11 @@ func startSetupWebserver() {
|
||||
WriteTimeout: 2 * time.Minute,
|
||||
Handler: mux,
|
||||
}
|
||||
if debugDisableAuth {
|
||||
srv.Addr = "127.0.0.1:" + port
|
||||
fmt.Println("Authentication is disabled by debug flag. Setup only accessible by localhost")
|
||||
fmt.Println("Please open http://127.0.0.1:" + port + "/setup to setup Gokapi.")
|
||||
}
|
||||
fmt.Println("Please open http://" + resolveHostIp() + ":" + port + "/setup to setup Gokapi.")
|
||||
listener, err := net.Listen("tcp", ":"+port)
|
||||
if err != nil {
|
||||
@@ -337,6 +342,10 @@ func parseServerSettings(result *models.Configuration, formObjects *[]jsonFormOb
|
||||
result.Port = ":" + strconv.Itoa(port)
|
||||
}
|
||||
|
||||
result.PublicName, err = getFormValueString(formObjects, "public_name")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result.ServerUrl, err = getFormValueString(formObjects, "url")
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -458,6 +458,7 @@ type setupValues struct {
|
||||
BindLocalhost setupEntry `form:"localhost_sel" isBool:"true"`
|
||||
UseSsl setupEntry `form:"ssl_sel" isBool:"true"`
|
||||
Port setupEntry `form:"port" isInt:"true"`
|
||||
PublicName setupEntry `form:"public_name"`
|
||||
ExtUrl setupEntry `form:"url"`
|
||||
RedirectUrl setupEntry `form:"url_redirection"`
|
||||
AuthenticationMode setupEntry `form:"authentication_sel" isInt:"true"`
|
||||
@@ -572,6 +573,7 @@ func createInputInternalAuth() setupValues {
|
||||
values.init()
|
||||
|
||||
values.BindLocalhost.Value = "1"
|
||||
values.PublicName.Value = "Test Name"
|
||||
values.UseSsl.Value = "0"
|
||||
values.Port.Value = "53842"
|
||||
values.ExtUrl.Value = "http://127.0.0.1:53842/"
|
||||
@@ -596,6 +598,7 @@ func createInputHeaderAuth() setupValues {
|
||||
values.init()
|
||||
|
||||
values.BindLocalhost.Value = "0"
|
||||
values.PublicName.Value = "Test Name"
|
||||
values.UseSsl.Value = "1"
|
||||
values.Port.Value = "53842"
|
||||
values.ExtUrl.Value = "http://127.0.0.1:53842/"
|
||||
|
||||
@@ -106,6 +106,11 @@
|
||||
|
||||
<div class="wizard-input-section">
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-8">
|
||||
<label for="public_name">Pubblic Name:</label>
|
||||
<input type="text" class="form-control" id="public_name" name="public_name" value="Gokapi" placeholder="Public Name" required>
|
||||
</div><br><br><br>
|
||||
<div class="col-sm-8">
|
||||
<label for="port">Port:</label>
|
||||
{{ if .IsDocker }}
|
||||
@@ -122,6 +127,7 @@
|
||||
<input type="text" class="form-control" id="url" name="url" value="http://127.0.0.1:53842/" onfocusout="extUrlChanged(this)" placeholder="Public URL" data-min="8" required data-validate="validateUrl">
|
||||
</div><br><br><br>
|
||||
|
||||
|
||||
|
||||
<div class="col-sm-8">
|
||||
<label for="url_redirection">Redirection URL for the index:</label>
|
||||
@@ -616,6 +622,7 @@ function TestAWS(button) {
|
||||
{{ end }}
|
||||
document.getElementById("port").value = "{{ .Port }}";
|
||||
document.getElementById("url").value = "{{ .Settings.ServerUrl }}";
|
||||
document.getElementById("public_name").value = "{{ .Settings.PublicName }}";
|
||||
document.getElementById("url_redirection").value = "{{ .Settings.RedirectUrl }}";
|
||||
document.getElementById("authentication_sel").value = "{{ .Auth.Method }}";
|
||||
authSelectionChanged("{{ .Auth.Method }}")
|
||||
|
||||
@@ -11,6 +11,7 @@ type Configuration struct {
|
||||
Port string `json:"Port"`
|
||||
ServerUrl string `json:"ServerUrl"`
|
||||
RedirectUrl string `json:"RedirectUrl"`
|
||||
PublicName string `json:"PublicName"`
|
||||
ConfigVersion int `json:"ConfigVersion"`
|
||||
LengthId int `json:"LengthId"`
|
||||
DataDir string `json:"DataDir"`
|
||||
|
||||
@@ -23,12 +23,13 @@ var testConfig = Configuration{
|
||||
Port: ":12345",
|
||||
ServerUrl: "https://testserver.com/",
|
||||
RedirectUrl: "https://test.com",
|
||||
ConfigVersion: 11,
|
||||
ConfigVersion: 14,
|
||||
LengthId: 5,
|
||||
DataDir: "test",
|
||||
MaxMemory: 50,
|
||||
UseSsl: true,
|
||||
MaxFileSizeMB: 20,
|
||||
PublicName: "public-name",
|
||||
Encryption: Encryption{
|
||||
Level: 1,
|
||||
Cipher: []byte{0x00},
|
||||
@@ -47,4 +48,4 @@ func TestConfiguration_ToString(t *testing.T) {
|
||||
test.IsEqualString(t, testConfig.ToString(), exptectedUnidentedOutput)
|
||||
}
|
||||
|
||||
const exptectedUnidentedOutput = `{"Authentication":{"Method":0,"SaltAdmin":"saltadmin","SaltFiles":"saltfiles","Username":"admin","Password":"adminpwhashed","HeaderKey":"","OauthProvider":"","OAuthClientId":"","OAuthClientSecret":"","HeaderUsers":null,"OauthUsers":null},"Port":":12345","ServerUrl":"https://testserver.com/","RedirectUrl":"https://test.com","ConfigVersion":11,"LengthId":5,"DataDir":"test","MaxMemory":50,"UseSsl":true,"MaxFileSizeMB":20,"Encryption":{"Level":1,"Cipher":"AA==","Salt":"encsalt","Checksum":"encsum","ChecksumSalt":"encsumsalt"},"PicturesAlwaysLocal":true}`
|
||||
const exptectedUnidentedOutput = `{"Authentication":{"Method":0,"SaltAdmin":"saltadmin","SaltFiles":"saltfiles","Username":"admin","Password":"adminpwhashed","HeaderKey":"","OauthProvider":"","OAuthClientId":"","OAuthClientSecret":"","HeaderUsers":null,"OauthUsers":null},"Port":":12345","ServerUrl":"https://testserver.com/","RedirectUrl":"https://test.com","PublicName":"public-name","ConfigVersion":14,"LengthId":5,"DataDir":"test","MaxMemory":50,"UseSsl":true,"MaxFileSizeMB":20,"Encryption":{"Level":1,"Cipher":"AA==","Salt":"encsalt","Checksum":"encsum","ChecksumSalt":"encsumsalt"},"PicturesAlwaysLocal":true}`
|
||||
|
||||
@@ -5,6 +5,7 @@ Handling of webserver and requests / uploads
|
||||
*/
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/base64"
|
||||
@@ -35,6 +36,7 @@ import (
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
templatetext "text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -71,8 +73,6 @@ var templateFolder *template.Template
|
||||
|
||||
var imageExpiredPicture []byte
|
||||
|
||||
const expiredFile = "static/expired.png"
|
||||
|
||||
var srv http.Server
|
||||
var sseServer *sse.Server
|
||||
|
||||
@@ -90,13 +90,12 @@ func Start() {
|
||||
if helper.FolderExists("static") {
|
||||
fmt.Println("Found folder 'static', using local folder instead of internal static folder")
|
||||
mux.Handle("/", http.FileServer(http.Dir("static")))
|
||||
imageExpiredPicture, err = os.ReadFile(expiredFile)
|
||||
helper.Check(err)
|
||||
} else {
|
||||
mux.Handle("/", http.FileServer(http.FS(webserverDir)))
|
||||
imageExpiredPicture, err = fs.ReadFile(staticFolderEmbedded, "web/"+expiredFile)
|
||||
helper.Check(err)
|
||||
}
|
||||
loadExpiryImage()
|
||||
|
||||
mux.HandleFunc("/admin", requireLogin(showAdminMenu, false))
|
||||
mux.HandleFunc("/api/", processApi)
|
||||
mux.HandleFunc("/apiDelete", requireLogin(deleteApiKey, false))
|
||||
@@ -157,6 +156,16 @@ func Start() {
|
||||
}
|
||||
}
|
||||
|
||||
func loadExpiryImage() {
|
||||
svgTemplate, err := templatetext.ParseFS(templateFolderEmbedded, "web/templates/expired_file_svg.tmpl")
|
||||
helper.Check(err)
|
||||
var buf bytes.Buffer
|
||||
view := UploadView{}
|
||||
err = svgTemplate.Execute(&buf, view.convertGlobalConfig(ViewMain))
|
||||
helper.Check(err)
|
||||
imageExpiredPicture = buf.Bytes()
|
||||
}
|
||||
|
||||
// Shutdown closes the webserver gracefully
|
||||
func Shutdown() {
|
||||
sseServer.Close()
|
||||
@@ -211,7 +220,7 @@ func doLogout(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Handling of /index and redirecting to globalConfig.RedirectUrl
|
||||
func showIndex(w http.ResponseWriter, r *http.Request) {
|
||||
err := templateFolder.ExecuteTemplate(w, "index", genericView{RedirectUrl: configuration.Get().RedirectUrl})
|
||||
err := templateFolder.ExecuteTemplate(w, "index", genericView{RedirectUrl: configuration.Get().RedirectUrl, PublicName: configuration.Get().PublicName})
|
||||
helper.Check(err)
|
||||
}
|
||||
|
||||
@@ -228,19 +237,19 @@ func showError(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Query().Has("key") {
|
||||
errorReason = wrongCipher
|
||||
}
|
||||
err := templateFolder.ExecuteTemplate(w, "error", genericView{ErrorId: errorReason})
|
||||
err := templateFolder.ExecuteTemplate(w, "error", genericView{ErrorId: errorReason, PublicName: configuration.Get().PublicName})
|
||||
helper.Check(err)
|
||||
}
|
||||
|
||||
// Handling of /error-auth
|
||||
func showErrorAuth(w http.ResponseWriter, r *http.Request) {
|
||||
err := templateFolder.ExecuteTemplate(w, "error_auth", genericView{})
|
||||
err := templateFolder.ExecuteTemplate(w, "error_auth", genericView{PublicName: configuration.Get().PublicName})
|
||||
helper.Check(err)
|
||||
}
|
||||
|
||||
// Handling of /forgotpw
|
||||
func forgotPassword(w http.ResponseWriter, r *http.Request) {
|
||||
err := templateFolder.ExecuteTemplate(w, "forgotpw", genericView{})
|
||||
err := templateFolder.ExecuteTemplate(w, "forgotpw", genericView{PublicName: configuration.Get().PublicName})
|
||||
helper.Check(err)
|
||||
}
|
||||
|
||||
@@ -303,15 +312,18 @@ func showLogin(w http.ResponseWriter, r *http.Request) {
|
||||
IsFailedLogin: failedLogin,
|
||||
User: user,
|
||||
IsAdminView: false,
|
||||
PublicName: configuration.Get().PublicName,
|
||||
})
|
||||
helper.Check(err)
|
||||
}
|
||||
|
||||
// LoginView contains variables for the login template
|
||||
type LoginView struct {
|
||||
IsFailedLogin bool
|
||||
User string
|
||||
IsAdminView bool
|
||||
IsFailedLogin bool
|
||||
IsAdminView bool
|
||||
IsDownloadView bool
|
||||
User string
|
||||
PublicName string
|
||||
}
|
||||
|
||||
// Handling of /d
|
||||
@@ -330,7 +342,9 @@ func showDownload(w http.ResponseWriter, r *http.Request) {
|
||||
Name: file.Name,
|
||||
Size: file.Size,
|
||||
Id: file.Id,
|
||||
IsDownloadView: true,
|
||||
EndToEndEncryption: file.Encryption.IsEndToEndEncrypted,
|
||||
PublicName: configuration.Get().PublicName,
|
||||
IsFailedLogin: false,
|
||||
UsesHttps: configuration.UsesHttps(),
|
||||
}
|
||||
@@ -354,6 +368,7 @@ func showDownload(w http.ResponseWriter, r *http.Request) {
|
||||
case <-time.After(1 * time.Second):
|
||||
}
|
||||
}
|
||||
view.IsPasswordView = true
|
||||
err := templateFolder.ExecuteTemplate(w, "download_password", view)
|
||||
helper.Check(err)
|
||||
return
|
||||
@@ -376,7 +391,7 @@ func showHotlink(w http.ResponseWriter, r *http.Request) {
|
||||
hotlinkId := strings.Replace(r.URL.Path, "/hotlink/", "", 1)
|
||||
file, ok := storage.GetFileByHotlink(hotlinkId)
|
||||
if !ok {
|
||||
w.Header().Set("Content-Type", "image/png")
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
_, err := w.Write(imageExpiredPicture)
|
||||
helper.Check(err)
|
||||
return
|
||||
@@ -487,7 +502,7 @@ func showE2ESetup(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
e2einfo := database.GetEnd2EndInfo()
|
||||
err := templateFolder.ExecuteTemplate(w, "e2esetup", e2ESetupView{HasBeenSetup: e2einfo.HasBeenSetUp()})
|
||||
err := templateFolder.ExecuteTemplate(w, "e2esetup", e2ESetupView{HasBeenSetup: e2einfo.HasBeenSetUp(), PublicName: configuration.Get().PublicName})
|
||||
helper.Check(err)
|
||||
}
|
||||
|
||||
@@ -496,17 +511,22 @@ type DownloadView struct {
|
||||
Name string
|
||||
Size string
|
||||
Id string
|
||||
Cipher string
|
||||
PublicName string
|
||||
IsFailedLogin bool
|
||||
IsAdminView bool
|
||||
IsDownloadView bool
|
||||
IsPasswordView bool
|
||||
ClientSideDecryption bool
|
||||
EndToEndEncryption bool
|
||||
UsesHttps bool
|
||||
Cipher string
|
||||
}
|
||||
|
||||
type e2ESetupView struct {
|
||||
IsAdminView bool
|
||||
HasBeenSetup bool
|
||||
IsAdminView bool
|
||||
IsDownloadView bool
|
||||
HasBeenSetup bool
|
||||
PublicName string
|
||||
}
|
||||
|
||||
// UploadView contains parameters for the admin menu template
|
||||
@@ -516,25 +536,27 @@ type UploadView struct {
|
||||
Url string
|
||||
HotlinkUrl string
|
||||
GenericHotlinkUrl string
|
||||
TimeNow int64
|
||||
IsAdminView bool
|
||||
IsApiView bool
|
||||
MaxFileSize int
|
||||
IsLogoutAvailable bool
|
||||
DefaultDownloads int
|
||||
DefaultExpiry int
|
||||
DefaultPassword string
|
||||
Logs string
|
||||
PublicName string
|
||||
IsAdminView bool
|
||||
IsDownloadView bool
|
||||
IsApiView bool
|
||||
IsLogoutAvailable bool
|
||||
DefaultUnlimitedDownload bool
|
||||
DefaultUnlimitedTime bool
|
||||
EndToEndEncryption bool
|
||||
MaxFileSize int
|
||||
DefaultDownloads int
|
||||
DefaultExpiry int
|
||||
ActiveView int
|
||||
Logs string
|
||||
TimeNow int64
|
||||
}
|
||||
|
||||
// ViewMain is the identifier for the main menu
|
||||
const ViewMain = 0
|
||||
|
||||
// ViewLogs is the identifier for the log viever menu
|
||||
// ViewLogs is the identifier for the log viewer menu
|
||||
const ViewLogs = 1
|
||||
|
||||
// ViewAPI is the identifier for the API menu
|
||||
@@ -583,15 +605,18 @@ func (u *UploadView) convertGlobalConfig(view int) *UploadView {
|
||||
}
|
||||
}
|
||||
|
||||
u.Url = configuration.Get().ServerUrl + "d?id="
|
||||
u.HotlinkUrl = configuration.Get().ServerUrl + "hotlink/"
|
||||
u.GenericHotlinkUrl = configuration.Get().ServerUrl + "downloadFile?id="
|
||||
config := configuration.Get()
|
||||
|
||||
u.Url = config.ServerUrl + "d?id="
|
||||
u.HotlinkUrl = config.ServerUrl + "hotlink/"
|
||||
u.GenericHotlinkUrl = config.ServerUrl + "downloadFile?id="
|
||||
u.Items = result
|
||||
u.PublicName = config.PublicName
|
||||
u.ApiKeys = resultApi
|
||||
u.TimeNow = time.Now().Unix()
|
||||
u.IsAdminView = true
|
||||
u.ActiveView = view
|
||||
u.MaxFileSize = configuration.Get().MaxFileSizeMB
|
||||
u.MaxFileSize = config.MaxFileSizeMB
|
||||
u.IsLogoutAvailable = authentication.IsLogoutAvailable()
|
||||
defaultValues := database.GetUploadDefaults()
|
||||
u.DefaultDownloads = defaultValues.Downloads
|
||||
@@ -599,7 +624,7 @@ func (u *UploadView) convertGlobalConfig(view int) *UploadView {
|
||||
u.DefaultPassword = defaultValues.Password
|
||||
u.DefaultUnlimitedDownload = defaultValues.UnlimitedDownload
|
||||
u.DefaultUnlimitedTime = defaultValues.UnlimitedTime
|
||||
u.EndToEndEncryption = configuration.Get().Encryption.Level == encryption.EndToEndEncryption
|
||||
u.EndToEndEncryption = config.Encryption.Level == encryption.EndToEndEncryption
|
||||
return u
|
||||
}
|
||||
|
||||
@@ -698,7 +723,9 @@ func addNoCacheHeader(w http.ResponseWriter) {
|
||||
|
||||
// A view containing parameters for a generic template
|
||||
type genericView struct {
|
||||
IsAdminView bool
|
||||
RedirectUrl string
|
||||
ErrorId int
|
||||
IsAdminView bool
|
||||
IsDownloadView bool
|
||||
PublicName string
|
||||
RedirectUrl string
|
||||
ErrorId int
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/forceu/gokapi/internal/webserver/authentication"
|
||||
"github.com/r3labs/sse/v2"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -35,13 +34,9 @@ func TestEmbedFs(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Unable to read templates")
|
||||
}
|
||||
if !strings.Contains(templates.DefinedTemplates(), "app_name") {
|
||||
if !strings.Contains(templates.DefinedTemplates(), "header") {
|
||||
t.Error("Unable to parse templates")
|
||||
}
|
||||
_, err = fs.Stat(staticFolderEmbedded, "web/static/expired.png")
|
||||
if err != nil {
|
||||
t.Error("Static webdir incomplete")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexRedirect(t *testing.T) {
|
||||
@@ -326,7 +321,7 @@ func TestDownloadHotlink(t *testing.T) {
|
||||
// Download expired hotlink
|
||||
test.HttpPageResult(t, test.HttpTestConfig{
|
||||
Url: "http://127.0.0.1:53843/hotlink/PhSs6mFtf8O5YGlLMfNw9rYXx9XRNkzCnJZpQBi7inunv3Z4A.jpg",
|
||||
RequiredContent: []string{"Created with GIMP"},
|
||||
RequiredContent: []string{"The requested image has expired"},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.6 KiB |
@@ -1,6 +1,6 @@
|
||||
function parseHashValue(id) {
|
||||
let key = localStorage.getItem("key-" + id);
|
||||
let filename = localStorage.getItem("fn-" + id);
|
||||
let key = sessionStorage.getItem("key-" + id);
|
||||
let filename = sessionStorage.getItem("fn-" + id);
|
||||
|
||||
if (key === null || filename === null) {
|
||||
hash = window.location.hash.substr(1);
|
||||
@@ -20,8 +20,8 @@ function parseHashValue(id) {
|
||||
redirectToE2EError();
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("key-" + id, info.c);
|
||||
localStorage.setItem("fn-" + id, info.f);
|
||||
sessionStorage.setItem("key-" + id, info.c);
|
||||
sessionStorage.setItem("fn-" + id, info.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
function parseHashValue(e){let t=localStorage.getItem("key-"+e),n=localStorage.getItem("fn-"+e);if(t===null||n===null){if(hash=window.location.hash.substr(1),hash.length<50){redirectToE2EError();return}let t;try{let e=atob(hash);t=JSON.parse(e)}catch{redirectToE2EError();return}if(!isCorrectJson(t)){redirectToE2EError();return}localStorage.setItem("key-"+e,t.c),localStorage.setItem("fn-"+e,t.f)}}function isCorrectJson(e){return e.f!==void 0&&e.c!==void 0&&typeof e.f=="string"&&typeof e.c=="string"&&e.f!=""&&e.c!=""}function redirectToE2EError(){window.location="./error?e2e"}
|
||||
function parseHashValue(e){let t=sessionStorage.getItem("key-"+e),n=sessionStorage.getItem("fn-"+e);if(t===null||n===null){if(hash=window.location.hash.substr(1),hash.length<50){redirectToE2EError();return}let t;try{let e=atob(hash);t=JSON.parse(e)}catch{redirectToE2EError();return}if(!isCorrectJson(t)){redirectToE2EError();return}sessionStorage.setItem("key-"+e,t.c),sessionStorage.setItem("fn-"+e,t.f)}}function isCorrectJson(e){return e.f!==void 0&&e.c!==void 0&&typeof e.f=="string"&&typeof e.c=="string"&&e.f!=""&&e.c!=""}function redirectToE2EError(){window.location="./error?e2e"}
|
||||
5
internal/webserver/web/templates/expired_file_svg.tmpl
Normal file
5
internal/webserver/web/templates/expired_file_svg.tmpl
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="300" viewBox="0 0 500 300">
|
||||
<rect width="100%" height="100%" fill="#888888" />
|
||||
<text x="50%" y="33%" fill="#ffffff" font-family="Arial" font-size="36" text-anchor="middle">{{.PublicName}}</text>
|
||||
<text x="50%" y="65%" fill="#ffffff" font-family="Arial" font-size="24" text-anchor="middle">The requested image has expired</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 400 B |
@@ -78,10 +78,10 @@
|
||||
async function DownloadEncrypted() {
|
||||
try {
|
||||
{{ if .EndToEndEncryption }}
|
||||
let key = localStorage.getItem("key-{{ .Id }}");
|
||||
localStorage.removeItem("key-{{ .Id }}");
|
||||
let filename = localStorage.getItem("fn-{{ .Id }}");
|
||||
localStorage.removeItem("fn-{{ .Id }}");
|
||||
let key = sessionStorage.getItem("key-{{ .Id }}");
|
||||
sessionStorage.removeItem("key-{{ .Id }}");
|
||||
let filename = sessionStorage.getItem("fn-{{ .Id }}");
|
||||
sessionStorage.removeItem("fn-{{ .Id }}");
|
||||
{{ else }}
|
||||
let key = "{{ .Cipher }}";
|
||||
{{ end }}
|
||||
@@ -141,7 +141,9 @@
|
||||
{{ end }}
|
||||
{{ if .EndToEndEncryption }}
|
||||
<script>
|
||||
document.getElementById("filename").innerText = localStorage.getItem("fn-{{ .Id }}");
|
||||
let filename = sessionStorage.getItem("fn-{{ .Id }}");
|
||||
document.getElementById("filename").innerText = filename;
|
||||
document.title = "{{.PublicName}}: "+ filename;
|
||||
</script>
|
||||
{{ end }}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link href="css/min/gokapi.min.css?v={{ template "css_main"}}" rel="stylesheet">
|
||||
{{ if .IsAdminView }}
|
||||
<title>{{template "app_name"}} Admin</title>
|
||||
<title>{{.PublicName}} Admin</title>
|
||||
<link href="./assets/dist/css/dropzone.min.css" rel="stylesheet">
|
||||
<link href="./assets/dist/css/datatables.min.css" rel="stylesheet" />
|
||||
<script src="./assets/dist/js/jquery.min.js"></script>
|
||||
@@ -31,7 +31,15 @@
|
||||
}
|
||||
</style>
|
||||
{{ else }}
|
||||
<title>{{template "app_name"}}</title>
|
||||
{{ if .IsDownloadView }}
|
||||
{{ if .IsPasswordView }}
|
||||
<title>{{.PublicName}}: Password required</title>
|
||||
{{ else }}
|
||||
<title>{{.PublicName}}: {{.Name}}</title>
|
||||
{{end }}
|
||||
{{ else }}
|
||||
<title>{{.PublicName}}</title>
|
||||
{{end }}
|
||||
<style>
|
||||
body {
|
||||
box-shadow: inset 0 0 5rem rgba(0, 0, 0, .5);
|
||||
@@ -45,7 +53,7 @@
|
||||
<div class="d-flex w-100 h-100 p-3 mx-auto flex-column">
|
||||
<header class="masthead mb-auto">
|
||||
<div style="max-width: 80em; margin: 0 auto;" class="inner">
|
||||
<h1>{{template "app_name"}}</h1>
|
||||
<h1>{{.PublicName}}</h1>
|
||||
<nav class="nav nav-masthead justify-content-center">
|
||||
<a class="nav-link {{ if eq .ActiveView 0}}active{{ end }}" href="./admin">Upload</a>
|
||||
<a class="nav-link {{ if eq .ActiveView 1 }}active{{ end }}" href="./logs">Logs</a>
|
||||
@@ -59,7 +67,7 @@
|
||||
<div class="d-flex w-100 h-100 p-3 mx-auto flex-column">
|
||||
<header class="mb-auto">
|
||||
<div>
|
||||
<h1><a href="/index" style="text-decoration: none;display: block;">{{template "app_name"}}</a></h1>
|
||||
<h1><a href="/index" style="text-decoration: none;display: block;">{{.PublicName}}</a></h1>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// Change these for rebranding
|
||||
{{define "app_name"}}Gokapi{{end}}
|
||||
{{define "version"}}1.7.1{{end}}
|
||||
{{define "version"}}1.7.2{{end}}
|
||||
|
||||
// Specifies the version of JS files, so that the browser doesn't
|
||||
// use a cached version, if the file has been updated
|
||||
{{define "js_admin_version"}}1{{end}}
|
||||
{{define "js_dropzone_version"}}3{{end}}
|
||||
{{define "js_e2eversion"}}2{{end}}
|
||||
{{define "css_main"}}1{{end}}
|
||||
{{define "css_main"}}1{{end}}
|
||||
|
||||
Reference in New Issue
Block a user