Merge branch 'master' into easy-forms
This commit is contained in:
@@ -24,6 +24,7 @@ type FileInfo struct {
|
||||
MimeType string `json:"mime_type"`
|
||||
MimeImage string `json:"mime_image"`
|
||||
ThumbnailHREF string `json:"thumbnail_href"`
|
||||
Availability string `json:"availability"`
|
||||
}
|
||||
|
||||
// GetFileInfo gets the FileInfo from the pixeldrain API
|
||||
|
@@ -30,7 +30,56 @@ var Toolbar = {
|
||||
}
|
||||
},
|
||||
download: function () {
|
||||
document.getElementById("download_frame").src = "/api/file/" + Viewer.currentFile + "?download";
|
||||
var triggerDL = function(){
|
||||
document.getElementById("download_frame").src = "/api/file/" + Viewer.currentFile + "?download";
|
||||
}
|
||||
|
||||
if (captchaKey === "a"){
|
||||
// If the server doesn't support captcha there's no use in checking
|
||||
// availability
|
||||
triggerDL();
|
||||
return;
|
||||
}
|
||||
|
||||
$.getJSON(
|
||||
apiEndpoint + "/file/" + Viewer.currentFile + "/availability"
|
||||
).done(function(data){
|
||||
if(data.success === true){
|
||||
// Downloading is allowed, start the download
|
||||
triggerDL();
|
||||
}
|
||||
}).fail(function(data){
|
||||
if(data.responseJSON.success === false) {
|
||||
var popupDiv = document.getElementById("captcha_popup");
|
||||
var popupTitle = document.getElementById("captcha_popup_title");
|
||||
var popupContent = document.getElementById("captcha_popup_content");
|
||||
var popupCaptcha = document.getElementById("captcha_popup_captcha");
|
||||
|
||||
if(data.responseJSON.value === "file_rate_limited_captcha_required") {
|
||||
popupTitle.innerText = "Rate limiting enabled!";
|
||||
popupContent.innerText = "This file is using a suspicious "+
|
||||
"amount of bandwidth relative to its popularity. To "+
|
||||
"continue downloading this file you will have to "+
|
||||
"prove that you're a human first.";
|
||||
}else if(data.responseJSON.value === "virus_detected_captcha_required"){
|
||||
popupTitle.innerText = "Malware warning!";
|
||||
popupContent.innerText = "According to our scanning "+
|
||||
"systems this file may contain a virus of type '"+
|
||||
data.responseJSON.extra+"'. You can continue "+
|
||||
"downloading this file at your own risk, but you will "+
|
||||
"have to prove that you're a human first.";
|
||||
}
|
||||
|
||||
// Load the recaptcha script with a load function
|
||||
$.getScript("https://www.google.com/recaptcha/api.js?onload=loadCaptcha&render=explicit");
|
||||
|
||||
popupDiv.style.opacity = "1";
|
||||
popupDiv.style.visibility = "visible";
|
||||
}else{
|
||||
// No JSON, try download anyway
|
||||
triggerDL();
|
||||
}
|
||||
});
|
||||
},
|
||||
downloadList: function(){
|
||||
if(!Viewer.isList){
|
||||
@@ -97,6 +146,23 @@ function copyText(text) {
|
||||
return success;
|
||||
}
|
||||
|
||||
function loadCaptcha(){
|
||||
grecaptcha.render("captcha_popup_captcha", {
|
||||
sitekey: captchaKey,
|
||||
theme: "dark",
|
||||
callback: function(token){
|
||||
document.getElementById("download_frame").src = "/api/file/" + Viewer.currentFile +
|
||||
"?download&recaptcha_response="+token;
|
||||
|
||||
setTimeout(function(){
|
||||
var popupDiv = document.getElementById("captcha_popup");
|
||||
popupDiv.style.opacity = "0";
|
||||
popupDiv.style.visibility = "hidden";
|
||||
}, 1000)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var DetailsWindow = {
|
||||
visible: false,
|
||||
popupDiv: document.getElementById("info_popup"),
|
||||
|
@@ -103,12 +103,13 @@ body{
|
||||
font-family: "Lato Thin", sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 1.8em;
|
||||
transition: box-shadow 0.5s;
|
||||
transition: box-shadow 2s;
|
||||
}
|
||||
.navigation a:hover {
|
||||
background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));
|
||||
box-shadow: var(--highlight_border), 2px 2px 8px var(--shadow_color);
|
||||
color: var(--highlight_text_color);
|
||||
transition: box-shadow 0.5s;
|
||||
text-decoration: none;
|
||||
}
|
||||
.navigation .icon {
|
||||
|
@@ -190,7 +190,6 @@ body{
|
||||
/* =====================
|
||||
|| MISC COMPONENTS ||
|
||||
===================== */
|
||||
|
||||
.full_popup{
|
||||
position: fixed;
|
||||
visibility: hidden;
|
||||
@@ -208,6 +207,28 @@ body{
|
||||
box-shadow: var(--shadow_color) 0px 0px 50px;
|
||||
z-index: 100;
|
||||
}
|
||||
.captcha_popup{
|
||||
position: fixed;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: visibility 1s, opacity 1s, left 1s;
|
||||
background-color: var(--background_color);
|
||||
border-color: var(--accent_color_dark_border);
|
||||
height: auto;
|
||||
width: 450px;
|
||||
max-width: 100%;
|
||||
top: 10%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -10%);
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
text-align: left;
|
||||
box-shadow: var(--shadow_color) 0px 0px 50px;
|
||||
z-index: 101;
|
||||
}
|
||||
#captcha_popup_captcha > div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
table {width: auto !important;}
|
||||
table > tbody > tr {border: none !important;}
|
||||
|
@@ -29,7 +29,10 @@
|
||||
<meta property="article:author" content="Fornax96" />
|
||||
<link rel="image_src" href="{{.OGData.Image}}" />
|
||||
|
||||
<script type="text/javascript">var apiEndpoint = '{{.APIEndpoint}}';</script>
|
||||
<script type="text/javascript">
|
||||
var apiEndpoint = '{{.APIEndpoint}}';
|
||||
var captchaKey = '{{.Other.CaptchaKey}}';
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -163,6 +166,12 @@
|
||||
<br/>
|
||||
</span>
|
||||
</div>
|
||||
<div id="captcha_popup" class="captcha_popup border_bottom">
|
||||
<div id="captcha_popup_title" class="highlight_light border_top border_bottom"></div>
|
||||
<div id="captcha_popup_content"></div>
|
||||
<br/>
|
||||
<div id="captcha_popup_captcha" style="text-align: center;"></div>
|
||||
</div>
|
||||
|
||||
<div id="filepreview">
|
||||
<img src="/res/img/misc/loadthink.gif" style="margin-top: 20%; width: 200px; height: 200px;" />
|
||||
|
@@ -61,24 +61,36 @@
|
||||
nobody will see it.
|
||||
</p>
|
||||
|
||||
<h3>What cookies does pixeldrain use?</h3>
|
||||
<h3>Does pixeldrain cost any money?</h3>
|
||||
<p>
|
||||
When uploading a file pixeldrain will install a cookie named
|
||||
'pduploads'. This cookie keeps a dot-separated list of all files
|
||||
you have uploaded anonymously in this browser. This cookie is
|
||||
<b>only</b> used for viewing your upload history.
|
||||
</p>
|
||||
<p>
|
||||
When logging in to a pixeldrain account a cookie named
|
||||
'pd_auth_key' will be installed. This cookie keeps your login
|
||||
session active. When you delete it you will be logged out of
|
||||
your account.
|
||||
</p>
|
||||
<p>
|
||||
When you use the style selector at the bottom of this page a
|
||||
cookie called 'style' will be set. This cookie controls the
|
||||
appearance of the website for you.
|
||||
No, pixeldrain is completely free at the moment. While there is
|
||||
an advertisement on the file downloading page, it doesn't
|
||||
generate nearly enough revenue to pay for maintaining this
|
||||
service. That's why I'd really appreciate it if you could spare
|
||||
some coins. Possible methods for donating are:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Bitcoin: <a href="bitcoin:1Ne7hGuvnfz9EFTRD3PLWVeaJTX9oA1QUr?label=Pixeldrain%20Donation">1Ne7hGuvnfz9EFTRD3PLWVeaJTX9oA1QUr</a></li>
|
||||
<li>
|
||||
BasicAttentionToken: Donate BAT by clicking the BAT icon in
|
||||
your address bar. If you don't have Brave browser yet you
|
||||
can download it here:
|
||||
<a class="button button_highlight" href="https://brave.com/pix009" target="_blank">Install Brave</a>.
|
||||
Installing and using Brave with this referral link also
|
||||
counts as a 5$ donation.
|
||||
</li>
|
||||
<li>
|
||||
Siacoin:
|
||||
26117c19ca3975b315d663dcbbc19cf9c07274f441689d4392ed380b2337589ef1aacfbdc93f
|
||||
(this address points directly at the storage backend.
|
||||
Donations will be used for paying storage contracts with Sia
|
||||
hosts)
|
||||
</li>
|
||||
<li>
|
||||
PayPal:
|
||||
<a class="button button_highlight" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WU49A5NHPAZ9G&source=url">Donate with PayPal</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Do I need to register an account?</h3>
|
||||
<p>
|
||||
@@ -97,25 +109,24 @@
|
||||
page</a>.
|
||||
</p>
|
||||
|
||||
<h3>Does pixeldrain cost any money?</h3>
|
||||
<h3>What cookies does pixeldrain use?</h3>
|
||||
<p>
|
||||
No, pixeldrain is completely free at the moment. While there is
|
||||
an advertisement on the file downloading page, it doesn't
|
||||
generate nearly enough revenue to pay for maintaining this
|
||||
service. That's why I'd really appreciate it if you could spare
|
||||
some coins. Possible methods for donating are:
|
||||
When uploading a file pixeldrain will install a cookie named
|
||||
'pduploads'. This cookie keeps a dot-separated list of all files
|
||||
you have uploaded anonymously in this browser. This cookie is
|
||||
<b>only</b> used for viewing your upload history.
|
||||
</p>
|
||||
<p>
|
||||
When logging in to a pixeldrain account a cookie named
|
||||
'pd_auth_key' will be installed. This cookie keeps your login
|
||||
session active. When you delete it you will be logged out of
|
||||
your account.
|
||||
</p>
|
||||
<p>
|
||||
When you use the style selector at the bottom of this page a
|
||||
cookie called 'style' will be set. This cookie controls the
|
||||
appearance of the website for you.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Bitcoin: <a href="bitcoin:1Ne7hGuvnfz9EFTRD3PLWVeaJTX9oA1QUr?label=Pixeldrain%20Donation">1Ne7hGuvnfz9EFTRD3PLWVeaJTX9oA1QUr</a></li>
|
||||
<li>
|
||||
Siacoin:
|
||||
26117c19ca3975b315d663dcbbc19cf9c07274f441689d4392ed380b2337589ef1aacfbdc93f
|
||||
(this address points directly at the storage backend.
|
||||
Donations will be used for paying storage contracts with Sia
|
||||
hosts)
|
||||
</li>
|
||||
<li><a class="button button_highlight" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WU49A5NHPAZ9G&source=url">Donate with PayPal</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Legality</h2>
|
||||
<p>
|
||||
@@ -139,6 +150,7 @@
|
||||
<input type="radio" id="style_default" name="style"><label for="style_default">Default Pixeldrain Style</label><br/>
|
||||
<input type="radio" id="style_solarized_dark" name="style"><label for="style_solarized_dark">Solarized Dark Style</label><br/>
|
||||
<input type="radio" id="style_maroon" name="style"><label for="style_maroon">Maroon Style</label><br/>
|
||||
<input type="radio" id="style_hacker" name="style"><label for="style_hacker">Hacker Style</label><br/>
|
||||
|
||||
{{template "footer"}}
|
||||
</div>
|
||||
|
@@ -187,11 +187,10 @@ seamless="seamless" frameborder="0" allowtransparency="true"
|
||||
|
||||
func (f filePreview) def() string {
|
||||
return fmt.Sprintf(
|
||||
`%s<br/>%s<br/><a href="%s"><img src="%s" class="image"></a>`,
|
||||
`<br/><br/><img src="%s" class="image"><br/><br/>%s<br/>Type: '%s'`,
|
||||
f.APIURL+f.FileInfo.ThumbnailHREF,
|
||||
f.FileInfo.Name,
|
||||
f.FileInfo.MimeType,
|
||||
f.DownloadURL,
|
||||
f.APIURL+f.FileInfo.ThumbnailHREF,
|
||||
)
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
type viewerData struct {
|
||||
Type string // file or list
|
||||
CaptchaKey string
|
||||
APIResponse interface{}
|
||||
}
|
||||
|
||||
@@ -52,7 +53,8 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
if list {
|
||||
templateData.Title = fmt.Sprintf("%d files in Pixeldrain", len(finfo))
|
||||
templateData.Other = viewerData{
|
||||
Type: "list",
|
||||
Type: "list",
|
||||
CaptchaKey: wc.captchaKey(),
|
||||
APIResponse: map[string]interface{}{
|
||||
"data": finfo,
|
||||
"date_created": "now",
|
||||
@@ -65,6 +67,7 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
templateData.Title = fmt.Sprintf("%s ~ Pixeldrain file", finfo[0].Name)
|
||||
templateData.Other = viewerData{
|
||||
Type: "file",
|
||||
CaptchaKey: wc.captchaKey(),
|
||||
APIResponse: finfo[0],
|
||||
}
|
||||
}
|
||||
@@ -80,7 +83,8 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
func (wc *WebController) serveFileViewerDemo(w http.ResponseWriter, r *http.Request) {
|
||||
templateData := wc.newTemplateData(w, r)
|
||||
templateData.Other = viewerData{
|
||||
Type: "file",
|
||||
Type: "file",
|
||||
CaptchaKey: wc.captchaSiteKey,
|
||||
APIResponse: map[string]interface{}{
|
||||
"id": "demo",
|
||||
"name": "Demo file",
|
||||
|
@@ -26,7 +26,8 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request,
|
||||
templateData.Title = fmt.Sprintf("%s ~ Pixeldrain list", list.Title)
|
||||
templateData.OGData = OpenGraphFromList(*list)
|
||||
templateData.Other = viewerData{
|
||||
Type: "list",
|
||||
Type: "list",
|
||||
CaptchaKey: wc.captchaSiteKey,
|
||||
APIResponse: map[string]interface{}{
|
||||
"id": list.ID,
|
||||
"data": list.Files,
|
||||
|
@@ -44,14 +44,20 @@ func (wc *WebController) newTemplateData(w http.ResponseWriter, r *http.Request)
|
||||
t.PixelAPI = pixelapi.New(wc.conf.APIURLInternal, key)
|
||||
uinf, err := t.PixelAPI.UserInfo()
|
||||
if err != nil {
|
||||
// This session key doesn't work, delete it
|
||||
// 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)
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "pd_auth_key",
|
||||
Value: "",
|
||||
Path: "/",
|
||||
Expires: time.Unix(0, 0),
|
||||
})
|
||||
|
||||
if err.Error() == "authentication_required" || err.Error() == "authentication_failed" {
|
||||
// This key is invalid, delete it
|
||||
log.Debug("Deleting invalid API key")
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "pd_auth_key",
|
||||
Value: "",
|
||||
Path: "/",
|
||||
Expires: time.Unix(0, 0),
|
||||
})
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
|
@@ -16,23 +16,7 @@ func (wc *WebController) serveRegister(
|
||||
p httprouter.Params,
|
||||
) {
|
||||
var tpld = wc.newTemplateData(w, r)
|
||||
|
||||
// This only runs on the first request
|
||||
if wc.captchaSiteKey == "" {
|
||||
capt, err := tpld.PixelAPI.GetRecaptcha()
|
||||
if err != nil {
|
||||
log.Error("Error getting recaptcha key: %s", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if capt.SiteKey == "" {
|
||||
wc.captchaSiteKey = "none"
|
||||
} else {
|
||||
wc.captchaSiteKey = capt.SiteKey
|
||||
}
|
||||
}
|
||||
|
||||
tpld.Other = wc.captchaSiteKey
|
||||
tpld.Other = wc.captchaKey()
|
||||
|
||||
err := wc.templates.Get().ExecuteTemplate(w, "register", tpld)
|
||||
if err != nil {
|
||||
|
@@ -15,15 +15,14 @@ func userStyle(r *http.Request) (style template.CSS) {
|
||||
switch cookie.Value {
|
||||
case "solarized_dark":
|
||||
selectedStyle = solarizedDarkStyle
|
||||
break
|
||||
case "maroon":
|
||||
selectedStyle = maroonStyle
|
||||
break
|
||||
case "hacker":
|
||||
selectedStyle = hackerStyle
|
||||
case "default":
|
||||
fallthrough // use default case
|
||||
default:
|
||||
selectedStyle = defaultPixeldrainStyle
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,3 +204,24 @@ var maroonStyle = pixeldrainStyleSheet{
|
||||
ShadowSpread: 50,
|
||||
ShadowIntensity: 5,
|
||||
}
|
||||
|
||||
var hackerStyle = pixeldrainStyleSheet{
|
||||
TextColor: hsl{0, 0, 1},
|
||||
InputColor: hsl{0, 0, .25},
|
||||
InputTextColor: hsl{0, 0, 1},
|
||||
HighlightColor: hsl{120, 1, .6},
|
||||
HighlightTextColor: hsl{0, 0, 0},
|
||||
DangerColor: hsl{0, .65, .31},
|
||||
DangerColorDark: hsl{0, .64, .23},
|
||||
FileBackgroundColor: hsl{120, .8, .06},
|
||||
|
||||
BackgroundColor: hsl{0, 0, 0},
|
||||
BodyColor: hsl{0, 0, 0},
|
||||
AccentColorDark: hsl{0, 0, .05},
|
||||
AccentColorMedium: hsl{0, 0, .10},
|
||||
AccentColorLight: hsl{0, 0, .15},
|
||||
|
||||
ShadowColor: hsl{120, 1, .1},
|
||||
ShadowSpread: 50,
|
||||
ShadowIntensity: 5,
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
|
||||
"fornaxian.com/pixeldrain-web/init/conf"
|
||||
"fornaxian.com/pixeldrain-web/pixelapi"
|
||||
"fornaxian.com/pixeldrain-web/webcontroller/forms"
|
||||
"github.com/Fornaxian/log"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
@@ -176,3 +177,22 @@ func (wc *WebController) getAPIKey(r *http.Request) (key string, err error) {
|
||||
}
|
||||
return "", errors.New("not a valid pixeldrain authentication cookie")
|
||||
}
|
||||
|
||||
func (wc *WebController) captchaKey() string {
|
||||
// This only runs on the first request
|
||||
if wc.captchaSiteKey == "" {
|
||||
var api = pixelapi.New(wc.conf.APIURLInternal, "")
|
||||
capt, err := api.GetRecaptcha()
|
||||
if err != nil {
|
||||
log.Error("Error getting recaptcha key: %s", err)
|
||||
return ""
|
||||
}
|
||||
if capt.SiteKey == "" {
|
||||
wc.captchaSiteKey = "none"
|
||||
} else {
|
||||
wc.captchaSiteKey = capt.SiteKey
|
||||
}
|
||||
}
|
||||
|
||||
return wc.captchaSiteKey
|
||||
}
|
||||
|
Reference in New Issue
Block a user