Merge 6e6beab914
into 089255997a
commit
f0d4e830f3
|
@ -38,6 +38,8 @@ func addConfigFlags(flags *pflag.FlagSet) {
|
|||
flags.String("auth.header", "", "HTTP header for auth.method=proxy")
|
||||
flags.String("auth.command", "", "command for auth.method=hook")
|
||||
|
||||
flags.String("logoutpage", "", "custom logout page")
|
||||
|
||||
flags.String("recaptcha.host", "https://www.google.com", "use another host for ReCAPTCHA. recaptcha.net might be useful in China")
|
||||
flags.String("recaptcha.key", "", "ReCaptcha site key")
|
||||
flags.String("recaptcha.secret", "", "ReCaptcha secret")
|
||||
|
@ -145,6 +147,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
|||
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
|
||||
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
|
||||
fmt.Fprintf(w, "Auth method:\t%s\n", set.AuthMethod)
|
||||
fmt.Fprintf(w, "LogoutPage:\t%s\n", set.LogoutPage)
|
||||
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
|
||||
fmt.Fprintln(w, "\nBranding:")
|
||||
fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name)
|
||||
|
|
|
@ -47,6 +47,8 @@ you want to change. Other options will remain unchanged.`,
|
|||
set.Signup = mustGetBool(flags, flag.Name)
|
||||
case "auth.method":
|
||||
hasAuth = true
|
||||
case "logoutpage":
|
||||
set.LogoutPage = mustGetString(flags, flag.Name)
|
||||
case "shell":
|
||||
set.Shell = convertCmdStrToCmdArray(mustGetString(flags, flag.Name))
|
||||
case "create-user-dir":
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
DisableUsedPercentage: false,
|
||||
EnableExec: true,
|
||||
EnableThumbs: true,
|
||||
LogoutPage: "",
|
||||
LoginPage: true,
|
||||
Name: "",
|
||||
NoAuth: false,
|
||||
|
|
|
@ -124,6 +124,7 @@ import {
|
|||
disableExternal,
|
||||
disableUsedPercentage,
|
||||
noAuth,
|
||||
logoutPage,
|
||||
loginPage,
|
||||
} from "@/utils/constants";
|
||||
import { files as api } from "@/api";
|
||||
|
@ -153,7 +154,7 @@ export default {
|
|||
version: () => version,
|
||||
disableExternal: () => disableExternal,
|
||||
disableUsedPercentage: () => disableUsedPercentage,
|
||||
canLogout: () => !noAuth && loginPage,
|
||||
canLogout: () => !noAuth && (loginPage || logoutPage !== "/login"),
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useLayoutStore, ["closeHovers", "showHover"]),
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useAuthStore } from "@/stores/auth";
|
|||
import router from "@/router";
|
||||
import type { JwtPayload } from "jwt-decode";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import { baseURL, noAuth } from "./constants";
|
||||
import { baseURL, noAuth, logoutPage } from "./constants";
|
||||
import { StatusError } from "@/api/utils";
|
||||
|
||||
export function parseToken(token: string) {
|
||||
|
@ -101,6 +101,8 @@ export function logout() {
|
|||
localStorage.setItem("jwt", "");
|
||||
if (noAuth) {
|
||||
window.location.reload();
|
||||
} else if (logoutPage !== "/login") {
|
||||
document.location.href = `${logoutPage}`;
|
||||
} else {
|
||||
router.push({ path: "/login" });
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ const version: string = window.FileBrowser.Version;
|
|||
const logoURL = `${staticURL}/img/logo.svg`;
|
||||
const noAuth: boolean = window.FileBrowser.NoAuth;
|
||||
const authMethod = window.FileBrowser.AuthMethod;
|
||||
const logoutPage: string = window.FileBrowser.LogoutPage || "/login";
|
||||
const loginPage: boolean = window.FileBrowser.LoginPage;
|
||||
const theme: UserTheme = window.FileBrowser.Theme;
|
||||
const enableThumbs: boolean = window.FileBrowser.EnableThumbs;
|
||||
|
@ -31,6 +32,7 @@ export {
|
|||
version,
|
||||
noAuth,
|
||||
authMethod,
|
||||
logoutPage,
|
||||
loginPage,
|
||||
theme,
|
||||
enableThumbs,
|
||||
|
|
21
http/auth.go
21
http/auth.go
|
@ -12,7 +12,9 @@ import (
|
|||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v4/request"
|
||||
|
||||
fbAuth "github.com/filebrowser/filebrowser/v2/auth"
|
||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/users"
|
||||
)
|
||||
|
||||
|
@ -64,6 +66,20 @@ func (e extractor) ExtractToken(r *http.Request) (string, error) {
|
|||
return "", request.ErrNoTokenInRequest
|
||||
}
|
||||
|
||||
func renewableErr(err error, d *data) bool {
|
||||
if d.settings.AuthMethod != fbAuth.MethodProxyAuth || err == nil {
|
||||
return false
|
||||
}
|
||||
if d.settings.LogoutPage == "" || d.settings.LogoutPage == settings.DefaultLogoutPage {
|
||||
return false
|
||||
}
|
||||
var verr *jwt.ValidationError
|
||||
if !errors.As(err, &verr) || verr == nil || verr.Errors != jwt.ValidationErrorExpired {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func withUser(fn handleFunc) handleFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||
keyFunc := func(_ *jwt.Token) (interface{}, error) {
|
||||
|
@ -71,9 +87,10 @@ func withUser(fn handleFunc) handleFunc {
|
|||
}
|
||||
|
||||
var tk authToken
|
||||
token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk))
|
||||
p := jwt.NewParser(jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Alg()}))
|
||||
token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk), request.WithParser(p))
|
||||
|
||||
if err != nil || !token.Valid {
|
||||
if (err != nil || !token.Valid) && !renewableErr(err, d) {
|
||||
return http.StatusUnauthorized, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, fSys
|
|||
"Signup": d.settings.Signup,
|
||||
"NoAuth": d.settings.AuthMethod == auth.MethodNoAuth,
|
||||
"AuthMethod": d.settings.AuthMethod,
|
||||
"LogoutPage": d.settings.LogoutPage,
|
||||
"LoginPage": auther.LoginPage(),
|
||||
"CSS": false,
|
||||
"ReCaptcha": false,
|
||||
|
|
|
@ -9,7 +9,10 @@ import (
|
|||
"github.com/filebrowser/filebrowser/v2/rules"
|
||||
)
|
||||
|
||||
const DefaultUsersHomeBasePath = "/users"
|
||||
const (
|
||||
DefaultLogoutPage = "/login"
|
||||
DefaultUsersHomeBasePath = "/users"
|
||||
)
|
||||
|
||||
// AuthMethod describes an authentication method.
|
||||
type AuthMethod string
|
||||
|
@ -22,6 +25,7 @@ type Settings struct {
|
|||
UserHomeBasePath string `json:"userHomeBasePath"`
|
||||
Defaults UserDefaults `json:"defaults"`
|
||||
AuthMethod AuthMethod `json:"authMethod"`
|
||||
LogoutPage string `json:"logoutPage"`
|
||||
Branding Branding `json:"branding"`
|
||||
Tus Tus `json:"tus"`
|
||||
Commands map[string][]string `json:"commands"`
|
||||
|
|
|
@ -33,6 +33,9 @@ func (s *Storage) Get() (*Settings, error) {
|
|||
if set.UserHomeBasePath == "" {
|
||||
set.UserHomeBasePath = DefaultUsersHomeBasePath
|
||||
}
|
||||
if set.LogoutPage == "" {
|
||||
set.LogoutPage = DefaultLogoutPage
|
||||
}
|
||||
if set.Tus == (Tus{}) {
|
||||
set.Tus = Tus{
|
||||
ChunkSize: DefaultTusChunkSize,
|
||||
|
|
Loading…
Reference in New Issue