Compare commits

...

8 Commits

Author SHA1 Message Date
Henrique Dias
d6d84e2b48 chore(release): 2.33.7 2025-06-25 17:47:23 +02:00
Henrique Dias
ca86f91621 Merge commit from fork 2025-06-25 17:42:39 +02:00
Henrique Dias
4bfbf33249 fix: linting issues 2025-06-25 17:37:18 +02:00
Henrique Dias
f19943a42e Merge commit from fork 2025-06-25 17:35:15 +02:00
Henrique Dias
e74c958862 fix: linting issues 2025-06-25 17:34:00 +02:00
Henrique Dias
221451a517 fix: correctly parse negative boolean flags 2025-06-25 17:24:06 +02:00
Henrique Dias
f46641b038 chore(release): 2.33.6 2025-06-24 22:00:57 +02:00
Henrique Dias
23bd8f6715 fix: remove incorrect default for password flag 2025-06-24 21:43:44 +02:00
8 changed files with 107 additions and 42 deletions

View File

@@ -2,6 +2,22 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [2.33.7](https://github.com/filebrowser/filebrowser/compare/v2.33.6...v2.33.7) (2025-06-25)
### Bug Fixes
* correctly parse negative boolean flags ([221451a](https://github.com/filebrowser/filebrowser/commit/221451a5179c8f139819a315b80d0ecb0e7220c3))
* linting issues ([4bfbf33](https://github.com/filebrowser/filebrowser/commit/4bfbf332499fc8aea5f6df6aae1efa0de918d1ae))
* linting issues ([e74c958](https://github.com/filebrowser/filebrowser/commit/e74c95886226c0ee429af1860eed21dd1f8601aa))
### [2.33.6](https://github.com/filebrowser/filebrowser/compare/v2.33.5...v2.33.6) (2025-06-24)
### Bug Fixes
* remove incorrect default for password flag ([23bd8f6](https://github.com/filebrowser/filebrowser/commit/23bd8f67155081d707d4799393d3b1e2bebeaa34))
### [2.33.5](https://github.com/filebrowser/filebrowser/compare/v2.33.4...v2.33.5) (2025-06-24)

View File

@@ -48,7 +48,7 @@ func init() {
persistent.StringP("database", "d", "./filebrowser.db", "database path")
flags.Bool("noauth", false, "use the noauth auther when using quick setup")
flags.String("username", "admin", "username for the first user when using quick config")
flags.String("password", "", "hashed password for the first user when using quick config (default \"admin\")")
flags.String("password", "", "hashed password for the first user when using quick config")
addServerFlags(flags)
}
@@ -201,42 +201,42 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
server, err := st.Settings.GetServer()
checkErr(err)
if val, set := getParamB(flags, "root"); set {
if val, set := getStringParamB(flags, "root"); set {
server.Root = val
}
if val, set := getParamB(flags, "baseurl"); set {
if val, set := getStringParamB(flags, "baseurl"); set {
server.BaseURL = val
}
if val, set := getParamB(flags, "log"); set {
if val, set := getStringParamB(flags, "log"); set {
server.Log = val
}
isSocketSet := false
isAddrSet := false
if val, set := getParamB(flags, "address"); set {
if val, set := getStringParamB(flags, "address"); set {
server.Address = val
isAddrSet = isAddrSet || set
}
if val, set := getParamB(flags, "port"); set {
if val, set := getStringParamB(flags, "port"); set {
server.Port = val
isAddrSet = isAddrSet || set
}
if val, set := getParamB(flags, "key"); set {
if val, set := getStringParamB(flags, "key"); set {
server.TLSKey = val
isAddrSet = isAddrSet || set
}
if val, set := getParamB(flags, "cert"); set {
if val, set := getStringParamB(flags, "cert"); set {
server.TLSCert = val
isAddrSet = isAddrSet || set
}
if val, set := getParamB(flags, "socket"); set {
if val, set := getStringParamB(flags, "socket"); set {
server.Socket = val
isSocketSet = isSocketSet || set
}
@@ -250,33 +250,62 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
server.Socket = ""
}
_, disableThumbnails := getParamB(flags, "disable-thumbnails")
disableThumbnails := getBoolParam(flags, "disable-thumbnails")
server.EnableThumbnails = !disableThumbnails
_, disablePreviewResize := getParamB(flags, "disable-preview-resize")
disablePreviewResize := getBoolParam(flags, "disable-preview-resize")
server.ResizePreview = !disablePreviewResize
_, disableTypeDetectionByHeader := getParamB(flags, "disable-type-detection-by-header")
disableTypeDetectionByHeader := getBoolParam(flags, "disable-type-detection-by-header")
server.TypeDetectionByHeader = !disableTypeDetectionByHeader
_, disableExec := getParamB(flags, "disable-exec")
disableExec := getBoolParam(flags, "disable-exec")
server.EnableExec = !disableExec
if val, set := getParamB(flags, "token-expiration-time"); set {
if val, set := getStringParamB(flags, "token-expiration-time"); set {
server.TokenExpirationTime = val
}
return server
}
// getParamB returns a parameter as a string and a boolean to tell if it is different from the default
// getBoolParamB returns a parameter as a string and a boolean to tell if it is different from the default
//
// NOTE: we could simply bind the flags to viper and use IsSet.
// Although there is a bug on Viper that always returns true on IsSet
// if a flag is binded. Our alternative way is to manually check
// the flag and then the value from env/config/gotten by viper.
// https://github.com/spf13/viper/pull/331
func getParamB(flags *pflag.FlagSet, key string) (string, bool) {
func getBoolParamB(flags *pflag.FlagSet, key string) (value, ok bool) {
value, _ = flags.GetBool(key)
// If set on Flags, use it.
if flags.Changed(key) {
return value, true
}
// If set through viper (env, config), return it.
if v.IsSet(key) {
return v.GetBool(key), true
}
// Otherwise use default value on flags.
return value, false
}
func getBoolParam(flags *pflag.FlagSet, key string) bool {
val, _ := getBoolParamB(flags, key)
return val
}
// getStringParamB returns a parameter as a string and a boolean to tell if it is different from the default
//
// NOTE: we could simply bind the flags to viper and use IsSet.
// Although there is a bug on Viper that always returns true on IsSet
// if a flag is binded. Our alternative way is to manually check
// the flag and then the value from env/config/gotten by viper.
// https://github.com/spf13/viper/pull/331
func getStringParamB(flags *pflag.FlagSet, key string) (string, bool) {
value, _ := flags.GetString(key)
// If set on Flags, use it.
@@ -293,8 +322,8 @@ func getParamB(flags *pflag.FlagSet, key string) (string, bool) {
return value, false
}
func getParam(flags *pflag.FlagSet, key string) string {
val, _ := getParamB(flags, key)
func getStringParam(flags *pflag.FlagSet, key string) string {
val, _ := getStringParamB(flags, key)
return val
}
@@ -349,7 +378,7 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
}
var err error
if _, noauth := getParamB(flags, "noauth"); noauth {
if _, noauth := getStringParamB(flags, "noauth"); noauth {
set.AuthMethod = auth.MethodNoAuth
err = d.store.Auth.Save(&auth.NoAuth{})
} else {
@@ -362,27 +391,27 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
checkErr(err)
ser := &settings.Server{
BaseURL: getParam(flags, "baseurl"),
Port: getParam(flags, "port"),
Log: getParam(flags, "log"),
TLSKey: getParam(flags, "key"),
TLSCert: getParam(flags, "cert"),
Address: getParam(flags, "address"),
Root: getParam(flags, "root"),
BaseURL: getStringParam(flags, "baseurl"),
Port: getStringParam(flags, "port"),
Log: getStringParam(flags, "log"),
TLSKey: getStringParam(flags, "key"),
TLSCert: getStringParam(flags, "cert"),
Address: getStringParam(flags, "address"),
Root: getStringParam(flags, "root"),
}
err = d.store.Settings.SaveServer(ser)
checkErr(err)
username := getParam(flags, "username")
password := getParam(flags, "password")
username := getStringParam(flags, "username")
password := getStringParam(flags, "password")
if password == "" {
var pwd string
pwd, err = users.RandomPwd()
checkErr(err)
log.Println("Generated random admin password for quick setup:", pwd)
log.Println("Randomly generated password for user 'admin':", pwd)
password, err = users.HashPwd(pwd)
checkErr(err)
@@ -420,6 +449,7 @@ func initConfig() {
v.SetEnvPrefix("FB")
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
if err := v.ReadInConfig(); err != nil {
var configParseError v.ConfigParseError

View File

@@ -25,7 +25,7 @@ this version.`,
flags := cmd.Flags()
oldDB := mustGetString(flags, "old.database")
oldConf := mustGetString(flags, "old.config")
err := importer.Import(oldDB, oldConf, getParam(flags, "database"))
err := importer.Import(oldDB, oldConf, getStringParam(flags, "database"))
checkErr(err)
},
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/spf13/pflag"
yaml "gopkg.in/yaml.v2"
"github.com/filebrowser/filebrowser/v2/files"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/storage"
"github.com/filebrowser/filebrowser/v2/storage/bolt"
@@ -86,7 +87,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
return func(cmd *cobra.Command, args []string) {
data := pythonData{hadDB: true}
path := getParam(cmd.Flags(), "database")
path := getStringParam(cmd.Flags(), "database")
absPath, err := filepath.Abs(path)
if err != nil {
panic(err)
@@ -105,7 +106,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
log.Println("Using database: " + absPath)
data.hadDB = exists
db, err := storm.Open(path)
db, err := storm.Open(path, storm.BoltOptions(files.PermFile, nil))
checkErr(err)
defer db.Close()
data.store, err = bolt.NewStorage(db)

View File

@@ -27,8 +27,8 @@ import (
"github.com/filebrowser/filebrowser/v2/rules"
)
const PermFile = 0644
const PermDir = 0755
const PermFile = 0640
const PermDir = 0750
var (
reSubDirs = regexp.MustCompile("(?i)^sub(s|titles)$")

View File

@@ -24,6 +24,7 @@
"ace-builds": "^1.37.5",
"core-js": "^3.40.0",
"dayjs": "^1.11.10",
"dompurify": "^3.2.6",
"epubjs": "^0.3.93",
"filesize": "^10.1.1",
"js-base64": "^3.7.7",

View File

@@ -26,6 +26,9 @@ importers:
dayjs:
specifier: ^1.11.10
version: 1.11.13
dompurify:
specifier: ^3.2.6
version: 3.2.6
epubjs:
specifier: ^0.3.93
version: 0.3.93
@@ -946,8 +949,8 @@ packages:
resolution: {integrity: sha512-dF2iMMy8P9uKVHV/20LA1ulFLL+MKSbfMiixSmn6fpwqzvix38OIc7ebgnFbBqElvghZCW9ACtzKTGKsTGTWGA==}
engines: {node: '>= 16'}
'@intlify/shared@11.1.3':
resolution: {integrity: sha512-pTFBgqa/99JRA2H1qfyqv97MKWJrYngXBA/I0elZcYxvJgcCw3mApAoPW3mJ7vx3j+Ti0FyKUFZ4hWxdjKaxvA==}
'@intlify/shared@11.1.7':
resolution: {integrity: sha512-4yZeMt2Aa/7n5Ehy4KalUlvt3iRLcg1tq9IBVfOgkyWFArN4oygn6WxgGIFibP3svpaH8DarbNaottq+p0gUZQ==}
engines: {node: '>= 16'}
'@intlify/shared@12.0.0-alpha.2':
@@ -1174,6 +1177,9 @@ packages:
'@types/node@22.10.10':
resolution: {integrity: sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==}
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
'@types/web-bluetooth@0.0.20':
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
@@ -1602,6 +1608,9 @@ packages:
dom-walk@0.1.2:
resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==}
dompurify@3.2.6:
resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==}
electron-to-chromium@1.5.67:
resolution: {integrity: sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==}
@@ -3628,7 +3637,7 @@ snapshots:
'@intlify/shared@11.1.2': {}
'@intlify/shared@11.1.3': {}
'@intlify/shared@11.1.7': {}
'@intlify/shared@12.0.0-alpha.2': {}
@@ -3636,8 +3645,8 @@ snapshots:
dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0)
'@intlify/bundle-utils': 10.0.0(vue-i18n@11.1.2(vue@3.5.13(typescript@5.6.3)))
'@intlify/shared': 11.1.3
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.3)(@vue/compiler-dom@3.5.13)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3))
'@intlify/shared': 11.1.7
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.7)(@vue/compiler-dom@3.5.13)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3))
'@rollup/pluginutils': 5.1.4(rollup@4.40.1)
'@typescript-eslint/scope-manager': 8.21.0
'@typescript-eslint/typescript-estree': 8.21.0(typescript@5.6.3)
@@ -3659,11 +3668,11 @@ snapshots:
- supports-color
- typescript
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.3)(@vue/compiler-dom@3.5.13)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3))':
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.7)(@vue/compiler-dom@3.5.13)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3))':
dependencies:
'@babel/parser': 7.26.7
optionalDependencies:
'@intlify/shared': 11.1.3
'@intlify/shared': 11.1.7
'@vue/compiler-dom': 3.5.13
vue: 3.5.13(typescript@5.6.3)
vue-i18n: 11.1.2(vue@3.5.13(typescript@5.6.3))
@@ -3812,6 +3821,9 @@ snapshots:
dependencies:
undici-types: 6.20.0
'@types/trusted-types@2.0.7':
optional: true
'@types/web-bluetooth@0.0.20': {}
'@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0)(typescript@5.6.3))(eslint@9.19.0)(typescript@5.6.3)':
@@ -4282,6 +4294,10 @@ snapshots:
dom-walk@0.1.2: {}
dompurify@3.2.6:
optionalDependencies:
'@types/trusted-types': 2.0.7
electron-to-chromium@1.5.67: {}
emoji-regex@8.0.0: {}

View File

@@ -41,6 +41,7 @@ import url from "@/utils/url";
import ace, { Ace, version as ace_version } from "ace-builds";
import modelist from "ace-builds/src-noconflict/ext-modelist";
import "ace-builds/src-noconflict/ext-language_tools";
import DOMPurify from "dompurify";
import HeaderBar from "@/components/header/HeaderBar.vue";
import Action from "@/components/header/Action.vue";
@@ -83,7 +84,7 @@ onMounted(() => {
if (isMarkdownFile && isPreview.value) {
const new_value = editor.value?.getValue() || "";
try {
previewContent.value = await marked(new_value);
previewContent.value = DOMPurify.sanitize(await marked(new_value));
} catch (error) {
console.error("Failed to convert content to HTML:", error);
previewContent.value = "";