Support embedded viewer
This commit is contained in:
7
go.mod
7
go.mod
@@ -1,18 +1,21 @@
|
||||
module fornaxian.tech/pixeldrain_web
|
||||
|
||||
go 1.14
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
fornaxian.tech/pd_database => ../pd_database
|
||||
fornaxian.tech/pixeldrain_api_client => ../pixeldrain_api_client
|
||||
fornaxian.tech/pixeldrain_server/api => ../pixeldrain_server/api
|
||||
fornaxian.tech/pixeldrain_server/database => ../pixeldrain_server/database
|
||||
fornaxian.tech/pixeldrain_server/pixelstore => ../pixeldrain_server/pixelstore
|
||||
fornaxian.tech/pixeldrain_server/util => ../pixeldrain_server/util
|
||||
github.com/gocql/gocql => github.com/scylladb/gocql v1.5.0
|
||||
)
|
||||
|
||||
require (
|
||||
fornaxian.tech/pixeldrain_server/api v0.0.0-00010101000000-000000000000
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-00010101000000-000000000000
|
||||
fornaxian.tech/pixeldrain_server/util v0.0.0-00010101000000-000000000000
|
||||
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||
github.com/Fornaxian/config v0.0.0-20180915150834-ac41cf746a70
|
||||
github.com/Fornaxian/log v0.0.0-20190617093801-1c7ce9a7c9b3
|
||||
github.com/Fornaxian/pd_mime_type v0.0.0-20200204165508-2815edf3a145
|
||||
|
@@ -25,6 +25,24 @@ function Viewer(type, viewToken, data) {
|
||||
this.toolbar.toggle()
|
||||
}
|
||||
|
||||
if (embeddedViewer) {
|
||||
// Remove padding from the headerbar
|
||||
document.getElementById("file_viewer_headerbar").classList += " file_viewer_headerbar_embedded"
|
||||
|
||||
// Hide toolbar by default
|
||||
if (this.toolbar.visible) {
|
||||
this.toolbar.toggle()
|
||||
}
|
||||
|
||||
// Alter home button to open in a new tab
|
||||
document.getElementById("button_home").setAttribute("target", "_blank")
|
||||
|
||||
// Remove sponsor bar if ads are disabled
|
||||
if (!data.show_ads) {
|
||||
document.getElementById("sponsors").remove()
|
||||
}
|
||||
}
|
||||
|
||||
if (type === "file") {
|
||||
this.isFile = true
|
||||
this.title = data.name
|
||||
|
@@ -25,6 +25,9 @@
|
||||
z-index: 10;
|
||||
box-shadow: none;
|
||||
}
|
||||
.file_viewer > .file_viewer_headerbar_embedded {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/* Headerbar components */
|
||||
.file_viewer > .file_viewer_headerbar > * {
|
||||
|
@@ -277,6 +277,7 @@
|
||||
'use strict';
|
||||
let apiEndpoint = '{{.APIEndpoint}}';
|
||||
let captchaKey = '{{.Other.CaptchaKey}}';
|
||||
let embeddedViewer = {{.Other.Embedded}};
|
||||
let highlightColor = '#{{.Style.HighlightColor.RGB}}';
|
||||
{{template `util.js`}}
|
||||
{{template `drawGraph.js`}}
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"fornaxian.tech/pixeldrain_server/api/restapi/apiclient"
|
||||
"fornaxian.tech/pixeldrain_api_client/pixelapi"
|
||||
"github.com/Fornaxian/log"
|
||||
)
|
||||
|
||||
@@ -65,7 +65,7 @@ func (wc *WebController) adminGlobalsForm(td *TemplateData, r *http.Request) (f
|
||||
|
||||
// Value changed, try to update global setting
|
||||
if err = td.PixelAPI.AdminSetGlobals(v.Name, v.EnteredValue); err != nil {
|
||||
if apiErr, ok := err.(apiclient.Error); ok {
|
||||
if apiErr, ok := err.(pixelapi.Error); ok {
|
||||
f.SubmitMessages = append(f.SubmitMessages, template.HTML(apiErr.Message))
|
||||
} else {
|
||||
log.Error("%s", err)
|
||||
|
@@ -10,8 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"fornaxian.tech/pixeldrain_server/api/restapi/apiclient"
|
||||
"fornaxian.tech/pixeldrain_server/api/restapi/apitype"
|
||||
"fornaxian.tech/pixeldrain_api_client/pixelapi"
|
||||
"github.com/Fornaxian/log"
|
||||
pdmimetype "github.com/Fornaxian/pd_mime_type"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
@@ -72,6 +71,7 @@ type viewerData struct {
|
||||
AdType int
|
||||
FileAdsEnabled bool
|
||||
UserAdsEnabled bool
|
||||
Embedded bool
|
||||
APIResponse interface{}
|
||||
}
|
||||
|
||||
@@ -87,17 +87,17 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
|
||||
templateData := wc.newTemplateData(w, r)
|
||||
|
||||
var files []apitype.ListFile
|
||||
var files []pixelapi.ListFile
|
||||
for _, id := range ids {
|
||||
inf, err := templateData.PixelAPI.GetFileInfo(id)
|
||||
if err != nil {
|
||||
if apiclient.ErrIsServerError(err) {
|
||||
if pixelapi.ErrIsServerError(err) {
|
||||
wc.templates.Get().ExecuteTemplate(w, "500", templateData)
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
files = append(files, apitype.ListFile{FileInfo: inf})
|
||||
files = append(files, pixelapi.ListFile{FileInfo: inf})
|
||||
}
|
||||
|
||||
if len(files) == 0 {
|
||||
@@ -115,10 +115,11 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
FileAdsEnabled: files[0].ShowAds,
|
||||
UserAdsEnabled: !(templateData.Authenticated && templateData.User.Subscription.DisableAdDisplay),
|
||||
}
|
||||
|
||||
if len(ids) > 1 {
|
||||
templateData.Title = fmt.Sprintf("%d files on pixeldrain", len(files))
|
||||
vd.Type = "list"
|
||||
vd.APIResponse = apitype.ListInfo{
|
||||
vd.APIResponse = pixelapi.ListInfo{
|
||||
Success: true,
|
||||
Title: "Multiple files",
|
||||
DateCreated: time.Now(),
|
||||
@@ -129,6 +130,11 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
vd.Type = "file"
|
||||
vd.APIResponse = files[0].FileInfo
|
||||
}
|
||||
|
||||
if _, ok := r.URL.Query()["embed"]; ok {
|
||||
vd.Embedded = true
|
||||
}
|
||||
|
||||
templateData.Other = vd
|
||||
|
||||
var templateName = "file_viewer"
|
||||
@@ -184,9 +190,9 @@ func (wc *WebController) serveFileViewerDemo(w http.ResponseWriter, r *http.Requ
|
||||
// ServeListViewer controller for GET /l/:id
|
||||
func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
var templateData = wc.newTemplateData(w, r)
|
||||
var list, err = templateData.PixelAPI.GetList(p.ByName("id"))
|
||||
var list, err = templateData.PixelAPI.GetListID(p.ByName("id"))
|
||||
if err != nil {
|
||||
if err, ok := err.(apiclient.Error); ok && err.Status == http.StatusNotFound {
|
||||
if err, ok := err.(pixelapi.Error); ok && err.Status == http.StatusNotFound {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
wc.templates.Get().ExecuteTemplate(w, "list_not_found", templateData)
|
||||
} else {
|
||||
@@ -204,7 +210,7 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request,
|
||||
|
||||
templateData.Title = fmt.Sprintf("%s ~ pixeldrain", list.Title)
|
||||
templateData.OGData = wc.metadataFromList(list)
|
||||
templateData.Other = viewerData{
|
||||
var vd = viewerData{
|
||||
Type: "list",
|
||||
CaptchaKey: wc.captchaSiteKey,
|
||||
ViewToken: wc.viewTokenOrBust(),
|
||||
@@ -214,6 +220,11 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request,
|
||||
APIResponse: list,
|
||||
}
|
||||
|
||||
if _, ok := r.URL.Query()["embed"]; ok {
|
||||
vd.Embedded = true
|
||||
}
|
||||
templateData.Other = vd
|
||||
|
||||
var templateName = "file_viewer"
|
||||
if browserCompat(r.UserAgent()) {
|
||||
templateName = "file_viewer_compat"
|
||||
@@ -307,7 +318,7 @@ func (wc *WebController) serveSkynetViewer(w http.ResponseWriter, r *http.Reques
|
||||
templateData.Other = viewerData{
|
||||
Type: "skylink",
|
||||
AdType: adType(),
|
||||
APIResponse: apitype.FileInfo{
|
||||
APIResponse: pixelapi.FileInfo{
|
||||
Success: true,
|
||||
ID: p.ByName("id"),
|
||||
Name: name,
|
||||
|
@@ -17,7 +17,7 @@ func (wc *WebController) serveShareXConfig(w http.ResponseWriter, r *http.Reques
|
||||
|
||||
w.Header().Add("Content-Disposition", "attachment; filename=pixeldrain.com.sxcu")
|
||||
if templateData.Authenticated {
|
||||
sess, err := templateData.PixelAPI.UserSessionCreate()
|
||||
sess, err := templateData.PixelAPI.PostUserSession()
|
||||
if err != nil {
|
||||
log.Error("Failed to create user session: %s", err)
|
||||
wc.templates.Get().ExecuteTemplate(w, "500", templateData)
|
||||
|
@@ -3,7 +3,7 @@ package webcontroller
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"fornaxian.tech/pixeldrain_server/api/restapi/apitype"
|
||||
"fornaxian.tech/pixeldrain_api_client/pixelapi"
|
||||
)
|
||||
|
||||
type ogData struct {
|
||||
@@ -21,7 +21,7 @@ func (og *ogData) addOG(k, v string) { og.OGRules = append(og.OGRules, ogPr
|
||||
func (og *ogData) addTwitter(k, v string) { og.TwitterRules = append(og.TwitterRules, ogProp{k, v}) }
|
||||
func (og *ogData) addLink(k, v string) { og.LinkRules = append(og.LinkRules, ogProp{k, v}) }
|
||||
|
||||
func (wc *WebController) metadataFromFile(f apitype.FileInfo) (og ogData) {
|
||||
func (wc *WebController) metadataFromFile(f pixelapi.FileInfo) (og ogData) {
|
||||
og.addOG("og:title", f.Name)
|
||||
og.addOG("og:site_name", "pixeldrain")
|
||||
og.addOG("og:description", "This file has been shared with you on pixeldrain")
|
||||
@@ -67,7 +67,7 @@ func (wc *WebController) metadataFromFile(f apitype.FileInfo) (og ogData) {
|
||||
}
|
||||
return og
|
||||
}
|
||||
func (wc *WebController) metadataFromList(l apitype.ListInfo) (og ogData) {
|
||||
func (wc *WebController) metadataFromList(l pixelapi.ListInfo) (og ogData) {
|
||||
og.addOG("og:type", "website")
|
||||
og.addOG("og:title", l.Title)
|
||||
og.addOG("og:site_name", "pixeldrain")
|
||||
|
@@ -18,7 +18,7 @@ func (wc *WebController) patreonLinkForm(td *TemplateData, r *http.Request) (f F
|
||||
return f
|
||||
}
|
||||
|
||||
patron, err := td.PixelAPI.PatreonByID(r.FormValue("key"))
|
||||
patron, err := td.PixelAPI.GetPatreonByID(r.FormValue("key"))
|
||||
if err != nil && err.Error() == "not_found" {
|
||||
f.Submitted = true
|
||||
f.SubmitMessages = []template.HTML{"Patron ID not found"}
|
||||
@@ -76,7 +76,7 @@ func (wc *WebController) patreonLinkForm(td *TemplateData, r *http.Request) (f F
|
||||
}}
|
||||
|
||||
if f.ReadInput(r) {
|
||||
if err := td.PixelAPI.PatreonLink(r.FormValue("key")); err != nil {
|
||||
if err := td.PixelAPI.PostPatreonLink(r.FormValue("key")); err != nil {
|
||||
formAPIError(err, &f)
|
||||
} else {
|
||||
// Request was a success
|
||||
@@ -105,7 +105,7 @@ func (wc *WebController) knoxfsLinkForm(td *TemplateData, r *http.Request) (f Fo
|
||||
return f
|
||||
}
|
||||
|
||||
sub, err := td.PixelAPI.SubscriptionByID(r.FormValue("key"))
|
||||
sub, err := td.PixelAPI.GetSubscriptionID(r.FormValue("key"))
|
||||
if err != nil && err.Error() == "not_found" {
|
||||
f.Submitted = true
|
||||
f.SubmitMessages = []template.HTML{"Subscription ID not found"}
|
||||
@@ -163,7 +163,7 @@ func (wc *WebController) knoxfsLinkForm(td *TemplateData, r *http.Request) (f Fo
|
||||
}
|
||||
|
||||
if f.ReadInput(r) {
|
||||
if err := td.PixelAPI.SubscriptionLink(r.FormValue("key")); err != nil {
|
||||
if err := td.PixelAPI.PostSubscriptionLink(r.FormValue("key")); err != nil {
|
||||
formAPIError(err, &f)
|
||||
} else {
|
||||
// Request was a success
|
||||
|
@@ -14,8 +14,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"fornaxian.tech/pixeldrain_server/api/restapi/apiclient"
|
||||
"fornaxian.tech/pixeldrain_server/api/restapi/apitype"
|
||||
"fornaxian.tech/pixeldrain_api_client/pixelapi"
|
||||
"fornaxian.tech/pixeldrain_server/util"
|
||||
"github.com/Fornaxian/log"
|
||||
)
|
||||
@@ -24,12 +23,12 @@ import (
|
||||
// the field Other you can pass your own template-specific variables.
|
||||
type TemplateData struct {
|
||||
Authenticated bool
|
||||
User apitype.UserInfo
|
||||
User pixelapi.UserInfo
|
||||
UserAgent string
|
||||
Style pixeldrainStyleSheet
|
||||
UserStyle template.CSS
|
||||
APIEndpoint template.URL
|
||||
PixelAPI apiclient.PixelAPI
|
||||
PixelAPI pixelapi.PixelAPI
|
||||
Hostname template.HTML
|
||||
|
||||
// Only used on file viewer page
|
||||
@@ -63,8 +62,7 @@ func (wc *WebController) newTemplateData(w http.ResponseWriter, r *http.Request)
|
||||
// and stuff like that
|
||||
if key, err := wc.getAPIKey(r); err == nil {
|
||||
t.PixelAPI = t.PixelAPI.Login(key) // Use the user's API key for all requests
|
||||
t.User, err = t.PixelAPI.UserInfo()
|
||||
if err != nil {
|
||||
if t.User, err = t.PixelAPI.GetUser(); err != nil {
|
||||
// This session key doesn't work, or the backend is down, user
|
||||
// cannot be authenticated
|
||||
log.Debug("Session check for key '%s' failed: %s", key, err)
|
||||
|
@@ -16,7 +16,7 @@ func (wc *WebController) serveLogout(
|
||||
) {
|
||||
if key, err := wc.getAPIKey(r); err == nil {
|
||||
var api = wc.api.Login(key)
|
||||
if err = api.UserSessionDestroy(key); err != nil {
|
||||
if err = api.DeleteUserSession(key); err != nil {
|
||||
log.Warn("logout failed for session '%s': %s", key, err)
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func (wc *WebController) registerForm(td *TemplateData, r *http.Request) (f Form
|
||||
var err error
|
||||
// This only runs on the first request
|
||||
if wc.captchaSiteKey == "" {
|
||||
capt, err := td.PixelAPI.GetRecaptcha()
|
||||
capt, err := td.PixelAPI.GetMiscRecaptcha()
|
||||
if err != nil {
|
||||
log.Error("Error getting recaptcha key: %s", err)
|
||||
f.SubmitMessages = []template.HTML{
|
||||
@@ -148,10 +148,11 @@ func (wc *WebController) loginForm(td *TemplateData, r *http.Request) (f Form) {
|
||||
}
|
||||
|
||||
if f.ReadInput(r) {
|
||||
if session, err := td.PixelAPI.UserLogin(
|
||||
if session, err := td.PixelAPI.PostUserLogin(
|
||||
f.FieldVal("username"),
|
||||
f.FieldVal("password"),
|
||||
); err != nil {
|
||||
log.Error("Error while logging in: %s", err)
|
||||
formAPIError(err, &f)
|
||||
} else {
|
||||
// Request was a success
|
||||
@@ -172,6 +173,7 @@ func (wc *WebController) loginForm(td *TemplateData, r *http.Request) (f Form) {
|
||||
// content also gets the cookie. We're not trying to track the
|
||||
// user around the web so we use lax
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
Secure: true,
|
||||
}
|
||||
f.Extra.RedirectTo = "/user"
|
||||
}
|
||||
@@ -206,7 +208,7 @@ func (wc *WebController) passwordResetForm(td *TemplateData, r *http.Request) (f
|
||||
}
|
||||
|
||||
if f.ReadInput(r) {
|
||||
if err := td.PixelAPI.UserPasswordReset(
|
||||
if err := td.PixelAPI.PutUserPasswordReset(
|
||||
f.FieldVal("email"),
|
||||
f.FieldVal("recaptcha_response"),
|
||||
); err != nil {
|
||||
@@ -258,7 +260,7 @@ func (wc *WebController) passwordResetConfirmForm(td *TemplateData, r *http.Requ
|
||||
return f
|
||||
}
|
||||
|
||||
if err := td.PixelAPI.UserPasswordResetConfirm(resetKey, f.FieldVal("new_password")); err != nil {
|
||||
if err := td.PixelAPI.PutUserPasswordResetConfirm(resetKey, f.FieldVal("new_password")); err != nil {
|
||||
formAPIError(err, &f)
|
||||
} else {
|
||||
f.SubmitSuccess = true
|
||||
|
@@ -46,7 +46,7 @@ func (wc *WebController) serveUserExportFiles(
|
||||
return
|
||||
}
|
||||
|
||||
files, err := td.PixelAPI.UserFiles()
|
||||
files, err := td.PixelAPI.GetUserFiles()
|
||||
if err != nil {
|
||||
log.Error("Failed to get user files: %s", err)
|
||||
return
|
||||
@@ -84,7 +84,7 @@ func (wc *WebController) serveUserExportLists(
|
||||
return
|
||||
}
|
||||
|
||||
lists, err := td.PixelAPI.UserLists()
|
||||
lists, err := td.PixelAPI.GetUserLists()
|
||||
if err != nil {
|
||||
log.Error("Failed to get user lists: %s", err)
|
||||
return
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"fornaxian.tech/pixeldrain_server/api/restapi/apiclient"
|
||||
"fornaxian.tech/pixeldrain_api_client/pixelapi"
|
||||
"github.com/Fornaxian/log"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func formAPIError(err error, f *Form) {
|
||||
return name
|
||||
}
|
||||
|
||||
if err, ok := err.(apiclient.Error); ok {
|
||||
if err, ok := err.(pixelapi.Error); ok {
|
||||
if err.StatusCode == "multiple_errors" {
|
||||
for _, err := range err.Errors {
|
||||
// Modify the message to make it more user-friendly
|
||||
@@ -116,7 +116,7 @@ func (wc *WebController) passwordForm(td *TemplateData, r *http.Request) (f Form
|
||||
|
||||
// Passwords match, send the request and fill in the response in the
|
||||
// form
|
||||
if err := td.PixelAPI.UserPasswordSet(
|
||||
if err := td.PixelAPI.PutUserPassword(
|
||||
f.FieldVal("old_password"),
|
||||
f.FieldVal("new_password"),
|
||||
); err != nil {
|
||||
@@ -149,7 +149,7 @@ func (wc *WebController) emailForm(td *TemplateData, r *http.Request) (f Form) {
|
||||
}
|
||||
|
||||
if f.ReadInput(r) {
|
||||
if err := td.PixelAPI.UserEmailReset(
|
||||
if err := td.PixelAPI.PutUserEmailReset(
|
||||
f.FieldVal("new_email"),
|
||||
false,
|
||||
); err != nil {
|
||||
@@ -171,7 +171,7 @@ func (wc *WebController) serveEmailConfirm(
|
||||
var err error
|
||||
var status string
|
||||
|
||||
err = wc.api.UserEmailResetConfirm(r.FormValue("key"))
|
||||
err = wc.api.PutUserEmailResetConfirm(r.FormValue("key"))
|
||||
if err != nil && err.Error() == "not_found" {
|
||||
status = "not_found"
|
||||
} else if err != nil {
|
||||
@@ -206,7 +206,7 @@ func (wc *WebController) usernameForm(td *TemplateData, r *http.Request) (f Form
|
||||
}
|
||||
|
||||
if f.ReadInput(r) {
|
||||
if err := td.PixelAPI.UserSetUsername(f.FieldVal("new_username")); err != nil {
|
||||
if err := td.PixelAPI.PutUserUsername(f.FieldVal("new_username")); err != nil {
|
||||
formAPIError(err, &f)
|
||||
} else {
|
||||
// Request was a success
|
||||
|
@@ -12,7 +12,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"fornaxian.tech/pixeldrain_server/api/restapi/apiclient"
|
||||
"fornaxian.tech/pixeldrain_api_client/pixelapi"
|
||||
"github.com/Fornaxian/log"
|
||||
"github.com/google/uuid"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
@@ -42,7 +42,7 @@ type WebController struct {
|
||||
// API client to use for all requests. If the user is authenticated you
|
||||
// should call Login() on this object. Calling Login will create a copy and
|
||||
// not alter the original PixelAPI, but it will use the same HTTP Transport
|
||||
api apiclient.PixelAPI
|
||||
api pixelapi.PixelAPI
|
||||
}
|
||||
|
||||
// New initializes a new WebController by registering all the request handlers
|
||||
@@ -68,7 +68,7 @@ func New(
|
||||
sessionCookieDomain: sessionCookieDomain,
|
||||
proxyAPIRequests: proxyAPIRequests,
|
||||
httpClient: &http.Client{Timeout: time.Minute * 10},
|
||||
api: apiclient.New(apiURLInternal),
|
||||
api: pixelapi.New(apiURLInternal),
|
||||
}
|
||||
wc.templates = NewTemplateManager(resourceDir, apiURLExternal, debugMode)
|
||||
wc.templates.ParseTemplates(false)
|
||||
@@ -379,7 +379,7 @@ func (wc *WebController) getAPIKey(r *http.Request) (key string, err error) {
|
||||
func (wc *WebController) captchaKey() string {
|
||||
// This only runs on the first request
|
||||
if wc.captchaSiteKey == "" {
|
||||
capt, err := wc.api.GetRecaptcha()
|
||||
capt, err := wc.api.GetMiscRecaptcha()
|
||||
if err != nil {
|
||||
log.Error("Error getting recaptcha key: %s", err)
|
||||
return ""
|
||||
|
Reference in New Issue
Block a user