From 2fba11269aa79c348a75a90a92b40c75ca6b1943 Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Wed, 5 Feb 2020 11:21:46 +0100 Subject: [PATCH 01/10] switch to sky.pixeldrain.com --- res/include/script/file_viewer/Viewer.js | 4 ++-- webcontroller/file_viewer.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/include/script/file_viewer/Viewer.js b/res/include/script/file_viewer/Viewer.js index 49f8e34..06a2c06 100644 --- a/res/include/script/file_viewer/Viewer.js +++ b/res/include/script/file_viewer/Viewer.js @@ -243,8 +243,8 @@ function fileFromAPIResp(resp) { function fileFromSkyNet(resp) { let file = fileFromAPIResp(resp) file.icon_href = "/res/img/mime/empty.png" - file.get_href = "https://siasky.net/"+resp.id - file.download_href = "https://siasky.net/"+resp.id+"?attachment=1" + file.get_href = "https://sky.pixeldrain.com/"+resp.id + file.download_href = "https://sky.pixeldrain.com/"+resp.id+"?attachment=1" file.availability_href = "" file.view_href = "" file.timeseries_href = "" diff --git a/webcontroller/file_viewer.go b/webcontroller/file_viewer.go index 4809415..cb0e448 100644 --- a/webcontroller/file_viewer.go +++ b/webcontroller/file_viewer.go @@ -165,7 +165,7 @@ func (wc *WebController) serveSkynetViewer(w http.ResponseWriter, r *http.Reques // Get the first few bytes from the file to probe the content type and // length - rq, err := http.NewRequest("GET", "https://siasky.net/"+p.ByName("id"), nil) + rq, err := http.NewRequest("GET", "https://sky.pixeldrain.com/"+p.ByName("id"), nil) if err != nil { log.Warn("Failed to make request to sia portal: %s", err) w.WriteHeader(http.StatusInternalServerError) From 650c7ede6c6e79bed8192efcdd5b85d4e3b2e140 Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Wed, 5 Feb 2020 11:35:31 +0100 Subject: [PATCH 02/10] update auth cookie settings --- pixelapi/pixelapi.go | 18 +++++++++--------- pixelapi/user.go | 2 +- webcontroller/templates.go | 5 ++++- webcontroller/user_account.go | 12 +++++++----- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/pixelapi/pixelapi.go b/pixelapi/pixelapi.go index 78ca2f6..a0522fe 100644 --- a/pixelapi/pixelapi.go +++ b/pixelapi/pixelapi.go @@ -17,7 +17,7 @@ var client = &http.Client{Timeout: time.Minute * 5} // PixelAPI is the Pixeldrain API client type PixelAPI struct { apiEndpoint string - apiKey string + APIKey string RealIP string } @@ -60,8 +60,8 @@ func (p *PixelAPI) jsonRequest(method, url string, target interface{}) error { Message: err.Error(), } } - if p.apiKey != "" { - req.SetBasicAuth("", p.apiKey) + if p.APIKey != "" { + req.SetBasicAuth("", p.APIKey) } if p.RealIP != "" { req.Header.Set("X-Real-IP", p.RealIP) @@ -86,8 +86,8 @@ func (p *PixelAPI) getString(url string) (string, error) { if err != nil { return "", err } - if p.apiKey != "" { - req.SetBasicAuth("", p.apiKey) + if p.APIKey != "" { + req.SetBasicAuth("", p.APIKey) } if p.RealIP != "" { req.Header.Set("X-Real-IP", p.RealIP) @@ -110,8 +110,8 @@ func (p *PixelAPI) getRaw(url string) (io.ReadCloser, error) { if err != nil { return nil, err } - if p.apiKey != "" { - req.SetBasicAuth("", p.apiKey) + if p.APIKey != "" { + req.SetBasicAuth("", p.APIKey) } if p.RealIP != "" { req.Header.Set("X-Real-IP", p.RealIP) @@ -141,8 +141,8 @@ func (p *PixelAPI) form( Message: err.Error(), } } - if p.apiKey != "" { - req.SetBasicAuth("", p.apiKey) + if p.APIKey != "" { + req.SetBasicAuth("", p.APIKey) } if p.RealIP != "" { req.Header.Set("X-Real-IP", p.RealIP) diff --git a/pixelapi/user.go b/pixelapi/user.go index 0d63bcd..24b7da7 100644 --- a/pixelapi/user.go +++ b/pixelapi/user.go @@ -58,7 +58,7 @@ func (p *PixelAPI) UserLogin(username, password string, saveKey bool) (resp *Log return nil, err } if saveKey { - p.apiKey = resp.APIKey + p.APIKey = resp.APIKey } return resp, nil } diff --git a/webcontroller/templates.go b/webcontroller/templates.go index 9e8cc46..f728f24 100644 --- a/webcontroller/templates.go +++ b/webcontroller/templates.go @@ -64,7 +64,10 @@ func (wc *WebController) newTemplateData(w http.ResponseWriter, r *http.Request) log.Debug("Session check for key '%s' failed: %s", key, err) if err.Error() == "authentication_required" || err.Error() == "authentication_failed" { - // This key is invalid, delete it + // Disable API authentication + t.PixelAPI.APIKey = "" + + // Remove the authentication cookie log.Debug("Deleting invalid API key") http.SetCookie(w, &http.Cookie{ Name: "pd_auth_key", diff --git a/webcontroller/user_account.go b/webcontroller/user_account.go index 5b2b5bf..8fac6e1 100644 --- a/webcontroller/user_account.go +++ b/webcontroller/user_account.go @@ -173,11 +173,13 @@ func (wc *WebController) loginForm(td *TemplateData, r *http.Request) (f Form) { f.SubmitSuccess = true f.SubmitMessages = []template.HTML{"Success!"} f.Extra.SetCookie = &http.Cookie{ - Name: "pd_auth_key", - Value: loginResp.APIKey, - Path: "/", - Expires: time.Now().AddDate(50, 0, 0), - Domain: wc.sessionCookieDomain, + Name: "pd_auth_key", + Value: loginResp.APIKey, + Path: "/", + Expires: time.Now().AddDate(50, 0, 0), + Domain: wc.sessionCookieDomain, + SameSite: http.SameSiteStrictMode, + Secure: true, } f.Extra.RedirectTo = "/user" } From ea6d8bf6c88de083fbdbe37a25a59e796acfc8a5 Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Wed, 5 Feb 2020 11:56:08 +0100 Subject: [PATCH 03/10] update cookie settings --- webcontroller/templates.go | 7 +++++++ webcontroller/user_account.go | 2 ++ webcontroller/web_controller.go | 1 + 3 files changed, 10 insertions(+) diff --git a/webcontroller/templates.go b/webcontroller/templates.go index f728f24..e5c3c17 100644 --- a/webcontroller/templates.go +++ b/webcontroller/templates.go @@ -76,6 +76,13 @@ func (wc *WebController) newTemplateData(w http.ResponseWriter, r *http.Request) Expires: time.Unix(0, 0), Domain: wc.sessionCookieDomain, }) + http.SetCookie(w, &http.Cookie{ + Name: "pd_auth_key", + Value: "", + Path: "/", + Expires: time.Unix(0, 0), + Domain: ".pixeldrain.com", + }) } return t } diff --git a/webcontroller/user_account.go b/webcontroller/user_account.go index 8fac6e1..dc9e6b6 100644 --- a/webcontroller/user_account.go +++ b/webcontroller/user_account.go @@ -172,6 +172,8 @@ func (wc *WebController) loginForm(td *TemplateData, r *http.Request) (f Form) { // Request was a success f.SubmitSuccess = true f.SubmitMessages = []template.HTML{"Success!"} + + // Set the autentication cookie f.Extra.SetCookie = &http.Cookie{ Name: "pd_auth_key", Value: loginResp.APIKey, diff --git a/webcontroller/web_controller.go b/webcontroller/web_controller.go index a7dcc72..87711e7 100644 --- a/webcontroller/web_controller.go +++ b/webcontroller/web_controller.go @@ -183,6 +183,7 @@ func (wc *WebController) serveForm( // Execute the extra actions if any if td.Form.Extra.SetCookie != nil { + w.Header().Del("Set-Cookie") http.SetCookie(w, td.Form.Extra.SetCookie) } if td.Form.Extra.RedirectTo != "" { From 2788c9ba4826a157482baddae801ddc84c013c31 Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Wed, 5 Feb 2020 16:45:31 +0100 Subject: [PATCH 04/10] fix rendering graph --- res/include/script/file_viewer/DetailsWindow.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/include/script/file_viewer/DetailsWindow.js b/res/include/script/file_viewer/DetailsWindow.js index 66325e2..fd1b553 100644 --- a/res/include/script/file_viewer/DetailsWindow.js +++ b/res/include/script/file_viewer/DetailsWindow.js @@ -32,7 +32,7 @@ DetailsWindow.prototype.toggle = function() { if (this.graph === 0) { this.renderGraph() } - this.updateGraph(this.fileID) + this.updateGraph(this.file) } } From dd1ccfea11448d05e7dd9e4ad0273be911a42ea1 Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Wed, 5 Feb 2020 16:52:55 +0100 Subject: [PATCH 05/10] fix graphs again --- res/include/script/file_viewer/DetailsWindow.js | 6 +++--- res/include/script/file_viewer/Viewer.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/res/include/script/file_viewer/DetailsWindow.js b/res/include/script/file_viewer/DetailsWindow.js index fd1b553..a7401fb 100644 --- a/res/include/script/file_viewer/DetailsWindow.js +++ b/res/include/script/file_viewer/DetailsWindow.js @@ -1,7 +1,7 @@ function DetailsWindow(viewer) { this.viewer = viewer this.visible = false - this.fileID = "" + this.file = null this.graph = 0 this.divPopup = document.getElementById("details_popup") @@ -36,12 +36,12 @@ DetailsWindow.prototype.toggle = function() { } } -DetailsWindow.prototype.setDetails = function(file) { +DetailsWindow.prototype.setFile = function(file) { + this.file = file let desc = "" if (this.viewer.isList) { desc = file.description } - this.fileID = file.id this.divFileDetails.innerHTML = "" + "" + "" diff --git a/res/include/script/file_viewer/Viewer.js b/res/include/script/file_viewer/Viewer.js index 06a2c06..fdf28a9 100644 --- a/res/include/script/file_viewer/Viewer.js +++ b/res/include/script/file_viewer/Viewer.js @@ -74,8 +74,8 @@ Viewer.prototype.setFile = function(file) { document.title = file.name + " ~ pixeldrain" } - // Update the file details - this.detailsWindow.setDetails(file) + // Relay the file change event to all components + this.detailsWindow.setFile(file) this.toolbar.setFile(file) // Register a new view. We don't care what this returns becasue we can't From ecab08b5aeb6fab60f4866cacba1fa22f7b2820a Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Wed, 5 Feb 2020 17:24:40 +0100 Subject: [PATCH 06/10] remove ad --- res/include/script/file_viewer/Viewer.js | 66 ++++++++++++------------ res/template/file_viewer.html | 9 ---- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/res/include/script/file_viewer/Viewer.js b/res/include/script/file_viewer/Viewer.js index fdf28a9..eeae310 100644 --- a/res/include/script/file_viewer/Viewer.js +++ b/res/include/script/file_viewer/Viewer.js @@ -54,8 +54,8 @@ function Viewer(type, viewToken, data) { this.setFile(fileFromSkyNet(data)) } - this.renderSponsors() - window.addEventListener("resize", e => { this.renderSponsors(e) }) + // this.renderSponsors() + // window.addEventListener("resize", e => { this.renderSponsors(e) }) // Register keyboard shortcuts document.addEventListener("keydown", e => { this.keyboardEvent(e) }) @@ -129,40 +129,40 @@ Viewer.prototype.setFile = function(file) { } } -Viewer.prototype.renderSponsors = function() { - let scale = 1 - let scaleWidth = 1 - let scaleHeight = 1 - let minWidth = 728 - let minHeight = 800 +// Viewer.prototype.renderSponsors = function() { +// let scale = 1 +// let scaleWidth = 1 +// let scaleHeight = 1 +// let minWidth = 728 +// let minHeight = 800 - if (window.innerWidth < minWidth) { - scaleWidth = window.innerWidth/minWidth - } - if (window.innerHeight < minHeight) { - scaleHeight = window.innerHeight/minHeight - } - scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight +// if (window.innerWidth < minWidth) { +// scaleWidth = window.innerWidth/minWidth +// } +// if (window.innerHeight < minHeight) { +// scaleHeight = window.innerHeight/minHeight +// } +// scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight - // Because of the scale transformation the automatic margins don't work - // anymore. So we have to maunally calculate the margin. Where we take the - // width of the viewport - the width of the ad to calculate the amount of - // pixels around the ad. We multiply the ad size by the scale we calcualted - // to account for the smaller size. - let offset = (window.innerWidth - (minWidth*scale)) / 2 - if (offset < 0) { - offset = 0 - } - document.querySelector(".sponsors > iframe").style.marginLeft = offset+"px" +// // Because of the scale transformation the automatic margins don't work +// // anymore. So we have to maunally calculate the margin. Where we take the +// // width of the viewport - the width of the ad to calculate the amount of +// // pixels around the ad. We multiply the ad size by the scale we calcualted +// // to account for the smaller size. +// let offset = (window.innerWidth - (minWidth*scale)) / 2 +// if (offset < 0) { +// offset = 0 +// } +// document.querySelector(".sponsors > iframe").style.marginLeft = offset+"px" - if (scale == 1) { - document.querySelector(".sponsors > iframe").style.transform = "none" - document.querySelector(".sponsors").style.height = "90px" - } else { - document.querySelector(".sponsors > iframe").style.transform = "scale("+scale+")" - document.querySelector(".sponsors").style.height = (scale*90)+"px" - } -} +// if (scale == 1) { +// document.querySelector(".sponsors > iframe").style.transform = "none" +// document.querySelector(".sponsors").style.height = "90px" +// } else { +// document.querySelector(".sponsors > iframe").style.transform = "scale("+scale+")" +// document.querySelector(".sponsors").style.height = (scale*90)+"px" +// } +// } Viewer.prototype.keyboardEvent = function(evt) { if (evt.ctrlKey || evt.altKey) { diff --git a/res/template/file_viewer.html b/res/template/file_viewer.html index e7245d9..c5ce726 100644 --- a/res/template/file_viewer.html +++ b/res/template/file_viewer.html @@ -95,15 +95,6 @@
{{template "spinner.svg" .}}
-
- - -
Name" + escapeHTML(file.name) + "
URL"+file.link+"
@@ -118,7 +133,31 @@

Returns

- A file output stream. +
HTTP 200: OK
+The requested file.
+		
+ +
HTTP 404: Not Found
+{
+	"success": false,
+	"value": "not_found",
+	"message": "The entity you requested could not be found"
+}
+
+
HTTP 403: Forbidden
+{
+	"success": false,
+	"value": "file_rate_limited_captcha_required",
+	"message": "This file is using too much bandwidth. For anonymous downloads a captcha is required now. The captcha entry is available on the download page"
+}
+		
+
HTTP 403: Forbidden
+{
+	"success": false,
+	"value": "virus_detected_captcha_required",
+	"message": "This file has been marked as malware by our scanning systems. To avoid infecting other systems through automated downloads we require you to enter a captcha. The captcha entry is available on the download page"
+}
+		
{{end}} @@ -152,17 +191,15 @@
HTTP 200: OK
 {
 	"success": true,
-	"id": "123abc",
+	"id": "1234abcd",
 	"name": "screenshot.png",
-	"date_upload": 1485894987, // Timestamp
-	"date_last_view": 1485894987, // Timestamp
+	"date_upload": 2020-02-04T18:34:05.706801Z,
+	"date_last_view": 2020-02-04T18:34:05.706801Z,
 	"size": 5694837, // Bytes
 	"views" 1234, // Amount of unique file views
 	"bandwidth_used": 1234567890, // Bytes
 	"mime_type" "image/png",
-	"description": "File description",
-	"mime_image": "http://pixeldra.in/res/img/mime/image-png.png", // Image associated with the mime type
-	"thumbnail": "http://pixeldra.in/api/thumbnail/123abc" // Link to a thumbnail of this file
+	"thumbnail_href": "/file/1234abcd/thumbnail" // Link to a thumbnail of this file
 }
HTTP 404: Not Found
 {

From db63e20cfdf877454031c0860d02731126d9249b Mon Sep 17 00:00:00 2001
From: Wim Brand 
Date: Fri, 7 Feb 2020 10:25:46 +0100
Subject: [PATCH 08/10] fix availability url

---
 res/include/script/file_viewer/Toolbar.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/res/include/script/file_viewer/Toolbar.js b/res/include/script/file_viewer/Toolbar.js
index ce0cfc6..c9d00a1 100644
--- a/res/include/script/file_viewer/Toolbar.js
+++ b/res/include/script/file_viewer/Toolbar.js
@@ -93,7 +93,7 @@ Toolbar.prototype.download = function() {
 		return
 	}
 
-	fetch(this.currentFile.file_availability_href).then(resp => {
+	fetch(this.currentFile.availability_href).then(resp => {
 		return resp.json()
 	}).then(resp => {
 		let popupDiv = document.getElementById("captcha_popup")

From 4374981ab44de1e3dfe4bd41429054ecd1bfe02f Mon Sep 17 00:00:00 2001
From: Wim Brand 
Date: Fri, 7 Feb 2020 10:32:14 +0100
Subject: [PATCH 09/10] update list API doc

---
 res/template/fragments/api/list.html | 39 ++++++++++++++++++----------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/res/template/fragments/api/list.html b/res/template/fragments/api/list.html
index ef79f3a..bdd040b 100644
--- a/res/template/fragments/api/list.html
+++ b/res/template/fragments/api/list.html
@@ -121,37 +121,50 @@
 	"success": true,
 	"id": "L8bhwx",
 	"title": "Rust in Peace",
-	"date_created": 1513033315,
+	"date_created": 2020-02-04T18:34:13.466276Z,
 	"files": [
+		// These structures are the same as the file info response, except for the detail_href and description fields
 		{
 			"detail_href": "/file/_SqVWi/info",
+			"description": "",
+			"success": true,
 			"id": "_SqVWi",
 			"name": "01 Holy Wars... The Punishment Due.mp3",
-			"description": "",
-			"date_created": 1513033304,
-			"date_last_view": 1513033304,
+			"size": 123456,
+			"date_created": 2020-02-04T18:34:13.466276Z,
+			"date_last_view": 2020-02-04T18:34:13.466276Z,
+			"mime_type": "audio/mp3",
 			"views": 1,
-			"bandwidth_used": 1234567890
+			"bandwidth_used": 1234567890,
+			"thumbnail_href": "/file/_SqVWi/thumbnail"
 		},
 		{
 			"detail_href": "/file/RKwgZb/info",
+			"description": "",
+			"success": true,
 			"id": "RKwgZb",
 			"name": "02 Hangar 18.mp3",
-			"description": "",
-			"date_created": 1513033304,
-			"date_last_view": 1513033304,
+			"size": 123456,
+			"date_created": 2020-02-04T18:34:13.466276Z,
+			"date_last_view": 2020-02-04T18:34:13.466276Z,
+			"mime_type": "audio/mp3",
 			"views": 2,
-			"bandwidth_used": 1234567890
+			"bandwidth_used": 1234567890,
+			"thumbnail_href": "/file/RKwgZb/thumbnail"
 		},
 		{
 			"detail_href": "/file/DRaL_e/info",
+			"description": "",
+			"success": true,
 			"id": "DRaL_e",
 			"name": "03 Take No Prisoners.mp3",
-			"description": "",
-			"date_created": 1513033304,
-			"date_last_view": 1513033304,
+			"size": 123456,
+			"date_created": 2020-02-04T18:34:13.466276Z,
+			"date_last_view": 2020-02-04T18:34:13.466276Z,
+			"mime_type": "audio/mp3",
 			"views": 3,
-			"bandwidth_used": 1234567890
+			"bandwidth_used": 1234567890,
+			"thumbnail_href": "/file/DRaL_e/thumbnail"
 		}
 	]
 }

From a2ec388e8d0114ba49f291da5c407212d1849d8e Mon Sep 17 00:00:00 2001
From: Wim Brand 
Date: Fri, 7 Feb 2020 16:21:43 +0100
Subject: [PATCH 10/10] fix scroll thumb size

---
 res/include/style/layout.css | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/res/include/style/layout.css b/res/include/style/layout.css
index 2299abc..daa0112 100644
--- a/res/include/style/layout.css
+++ b/res/include/style/layout.css
@@ -488,6 +488,8 @@ input[type=file]{
 	background-color: var(--scrollbar_foreground_color);
 	border-radius: 10px;
 	border: 5px solid var(--scrollbar_background_color);
+	height: 40px;
+	width: 40px;
 }
 ::-webkit-scrollbar-thumb:hover {
 	background-color: var(--scrollbar_hover_color);