|
@@ -60,6 +60,7 @@ const (
|
|
templateClientShare = "share.html"
|
|
templateClientShare = "share.html"
|
|
templateClientShares = "shares.html"
|
|
templateClientShares = "shares.html"
|
|
templateClientViewPDF = "viewpdf.html"
|
|
templateClientViewPDF = "viewpdf.html"
|
|
|
|
+ templateShareLogin = "sharelogin.html"
|
|
templateShareFiles = "sharefiles.html"
|
|
templateShareFiles = "sharefiles.html"
|
|
templateUploadToShare = "shareupload.html"
|
|
templateUploadToShare = "shareupload.html"
|
|
pageClientFilesTitle = "My Files"
|
|
pageClientFilesTitle = "My Files"
|
|
@@ -156,6 +157,15 @@ type filesPage struct {
|
|
HasIntegrations bool
|
|
HasIntegrations bool
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+type shareLoginPage struct {
|
|
|
|
+ CurrentURL string
|
|
|
|
+ Version string
|
|
|
|
+ Error string
|
|
|
|
+ CSRFToken string
|
|
|
|
+ StaticURL string
|
|
|
|
+ Branding UIBranding
|
|
|
|
+}
|
|
|
|
+
|
|
type shareFilesPage struct {
|
|
type shareFilesPage struct {
|
|
baseClientPage
|
|
baseClientPage
|
|
CurrentDir string
|
|
CurrentDir string
|
|
@@ -298,6 +308,11 @@ func loadClientTemplates(templatesPath string) {
|
|
filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
filepath.Join(templatesPath, templateClientDir, templateClientViewPDF),
|
|
filepath.Join(templatesPath, templateClientDir, templateClientViewPDF),
|
|
}
|
|
}
|
|
|
|
+ shareLoginPath := []string{
|
|
|
|
+ filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
|
|
+ filepath.Join(templatesPath, templateClientDir, templateClientBaseLogin),
|
|
|
|
+ filepath.Join(templatesPath, templateClientDir, templateShareLogin),
|
|
|
|
+ }
|
|
shareFilesPath := []string{
|
|
shareFilesPath := []string{
|
|
filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
filepath.Join(templatesPath, templateClientDir, templateClientBase),
|
|
filepath.Join(templatesPath, templateClientDir, templateClientBase),
|
|
@@ -318,6 +333,7 @@ func loadClientTemplates(templatesPath string) {
|
|
twoFactorTmpl := util.LoadTemplate(nil, twoFactorPath...)
|
|
twoFactorTmpl := util.LoadTemplate(nil, twoFactorPath...)
|
|
twoFactorRecoveryTmpl := util.LoadTemplate(nil, twoFactorRecoveryPath...)
|
|
twoFactorRecoveryTmpl := util.LoadTemplate(nil, twoFactorRecoveryPath...)
|
|
editFileTmpl := util.LoadTemplate(nil, editFilePath...)
|
|
editFileTmpl := util.LoadTemplate(nil, editFilePath...)
|
|
|
|
+ shareLoginTmpl := util.LoadTemplate(nil, shareLoginPath...)
|
|
sharesTmpl := util.LoadTemplate(nil, sharesPaths...)
|
|
sharesTmpl := util.LoadTemplate(nil, sharesPaths...)
|
|
shareTmpl := util.LoadTemplate(nil, sharePaths...)
|
|
shareTmpl := util.LoadTemplate(nil, sharePaths...)
|
|
forgotPwdTmpl := util.LoadTemplate(nil, forgotPwdPaths...)
|
|
forgotPwdTmpl := util.LoadTemplate(nil, forgotPwdPaths...)
|
|
@@ -340,6 +356,7 @@ func loadClientTemplates(templatesPath string) {
|
|
clientTemplates[templateForgotPassword] = forgotPwdTmpl
|
|
clientTemplates[templateForgotPassword] = forgotPwdTmpl
|
|
clientTemplates[templateResetPassword] = resetPwdTmpl
|
|
clientTemplates[templateResetPassword] = resetPwdTmpl
|
|
clientTemplates[templateClientViewPDF] = viewPDFTmpl
|
|
clientTemplates[templateClientViewPDF] = viewPDFTmpl
|
|
|
|
+ clientTemplates[templateShareLogin] = shareLoginTmpl
|
|
clientTemplates[templateShareFiles] = shareFilesTmpl
|
|
clientTemplates[templateShareFiles] = shareFilesTmpl
|
|
clientTemplates[templateUploadToShare] = shareUploadTmpl
|
|
clientTemplates[templateUploadToShare] = shareUploadTmpl
|
|
}
|
|
}
|
|
@@ -397,6 +414,18 @@ func (s *httpdServer) renderClientResetPwdPage(w http.ResponseWriter, error, ip
|
|
renderClientTemplate(w, templateResetPassword, data)
|
|
renderClientTemplate(w, templateResetPassword, data)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (s *httpdServer) renderShareLoginPage(w http.ResponseWriter, currentURL, error, ip string) {
|
|
|
|
+ data := shareLoginPage{
|
|
|
|
+ CurrentURL: currentURL,
|
|
|
|
+ Version: version.Get().Version,
|
|
|
|
+ Error: error,
|
|
|
|
+ CSRFToken: createCSRFToken(ip),
|
|
|
|
+ StaticURL: webStaticFilesPath,
|
|
|
|
+ Branding: s.binding.Branding.WebClient,
|
|
|
|
+ }
|
|
|
|
+ renderClientTemplate(w, templateShareLogin, data)
|
|
|
|
+}
|
|
|
|
+
|
|
func renderClientTemplate(w http.ResponseWriter, tmplName string, data any) {
|
|
func renderClientTemplate(w http.ResponseWriter, tmplName string, data any) {
|
|
err := clientTemplates[tmplName].ExecuteTemplate(w, tmplName, data)
|
|
err := clientTemplates[tmplName].ExecuteTemplate(w, tmplName, data)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -663,7 +692,7 @@ func (s *httpdServer) handleWebClientDownloadZip(w http.ResponseWriter, r *http.
|
|
func (s *httpdServer) handleClientSharePartialDownload(w http.ResponseWriter, r *http.Request) {
|
|
func (s *httpdServer) handleClientSharePartialDownload(w http.ResponseWriter, r *http.Request) {
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
validScopes := []dataprovider.ShareScope{dataprovider.ShareScopeRead, dataprovider.ShareScopeReadWrite}
|
|
validScopes := []dataprovider.ShareScope{dataprovider.ShareScopeRead, dataprovider.ShareScopeReadWrite}
|
|
- share, connection, err := s.checkPublicShare(w, r, validScopes, true)
|
|
|
|
|
|
+ share, connection, err := s.checkPublicShare(w, r, validScopes)
|
|
if err != nil {
|
|
if err != nil {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -706,7 +735,7 @@ func (s *httpdServer) handleClientSharePartialDownload(w http.ResponseWriter, r
|
|
func (s *httpdServer) handleShareGetDirContents(w http.ResponseWriter, r *http.Request) {
|
|
func (s *httpdServer) handleShareGetDirContents(w http.ResponseWriter, r *http.Request) {
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
validScopes := []dataprovider.ShareScope{dataprovider.ShareScopeRead, dataprovider.ShareScopeReadWrite}
|
|
validScopes := []dataprovider.ShareScope{dataprovider.ShareScopeRead, dataprovider.ShareScopeReadWrite}
|
|
- share, connection, err := s.checkPublicShare(w, r, validScopes, true)
|
|
|
|
|
|
+ share, connection, err := s.checkPublicShare(w, r, validScopes)
|
|
if err != nil {
|
|
if err != nil {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -757,7 +786,7 @@ func (s *httpdServer) handleShareGetDirContents(w http.ResponseWriter, r *http.R
|
|
func (s *httpdServer) handleClientUploadToShare(w http.ResponseWriter, r *http.Request) {
|
|
func (s *httpdServer) handleClientUploadToShare(w http.ResponseWriter, r *http.Request) {
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
validScopes := []dataprovider.ShareScope{dataprovider.ShareScopeWrite, dataprovider.ShareScopeReadWrite}
|
|
validScopes := []dataprovider.ShareScope{dataprovider.ShareScopeWrite, dataprovider.ShareScopeReadWrite}
|
|
- share, _, err := s.checkPublicShare(w, r, validScopes, true)
|
|
|
|
|
|
+ share, _, err := s.checkPublicShare(w, r, validScopes)
|
|
if err != nil {
|
|
if err != nil {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -771,7 +800,7 @@ func (s *httpdServer) handleClientUploadToShare(w http.ResponseWriter, r *http.R
|
|
func (s *httpdServer) handleShareGetFiles(w http.ResponseWriter, r *http.Request) {
|
|
func (s *httpdServer) handleShareGetFiles(w http.ResponseWriter, r *http.Request) {
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
validScopes := []dataprovider.ShareScope{dataprovider.ShareScopeRead, dataprovider.ShareScopeReadWrite}
|
|
validScopes := []dataprovider.ShareScope{dataprovider.ShareScopeRead, dataprovider.ShareScopeReadWrite}
|
|
- share, connection, err := s.checkPublicShare(w, r, validScopes, true)
|
|
|
|
|
|
+ share, connection, err := s.checkPublicShare(w, r, validScopes)
|
|
if err != nil {
|
|
if err != nil {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -1427,3 +1456,46 @@ func (s *httpdServer) handleClientGetPDF(w http.ResponseWriter, r *http.Request)
|
|
}
|
|
}
|
|
downloadFile(w, r, connection, name, info, true, nil) //nolint:errcheck
|
|
downloadFile(w, r, connection, name, info, true, nil) //nolint:errcheck
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleClientShareLoginGet(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxLoginBodySize)
|
|
|
|
+ s.renderShareLoginPage(w, r.RequestURI, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleClientShareLoginPost(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxLoginBodySize)
|
|
|
|
+ ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
|
|
+ if err := r.ParseForm(); err != nil {
|
|
|
|
+ s.renderShareLoginPage(w, r.RequestURI, err.Error(), ipAddr)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
|
|
|
+ s.renderShareLoginPage(w, r.RequestURI, err.Error(), ipAddr)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ shareID := getURLParam(r, "id")
|
|
|
|
+ share, err := dataprovider.ShareExists(shareID, "")
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderShareLoginPage(w, r.RequestURI, dataprovider.ErrInvalidCredentials.Error(), ipAddr)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ match, err := share.CheckCredentials(r.Form.Get("share_password"))
|
|
|
|
+ if !match || err != nil {
|
|
|
|
+ s.renderShareLoginPage(w, r.RequestURI, dataprovider.ErrInvalidCredentials.Error(), ipAddr)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ c := jwtTokenClaims{
|
|
|
|
+ Username: shareID,
|
|
|
|
+ }
|
|
|
|
+ err = c.createAndSetCookie(w, r, s.tokenAuth, tokenAudienceWebShare, ipAddr)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderShareLoginPage(w, r.RequestURI, common.ErrInternalFailure.Error(), ipAddr)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ next := r.URL.Query().Get("next")
|
|
|
|
+ if strings.HasPrefix(next, path.Join(webClientPubSharesPath, share.ShareID)) {
|
|
|
|
+ http.Redirect(w, r, next, http.StatusFound)
|
|
|
|
+ }
|
|
|
|
+ s.renderClientMessagePage(w, r, "Share Login OK", "Share login successful, you can now use your link",
|
|
|
|
+ http.StatusOK, nil, "")
|
|
|
|
+}
|