diff --git a/.gitignore b/.gitignore index 33891fd..077c648 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,4 @@ -out/ -*.xml -src/php/config.php -google*.html -bower_components/ -.vs +.vs/ bin/ obj/ *.csproj.user \ No newline at end of file diff --git a/bower.json b/bower.json deleted file mode 100644 index e7b35f9..0000000 --- a/bower.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "void.cat", - "description": "void.cat", - "main": "index.html", - "authors": [ - "v0l" - ], - "license": "MIT", - "homepage": "https://github.com/v0l/void.cat", - "private": true, - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], - "dependencies": { - "polymer": "polymer/polymer#^2.0.0", - "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.17" - } -} diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..1e11362 --- /dev/null +++ b/build.bat @@ -0,0 +1,2 @@ +@echo off +sass src/style.scss dist/style.css && google-closure-compiler src/script.js src/ripemd160.js --js_output_file dist/script.min.js --language_out ECMASCRIPT_NEXT \ No newline at end of file diff --git a/index.html b/index.html index 0689443..3da20ce 100644 --- a/index.html +++ b/index.html @@ -1,49 +1,32 @@ - + - - void.cat - - - - - - - - - - - - - - -
-
- void.cat -
-
- + + + void.cat + + + + + + +
+
+
Click me!
+
asdf
+
+
+
+ + + + \ No newline at end of file diff --git a/polymer.json b/polymer.json deleted file mode 100644 index a40f535..0000000 --- a/polymer.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "entrypoint": "index.html", - "fragments": [ - "src/modules/main.html", - "src/modules/dropzone.html", - "src/modules/upload.html", - "src/modules/view.html" - ], - "sources": [ - "src/php/*.php", - "src/js/*.js", - "src/css/*.css" - ], - "builds": [ - { - "bundle": true, - "js": { "compile": true, "minify": true }, - "css": { "minify": true }, - "html": { "minify": true } - } - ] -} \ No newline at end of file diff --git a/src/css/style.css b/src/css/style.css deleted file mode 100644 index 18ffed4..0000000 --- a/src/css/style.css +++ /dev/null @@ -1,41 +0,0 @@ -html, body { - background-color: #dbedf5; - font-family: 'Roboto', sans-serif; - font-size: 12px; - padding: 0; - margin: 0; -} - -.page { - width:1024px; - margin-left:auto; - margin-right:auto; - margin-top:20px; - background-color: #a5d4ea; - border-radius: 5px; - border: 1px solid #aaa; -} - -.content { - padding:20px; -} - -.header{ - text-align: center; - color: #555555; - font-size: 50px; - padding: 10px; - border-bottom: 1px solid #aaa; - background-color: #E4E4E4; - border-radius: 5px 5px 0px 0px; -} - -@media(max-width: 1024px){ - .page { - width: auto; - margin: 10px 0 0 0; - } - .content { - padding: 5px; - } -} \ No newline at end of file diff --git a/src/css/style.scss b/src/css/style.scss new file mode 100644 index 0000000..23b5673 --- /dev/null +++ b/src/css/style.scss @@ -0,0 +1,88 @@ +$page-width: 1024px; +$page-height: 512px; +$page-padding: 10px; +$page-margin-top: 20px; +$dropzone-border-width: 2px; +$dropzone-height: ($page-height - ($dropzone-border-width * 2)) / 2; +$dropzone-width: ($page-width / 2) - ($dropzone-border-width * 2); + +$upload-progress-padding: 2px; +$upload-progress-height: 20px; +$upload-padding: 10px; +$upload-border: 2px solid rgb(168, 168, 168); + +html, body { + margin: 0; + padding: 0; + font-family: Arial; + font-size: 12px; + background-color: rgb(14, 14, 14); +} + +.page { + width: $page-width; + min-height: $page-height; + margin-left: auto; + margin-right: auto; + margin-top: $page-margin-top; + overflow: hidden; + padding: $page-padding; + border-radius: 10px; + background-color: rgb(233, 252, 255); + box-shadow: 0px 0px 15px 5px #000; + user-select: none; +} + +.float-left { + float: left; +} + +.left-module { + height: $dropzone-height; + width: $dropzone-width; +} + +#dropzone { + border: $dropzone-border-width dashed #333; + line-height: $dropzone-height; + text-align: center; + font-size: 50px; +} + +#uploads { + float: left; + width: ($page-width / 2); +} + +.upload { + overflow: hidden; + border: $upload-border; + margin: $upload-padding; + margin-top: 0; +} + +.upload .upload-progress { + border: 0.5px solid; + overflow: hidden; + text-align: center; + margin: 10px; +} + +.upload .status { + padding: 5px 5px 5px 10px; +} + +.upload .file-info { + text-align: center; + padding: 5px; + border-bottom: $upload-border; + background-color: #aaa; +} + +.upload .upload-progress div { + margin-top: -$upload-progress-height; + height: $upload-progress-height; + line-height: $upload-progress-height; + font-size: $upload-progress-height * 0.8; + background-color: rgb(10, 161, 10); +} \ No newline at end of file diff --git a/src/db.sql b/src/db.sql deleted file mode 100644 index a483d1a..0000000 --- a/src/db.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE `files` ( - `hash160` varchar(40) NOT NULL, - `hash256` varchar(64) NOT NULL, - `filename` varchar(255) NOT NULL, - `mime` varchar(64) NOT NULL, - `size` bigint(20) NOT NULL, - `path` varchar(512) NOT NULL, - `views` bigint(20) DEFAULT 0 NULL, - `isAdminFile` bit(1) DEFAULT 0 NULL, - `uploaded` timestamp NULL DEFAULT CURRENT_TIMESTAMP, - `lastview` timestamp NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`hash160`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 \ No newline at end of file diff --git a/src/js/ripemd160.js b/src/js/ripemd160.js new file mode 100644 index 0000000..0f72d28 --- /dev/null +++ b/src/js/ripemd160.js @@ -0,0 +1,29 @@ +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +/* + +(c) 2012 by C?dric Mesnil. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +var CryptoJS=CryptoJS||function(j,k){var e={},l=e.lib={},z=function(){},t=l.Base={extend:function(a){z.prototype=this;var c=new z;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, +u=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=k?c:4*a.length},toString:function(a){return(a||D).stringify(this)},concat:function(a){var c=this.words,h=a.words,d=this.sigBytes;a=a.sigBytes;this.clamp();if(d%4)for(var b=0;b>>2]|=(h[b>>>2]>>>24-8*(b%4)&255)<<24-8*((d+b)%4);else if(65535>>2]=h[b>>>2];else c.push.apply(c,h);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< +32-8*(c%4);a.length=j.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b>>2]>>>24-8*(d%4)&255;b.push((g>>>4).toString(16));b.push((g&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],d=0;d>>3]|=parseInt(a.substr(d, +2),16)<<24-4*(d%8);return new u.init(b,c/2)}},A=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],d=0;d>>2]>>>24-8*(d%4)&255));return b.join("")},parse:function(a){for(var b=a.length,h=[],d=0;d>>2]|=(a.charCodeAt(d)&255)<<24-8*(d%4);return new u.init(h,b)}},g=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(A.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return A.parse(unescape(encodeURIComponent(a)))}}, +v=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new u.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=g.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var b=this._data,h=b.words,d=b.sigBytes,g=this.blockSize,v=d/(4*g),v=a?j.ceil(v):j.max((v|0)-this._minBufferSize,0);a=v*g;d=j.min(4*a,d);if(a){for(var e=0;eb;b++){var a=e+b,c=g[a];g[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360}var a=this._hash.words,c=D.words,h=A.words,d=z.words,j=t.words,k=u.words,l=w.words,B,m,n,p,x,C,q,r,s,y;C=B=a[0];q=m=a[1];r=n=a[2];s=p=a[3];y=x=a[4];for(var f,b=0;80>b;b+=1)f=B+g[e+d[b]]|0,f=16>b?f+((m^n^p)+c[0]):32>b?f+((m&n|~m&p)+c[1]):48>b? +f+(((m|~n)^p)+c[2]):64>b?f+((m&p|n&~p)+c[3]):f+((m^(n|~p))+c[4]),f|=0,f=f<>>32-k[b],f=f+x|0,B=x,x=p,p=n<<10|n>>>22,n=m,m=f,f=C+g[e+j[b]]|0,f=16>b?f+((q^(r|~s))+h[0]):32>b?f+((q&s|r&~s)+h[1]):48>b?f+(((q|~r)^s)+h[2]):64>b?f+((q&r|~q&s)+h[3]):f+((q^r^s)+h[4]),f|=0,f=f<>>32-l[b],f=f+y|0,C=y,y=s,s=r<<10|r>>>22,r=q,q=f;f=a[1]+n+s|0;a[1]=a[2]+p+y|0;a[2]=a[3]+x+C|0;a[3]=a[4]+B+q|0;a[4]=a[0]+m+r|0;a[0]=f},_doFinalize:function(){var g=this._data,e=g.words,b=8*this._nDataBytes,a=8*g.sigBytes; +e[a>>>5]|=128<<24-a%32;e[(a+64>>>9<<4)+14]=(b<<8|b>>>24)&16711935|(b<<24|b>>>8)&4278255360;g.sigBytes=4*(e.length+1);this._process();g=this._hash;e=g.words;for(b=0;5>b;b++)a=e[b],e[b]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;return g},clone:function(){var e=l.clone.call(this);e._hash=this._hash.clone();return e}});j.RIPEMD160=l._createHelper(k);j.HmacRIPEMD160=l._createHmacHelper(k)})(Math); diff --git a/src/js/script.js b/src/js/script.js new file mode 100644 index 0000000..bab1907 --- /dev/null +++ b/src/js/script.js @@ -0,0 +1,326 @@ +/** + * @constant {number} - Size of 1 kiB + */ +const kiB = Math.pow(1024, 1); +/** + * @constant {number} - Size of 1 MiB + */ +const MiB = Math.pow(1024, 2); +/** + * @constant {number} - Size of 1 GiB + */ +const GiB = Math.pow(1024, 3); +/** + * @constant {number} - Size of 1 TiB + */ +const TiB = Math.pow(1024, 4); +/** + * @constant {number} - Size of 1 PiB + */ +const PiB = Math.pow(1024, 5); +/** + * @constant {number} - Size of 1 EiB + */ +const EiB = Math.pow(1024, 6); +/** + * @constant {number} - Size of 1 ZiB + */ +const ZiB = Math.pow(1024, 7); +/** + * @constant {number} - Size of 1 YiB + */ +const YiB = Math.pow(1024, 8); +/** + * @constant {function} - Helper function for document.querySelector + * @param {string} selector - The selector to use in the query + * @returns {HTMLElement} The first selected element + */ +const $ = (selector) => document.querySelector(selector); + +const Log = { + I: (msg) => console.log(`[App_v ${App.Version}][I]: ${msg}`), + W: (msg) => console.warn(`[App_v ${App.Version}][W]: ${msg}`), + E: (msg) => console.error(`[App_v ${App.Version}][E]: ${msg}`) +}; + +/** + * @constant {Object} + */ +const App = { + get Version() { return "1.0" }, + + Elements: { + get Dropzone() { return $('#dropzone') }, + get Uploads() { return $('#uploads') } + }, + + Templates: { + get Upload() { return $("template[id='tmpl-upload']") } + }, + + /** + * Uploads the files as selected by the input form + * @param {Element} ctx + * @returns {Promise} + */ + UploadFiles: async function (ctx) { + let files = ctx.files; + let proc_files = []; + + for (let x = 0; x < files.length; x++) { + let fu = new FileUpload(files[x]); + proc_files[proc_files.length] = fu.ProcessUpload(); + } + + await Promise.all(proc_files); + }, + + Utils: { + /** + * Formats an ArrayBuffer to hex + * @param {ArrayBuffer} buffer - Input data to convert to hex + * @returns {string} The encoded data as a hex string + */ + ArrayToHex: (buffer) => Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join(''), + + /** + * Formats bytes into binary notation + * @param {number} b - The value in bytes + * @param {number} [f=2] - The number of decimal places to use + * @returns {string} Bytes formatted in binary notation + */ + FormatBytes: (b, f) => { + f = typeof f === 'number' ? 2 : f; + if (b >= YiB) + return (b / YiB).toFixed(f) + ' YiB'; + if (b >= ZiB) + return (b / ZiB).toFixed(f) + ' ZiB'; + if (b >= EiB) + return (b / EiB).toFixed(f) + ' EiB'; + if (b >= PiB) + return (b / PiB).toFixed(f) + ' PiB'; + if (b >= TiB) + return (b / TiB).toFixed(f) + ' TiB'; + if (b >= GiB) + return (b / GiB).toFixed(f) + ' GiB'; + if (b >= MiB) + return (b / MiB).toFixed(f) + ' MiB'; + if (b >= kiB) + return (b / kiB).toFixed(f) + ' KiB'; + return b.toFixed(f) + ' B' + } + }, + + /** + * Sets up the page + */ + Init: function () { + new DropzoneManager(App.Elements.Dropzone) + } +}; + +/** + * Make a HTTP request with promise + * @param {string} method - HTTP method for this request + * @param {string} url - Request URL + * @param {[object]} data - Request payload (method must be post) + * @returns {Promise} The completed request + */ +const XHR = function(method, url, data){ + return new Promise(function (resolve, reject) { + let x = new XMLHttpRequest(); + x.onreadystatechange = function (ev) { + if (ev.target.readyState === 4) { + resolve(ev.target); + } + }; + x.onerror = function (ev) { + reject(ev); + }; + x.open(method, url, true); + if (method === "POST" && typeof data === "object" && data !== null) { + x.setRequestHeader('Content-Type', 'application/json'); + x.send(JSON.stringify(data)); + } else { + x.send(); + } + }) +}; + +/** +* @constructor Creates an instance of the DropzoneManager +* @param {HTMLElement} dz - Dropzone element +*/ +const DropzoneManager = function (dz) { + this.dz = dz; + + this.OpenFileSelect = function(ev){ + let i = document.createElement('input'); + i.setAttribute('type', 'file'); + i.setAttribute('multiple', ''); + i.addEventListener('change', function (evt) { + let fl = evt.target.files; + for (let z = 0; z < fl.length; z++) { + new FileUpload(fl[z]).ProcessUpload(); + } + }.bind(this)); + i.click(); + }; + + this.dz.addEventListener('click', this.OpenFileSelect.bind(this), false); +}; + +/** + * File upload handler class + * @class + * @param {File} file - The file handle to upload + */ +const FileUpload = function (file) { + this.hasCrypto = typeof window.crypto.subtle === "object"; + this.file = file; + this.domNode = null; + + /** + * Loads the file and SHA256 hashes it + * @return {Promise} + */ + this.HashFile = async () => { + return new Promise(function (resolve, reject) { + var fr = new FileReader(); + + fr.onloadstart = function (ev) { + this.HandleProgress('state-load-start'); + }.bind(this); + + fr.onloadend = function (ev) { + this.HandleProgress('state-load-end'); + }.bind(this); + + fr.onload = function (ev) { + this.HandleProgress('state-hash-start'); + crypto.subtle.digest("SHA-256", ev.target.result).then(function (hash) { + this.HandleProgress('state-hash-end'); + this.HandleProgress('progress-hash-file', 1); //no progress from crypto.subtle.digest so we cant show any progress + resolve(hash); + }.bind(this)); + }.bind(this); + + fr.onprogress = function (ev) { + this.HandleProgress('progress-load-file', ev.loaded / parseFloat(ev.total)); + }.bind(this); + + fr.onerror = function (ev) { + this.HandleError({ + type: 'FileReaderError', + error: ev.target.error + }) + }.bind(this); + + fr.readAsArrayBuffer(this.file); + }.bind(this)); + }; + + /** + * Sets the width of the progress bar for this upload + * @param {number} value - The value of the progress + */ + this.SetProgressBar = function (value) { + this.domNode.progress.textContent = `${(100 * value).toFixed(1)}%`; + this.domNode.progressBar.style.width = `${(100 * value)}%`; + }; + + /** + * Sets the status label for this upload + * @param {string} value - The status label + */ + this.SetStatus = function (value){ + this.domNode.status.textContent = `Status: ${value}`; + }; + + /** + * Handles progress messages from the upload process and updates the UI + * @param {string} type - The progress event type + * @param {number} progress - The percentage of this progress type + */ + this.HandleProgress = function (type, progress) { + switch (type) { + case 'state-load-start': { + this.SetStatus('Loading file..'); + this.SetProgressBar(0); + break; + } + case 'state-load-end': { + + break; + } + case 'state-hash-start': { + this.SetStatus('Hashing..'); + this.SetProgressBar(0); + break; + } + case 'state-hash-end': { + + break; + } + case 'state-upload-start': { + this.SetStatus('Uploading..'); + this.SetProgressBar(0); + break; + } + case 'state-upload-end': { + + break; + } + case 'progress-load-file': { + this.SetProgressBar(progress < 0.01 ? 0.01 : progress); + break; + } + case 'progress-hash-file': { + this.SetProgressBar(progress < 0.01 ? 0.01 : progress); + break; + } + } + }; + + /** + * Handles upload errors to display on the UI + */ + this.HandleError = function (err) { + Log.E(err.error); + switch (err.type) { + case 'FileReaderError': { + this.SetProgressBar('1px'); + break; + } + } + }; + + /** + * Creates a template for the upload to show progress + */ + this.CreateNode = function () { + let nelm = document.importNode(App.Templates.Upload.content, true); + nelm.fileInfo = nelm.querySelector('.file-info'); + nelm.progress = nelm.querySelector('.upload-progress span'); + nelm.progressBar = nelm.querySelector('.upload-progress div'); + nelm.status = nelm.querySelector('.status'); + + nelm.fileInfo.textContent = this.file.name; + this.domNode = nelm; + $('#uploads').appendChild(nelm); + }; + + /** + * Processes the file upload + * @return {Promise} + */ + this.ProcessUpload = async function () { + Log.I(`Starting upload for ${this.file.name}`); + this.CreateNode(); + + let h256 = App.Utils.ArrayToHex(await this.HashFile()); + let h160 = CryptoJS.RIPEMD160(h256); + Log.I(`${this.file.name} hash is: ${h256} (${h160})`); + }; +}; +App.Init(); diff --git a/src/js/util.js b/src/js/util.js deleted file mode 100644 index dd74372..0000000 --- a/src/js/util.js +++ /dev/null @@ -1,88 +0,0 @@ -const API = { - xhr: function (method, url, data, cb) { - let x = new XMLHttpRequest(); - x.onreadystatechange = function () { - if (x.readyState === 4 && cb !== undefined && cb !== null && typeof cb === 'function') { - cb(this); - } - } - x.open(method, url, true); - if (data !== null) { - x.setRequestHeader('Content-Type', 'application/json'); - x.send(JSON.stringify(data)); - } else { - x.send(); - } - }, - - sendAPICommand: function (data, cb) { - API.xhr('POST', '/src/php/api.php', data, function (xhr) { - if(xhr.status == 200) { - cb(JSON.parse(xhr.response)); - } - }); - }, - - getServerConfig: function (cb) { - API.sendAPICommand({ cmd: 'config' }, function (data) { - cb(data); - }); - }, - - getFileInfo: function(hash, cb) { - API.sendAPICommand({ cmd: 'file', hash: hash }, function (data) { - cb(data); - }); - } -}; - -const Util = { - formatBytes: function (b, f) { - f = f === undefined ? 2 : f; - if(b >= 1099511627776) { - return (b / 1099511627776.0).toFixed(f) + ' TiB'; - }else if (b >= 1073741824) { - return (b / 1073741824.0).toFixed(f) + ' GiB'; - } else if (b >= 1048576) { - return (b / 1048576.0).toFixed(f) + ' MiB'; - } else if (b >= 1024) { - return (b / 1024.0).toFixed(f) + ' KiB'; - } - return b.toFixed(f | 2) + ' B' - } -}; - -const doCaptcha = function(view){ - API.sendAPICommand({ cmd: 'captcha_config' }, function(data){ - this.view.captchaKey = data.cap_key; - this.view.captchaDL = data.cap_dl; - - window['capLoad'] = function(){ - window["capCb"] = function(rsp){ - API.sendAPICommand({ cmd: 'captcha_verify', hash: this.view.fileInfo.hash160, token: rsp }, function(data){ - if(window.location.search.indexOf('?dl') === 0){ - window.location = window.location.href.replace('?dl#', ''); - }else{ - window.location.reload(); - } - }.bind({ view: this.view })); - }.bind({ view: this.view }); - - grecaptcha.render(document.querySelector('#g-recaptcha'), - { - sitekey: this.view.captchaKey, - callback: 'capCb' - } - ); - }.bind({ view: this.view }); - let cb = document.createElement('div'); - cb.id = 'g-recaptcha'; - - let par = document.querySelector('.content'); - par.insertBefore(cb, par.firstChild); - - let ct = document.createElement('script'); - ct.src = 'https://www.google.com/recaptcha/api.js?onload=capLoad&render=explicit'; - document.head.appendChild(ct); - }.bind({ view: view })); -}; \ No newline at end of file diff --git a/src/modules/dropzone.html b/src/modules/dropzone.html deleted file mode 100644 index 0f8d564..0000000 --- a/src/modules/dropzone.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/modules/main.html b/src/modules/main.html deleted file mode 100644 index c26e7aa..0000000 --- a/src/modules/main.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - diff --git a/src/modules/upload.html b/src/modules/upload.html deleted file mode 100644 index e44b77f..0000000 --- a/src/modules/upload.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/modules/view.html b/src/modules/view.html deleted file mode 100644 index 1bdb4bb..0000000 --- a/src/modules/view.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/php/abuse.php b/src/php/abuse.php new file mode 100644 index 0000000..c984f06 --- /dev/null +++ b/src/php/abuse.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/src/php/api.php b/src/php/api.php index 84c19a0..27aac7f 100644 --- a/src/php/api.php +++ b/src/php/api.php @@ -1,96 +1,13 @@ - $c - ); - - $redis = new Redis(); - $redis->pconnect(_REDIS_SERVER); +cmd){ - case "config": - { - include_once("db.php"); - - $db = new DB(); - $rsp["stats"] = $db->GetStats(); - - $maxsizeM = ini_get('post_max_size'); - $maxsize = (int)(str_replace('M', '', $maxsizeM) * 1000 * 1000); - $rsp["maxsize"] = $maxsize; - $rsp["expire"] = _FILE_EXPIRE_TIME; - //$rsp["tips"] = GetTipTotal(); - break; - } - case "file": - { - include_once("db.php"); - - $db = new DB(); - $fi = $db->GetFile($c->hash); - if($fi->hash160 != NULL) - { - unset($fi->path); //block internal path value - $fi->url = _SITEURL . $fi->hash160; - $rsp["file"] = $fi; - - $hashKey = _UIP . ':' . $fi->hash160; - - $dlCounter = $redis->get($hashKey); - if($dlCounter != False && $dlCounter >= _DL_CAPTCHA) { - ga_event("Captcha", "Hit"); - $rsp["captcha"] = True; - } - }else { - $rsp["file"] = NULL; - } - break; - } - case "captcha_config": - { - $rsp["cap_key"] = _CAPTCHA_KEY; - $rsp["cap_dl"] = _DL_CAPTCHA; - break; - } - case "captcha_verify": - { - $hashKey = _UIP . ':' . $c->hash; - - $dlCounter = $redis->get($hashKey); - if($dlCounter != FALSE) { - $ch = curl_init(); + class Api implements RequestHandler { + public function HandleRequest() { - curl_setopt($ch, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify'); - curl_setopt($ch, CURLOPT_POST, 1); - curl_setopt($ch, CURLOPT_POSTFIELDS, 'secret=' . _CAPTCHA_SECRET . '&response=' . $c->token . '&remoteip=' . _UIP); - - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - $crsp = json_decode(curl_exec($ch)); - curl_close ($ch); - - if($crsp->success == True){ - $dlCounter = 0; - $redis->setEx($hashKey, _CAPTCHA_DL_EXPIRE, 0); - $rsp["ok"] = True; - ga_event("Captcha", "Pass"); - }else{ - $rsp["ok"] = False; - ga_event("Captcha", "Fail"); - } - }else{ - $rsp["ok"] = True; - ga_event("Captcha", "Miss"); - } - break; - } - } + } + + public function GetStats() { + + } + } - header('Content-Type: application/json'); - echo json_encode($rsp); -?> +?> \ No newline at end of file diff --git a/src/php/config.php b/src/php/config.php new file mode 100644 index 0000000..d583812 --- /dev/null +++ b/src/php/config.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/src/php/config.php.sample b/src/php/config.php.sample deleted file mode 100644 index 81b6346..0000000 --- a/src/php/config.php.sample +++ /dev/null @@ -1,68 +0,0 @@ - "3AL9jqxVTjAZJMseBBnC75F3S6r4HSphUt", - "BCH" => "1qbcr7Bnt53sq9qEbPPrzu4jAvEeF6oUm", - "BTG" => "AbtKHMqpwUqJJVYj7f1roR6FCecViPt1zK", - "DASH" => "XfFNizQfuqwRtdx4WqpcK3L8tZEvG4WaJk", - "LTC" => "MGBNvUefXrFvdiZRNrQTG6UX8za2Phr5Eu", - "ZEC" => "t1VSkrikVyjoCKrC7DXnVPxPZCWRQihneTz", - "ETH" => "0x367e6864d84b38c58312a340afbd55417d1c9Ce2", - "TRX" => "0x367e6864d84b38c58312a340afbd55417d1c9Ce2", - "ETC" => "0x5653306b771d0ECD9f1010114a378a50301f68c3", - "XEM" => "NDWAWGJ5E5FCQTGKMTAQPS5TACICPB5NA4ZVT232" - )); -?> \ No newline at end of file diff --git a/src/php/cron.php b/src/php/cron.php deleted file mode 100644 index e6afd56..0000000 --- a/src/php/cron.php +++ /dev/null @@ -1,25 +0,0 @@ -GetExpiredFiles(); - - foreach($fl as $f) { - if(unlink($f->path)) { - $db->DeleteFile($f); - echo 'Deleted file: ' . $f->filename . ' (' . $f->hash160 . ') \n'; - $del[] = $f->hash160; - }else{ - echo 'Cant delete file ' . $f->path . ' \n'; - } - } - - if(count($fl) > 0){ - $discord_data = array("content" => 'Deleted ' . count($fl) . ' expired files. `' . implode("` `", $del) . '`'); - send_pub_discord_msg($discord_data); - } -?> diff --git a/src/php/db.php b/src/php/db.php index 338a807..8ac0087 100644 --- a/src/php/db.php +++ b/src/php/db.php @@ -1,187 +1,18 @@ error = null; - $this->mysqli = new mysqli(_DB_HOST, _DB_USER, _DB_PASS, _DB_DATABASE); - - if ($this->mysqli->connect_errno) { - $this->error = "Failed to connect to MySQL: (" . $this->mysqli->connect_errno . ") " . $this->mysqli->connect_error; - } - } - - function __destruct() - { - if($this->error == null) - { - $this->mysqli->close(); - } - } - - function Exists256($hash) - { - return $this->GetFile($hash, "hash256"); - } - - function GetStats() - { - $res = new FileStats(); - - $stmt = $this->mysqli->prepare("select count(hash160), sum(size), avg(size), sum(views * size) from files"); - if($stmt) - { - $stmt->execute(); - $stmt->bind_result($res->files, $res->size, $res->avgSize, $res->transfer); - $stmt->fetch(); - $stmt->close(); - $res->size = floatval($res->size); - $res->avgSize = floatval($res->avgSize); - $res->transfer = floatval($res->transfer); - } - - return $res; - } - - function GuessHash($hash) { - //sometimes are making a request like this: lets just do a LIKE query to find it bf9fdaa217271f9e1f6ab88...f42bd0a538 - //poor lost people i cri evry time - $res = null; - - $stmt = $this->mysqli->prepare("select hash160 from files where hash160 like ? limit 1"); - if($stmt) - { - $stmt->bind_param("s", $hash); - $stmt->execute(); - $stmt->bind_result($res); - $stmt->fetch(); - $stmt->close(); - } - - return $res; - } - - function GetFile($hash, $hc = "hash160") - { - $res = new FileUpload(); - - $stmt = $this->mysqli->prepare("select hash160, hash256, filename, mime, size, path, views, isAdminFile, uploaded, lastview from files where " . $hc . " = ? limit 1"); - if($stmt) - { - $stmt->bind_param("s", $hash); - $stmt->execute(); - $stmt->bind_result($res->hash160, $res->hash256, $res->filename, $res->mime, $res->size, $res->path, $res->views, $res->isAdminFile, $res->uploaded, $res->lastview); - $stmt->fetch(); - $stmt->close(); - } - - return $res; - } + class Db { + public static $Instance = NULL; + public static $Error = NULL; - function GetFiles() - { - $res = array(); + public static function Connect() { + $cfg = Config::$Instance; + self::$Instance = new mysqli($cfg->db_host, $cfg->db_user, $cfg->db_password, $cfg->db_database); - $stmt = $this->mysqli->prepare("select hash160, hash256, filename, mime, size, path, views, isAdminFile, uploaded, lastview from files order by uploaded desc"); - if($stmt) - { - $stmt->execute(); - $stmt->bind_result($hash160, $hash256, $filename, $mime, $size, $path, $views, $isAdminFile, $uploaded, $lastview); - while($stmt->fetch()){ - $nf = new FileUpload(); - $nf->hash160 = $hash160; - $nf->hash256 = $hash256; - $nf->filename = $filename; - $nf->mime = $mime; - $nf->size = $size; - $nf->path = $path; - $nf->views = $views; - $nf->isAdminFile = $isAdminFile; - $nf->uploaded = $uploaded; - $nf->lastview = $lastview; - - array_push($res, $nf); - } - $stmt->close(); - } - - return $res; - } - - function InsertFile($f) - { - $stmt = $this->mysqli->prepare("insert into files(hash160, hash256, filename, mime, size, path) values(?,?,?,?,?,?)"); - if($stmt) - { - $stmt->bind_param("ssssss", $f->hash160, $f->hash256, $f->filename, $f->mime, $f->size, $f->path); - $stmt->execute(); - $stmt->close(); - } - } - - function DeleteFile($f) - { - $stmt = $this->mysqli->prepare("delete from files where hash160 = ?"); - if($stmt) - { - $stmt->bind_param("s", $f->hash160); - $stmt->execute(); - $stmt->close(); - } - } - - function UpdateFileSize($h, $s) - { - $stmt = $this->mysqli->prepare("update files set size = ? where hash160 = ?"); - if($stmt) - { - $stmt->bind_param("ds", $s, $h); - $stmt->execute(); - $stmt->close(); - } - } - - function AddView($hash160) - { - $stmt = $this->mysqli->prepare("update files set views = views + 1, lastview = NOW() where hash160 = ?"); - if($stmt) - { - $stmt->bind_param("s", $hash160); - $stmt->execute(); - $stmt->close(); - } - } - - function GetExpiredFiles() - { - return $this->GetExpiredFilesT(_FILE_EXPIRE_TIME); - } - - function GetExpiredFilesT($tt) - { - $res = array(); - - $stmt = $this->mysqli->prepare("select hash160, filename, path, lastview, size from files where date_add(lastview, INTERVAL " . $tt . " DAY) < CURRENT_TIMESTAMP or (views = 0 and date_add(lastview, INTERVAL 1 DAY) < CURRENT_TIMESTAMP) order by lastview desc"); - if($stmt) - { - $stmt->execute(); - $stmt->bind_result($hash160, $filename, $path, $lastview, $size); - while($stmt->fetch()){ - $nf = new FileUpload(); - $nf->hash160 = $hash160; - $nf->filename = $filename; - $nf->path = $path; - $nf->lastview = $lastview; - $nf->size = $size; - array_push($res, $nf); - } - $stmt->close(); - } - - return $res; - } - }; -?> + if (mysqli_connect_errno()) { + self::$Error = mysqli_connect_error(); + return FALSE; + } + return TRUE; + } + } +?> \ No newline at end of file diff --git a/src/php/download.php b/src/php/download.php index 9611fa9..4ba27f3 100644 --- a/src/php/download.php +++ b/src/php/download.php @@ -1,152 +1,31 @@ pconnect(_REDIS_SERVER); - - if(!isset($_SERVER['HTTP_RANGE'])) { - matomo_page_view($redis); - } - - $hash = substr($_SERVER["REQUEST_URI"], 1); - $hashKey = _UIP . ':' . $hash; + class Download implements RequestHandler { - if(_IS_LB_HOST == False && count(_LB_HOSTS) > 0) { - $has_cache = $redis->sIsMember("VC:DL:LB", $hash); - if($has_cache == False) { - $lb_hash_cache = True; - foreach(_LB_HOSTS as $lbh) { - $lb_x = json_decode(curl_get($lbh . "/hasfile.php?hash=" . $hash, array("Host: " . _LB_HOSTNAME))); - if($lb_x->result == False){ - $lb_hash_cache = False; - break; - } - } - - if($lb_hash_cache == True){ - $redis->sadd("VC:DL:LB", $hash); - header("location: https://" . _LB_HOSTNAME . "/" . $hash, true, 301); - exit(); - } - } else { - header("location: https://" . _LB_HOSTNAME . "/" . $hash, true, 301); - exit(); - } - } else { - $redis->publish('dl-track', json_encode(array( - "host" => gethostname(), - "uid" => isset($_COOKIE["VC:UID"]) ? $_COOKIE["VC:UID"] : NULL, - "uip" => _UIP, - "hash" => $hash, - "range" => isset($_SERVER['HTTP_RANGE']) ? $_SERVER['HTTP_RANGE'] : NULL - ))); - } - - $refr = isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : False; - if($refr != False){ - $rh = parse_url($refr)["host"]; - if(in_array($rh, _BLOCK_REFERER)){ - header("Content-Type: text/html"); - echo file_get_contents("empty.html"); - //http_response_code(403); - exit(); - } - - if(_IS_LB_HOST == False && $rh != "void.cat") { - //redirect to view page from hotlink - header("location: /#" . $hash); - exit(); - } - } - - //check is range request - $is_non_range = True; - if(isset($_SERVER['HTTP_RANGE'])){ - $rby = explode('=', $_SERVER['HTTP_RANGE']); - $rbv = explode('-', $rby[1]); - if($rbv[0] != '0'){ - $is_non_range = False; - } - } - - //block certain bots from counting views (to stop files never expiring) - $isCrawlBot = False; - $ua = isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : ""; - if(preg_match('/.*(\(.*\))/i', $ua, $matches) == 1) - { - $opts = array(); - if(strpos($matches[1], ';') != False){ - $opts = explode(';', $matches[1]); - }else{ - $opts[0] = $matches[1]; - } - - foreach($opts as $opt){ - if(in_array(trim($opt), _UA_NO_VIEW)){ - $isCrawlBot = True; - break; - } - } - } - - $dlCounter = $redis->get($hashKey); - if($dlCounter != FALSE) { - if($dlCounter >= _DL_CAPTCHA * 2){ - $cfbk = 'VC:CF:BLOCK'; - if(_CLOUDFLARE_API_KEY != 'API_KEY' && $redis->sIsMember($cfbk, _UIP) == False){ - $redis->sadd($cfbk, _UIP); - AddFirewallRule(_UIP); - } - header('location: /'); - exit(); - }else if($dlCounter >= _DL_CAPTCHA){ - //redirect for captcha check - $redis->incr($hashKey); - ga_event("Captcha", "Hit"); - header('location: ' . _SITEURL . '?dl#' . $hash); - exit(); - } - }else{ - $redis->setEx($hashKey, _CAPTCHA_DL_EXPIRE, 0); - $dlCounter = 0; - } - - include_once('db.php'); - $db = new DB(); - - //try to guess the hash if the link was truncated with '...' - if(strpos($hash, "...") !== false) { - $nh = str_replace("...", "%", $hash); - $gh = $db->GuessHash($nh); - if($gh !== null) { - header('location: ' . _SITEURL . $gh); - exit(); - } - } - - $f = $db->GetFile($hash); - if($f->hash160 != NULL){ - $vtr = CheckVirusTotalCached($redis, $f->hash256, $f->hash160); - if($vtr != null && isset($vtr->positives) && $vtr->positives > 1) { - http_response_code(404); - }else { - $expire = 604800; - $location = _UPLOADDIR . $f->hash160; - $mimeType = $f->mime; - $filename = $f->filename; - - header("X-Accel-Redirect: $location"); - header("Cache-Control: public, max-age=$expire"); - header("Content-type: $mimeType"); - header('Content-Disposition: inline; filename="' . $filename . '"'); - - if(!$isCrawlBot && $is_non_range){ - $db->AddView($f->hash160); - $redis->incr($hashKey); - } - } - }else{ - http_response_code(404); - } -?> + function __construct(){ + $this->Redis = StaticRedis::$Instance; + $this->Config = Config::$Instance; + $this->Db = Db::$Instance; + + $this->Abuse = new Abuse(); + $this->Tracking = new Tracking(); + $this->FileStore = new FileStore(); + + $this->Redis->pconnect($this->Config->Redis); + } + + public function HandleRequest() { + if(isset($_REQUEST["hash"])){ + $hash = $_REQUEST["hash"]; + + $fi = $this->FileStore->GetFileInfo($hash); + } else { + http_response_code(404); + exit(); + } + } + + function StartDownload($req){ + + } + } +?> \ No newline at end of file diff --git a/src/php/empty.html b/src/php/empty.html deleted file mode 100644 index e75576e..0000000 --- a/src/php/empty.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -!! ☠☠☠ !! - - - - - - - \ No newline at end of file diff --git a/src/php/file.php b/src/php/file.php deleted file mode 100644 index 239ba17..0000000 --- a/src/php/file.php +++ /dev/null @@ -1,21 +0,0 @@ - \ No newline at end of file diff --git a/src/php/filestore.php b/src/php/filestore.php new file mode 100644 index 0000000..c80bff3 --- /dev/null +++ b/src/php/filestore.php @@ -0,0 +1,13 @@ +Redis = StaticRedis::$Instance; + $this->Db = Db::$Instance; + } + + public function GetFileInfo($h160) { + + } + } +?> \ No newline at end of file diff --git a/src/php/functions.php b/src/php/functions.php deleted file mode 100644 index b62e4bd..0000000 --- a/src/php/functions.php +++ /dev/null @@ -1,378 +0,0 @@ - "2.0", "method" => $method, "params" => $params, "id" => 1)) . "\n"); - $rsp = fgets($sock); - fclose($sock); - return json_decode($rsp); - } - return NULL; - } - - function curl_json_get($url) - { - return json_decode(curl_get($url)); - } - - function curl_get($url) - { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_USERAGENT, _CURL_USER_AGENT); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); - - $result = curl_exec($ch); - curl_close($ch); - return $result; - } - - function curl_post($url, $data) - { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_USERAGENT, _CURL_USER_AGENT); - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); - - $result = curl_exec($ch); - curl_close($ch); - return $result; - } - - function GetAllAddrInfo($addrs) - { - $ret = array(); - - foreach($addrs as $cur => $addr) - { - $f = "GetAddrInfo_" . $cur; - if(is_callable($f)) { - $val = call_user_func($f, $addr); - if($val) - { - array_push($ret, (object) [ - "currency" => $cur, - "address" => $addr, - "balance" => $val->balance, - "txns" => $val->txns - ]); - } - } - } - - return $ret; - } - - function GetAddrInfo_BTC($addr) - { - $val = curl_json_get("https://api.blockcypher.com/v1/btc/main/addrs/" . $addr . "/balance"); - return (object) [ - "balance" => $val->final_balance * SAT, - "txns" => $val->final_n_tx - ]; - } - - function GetAddrInfo_LTC($addr) - { - $val = curl_json_get("https://api.blockcypher.com/v1/ltc/main/addrs/" . $addr . "/balance"); - return (object) [ - "balance" => $val->final_balance, - "txns" => $val->final_n_tx - ]; - } - - function GetAddrInfo_DASH($addr) - { - $val = curl_json_get("https://api.blockcypher.com/v1/dash/main/addrs/" . $addr . "/balance"); - return (object) [ - "balance" => $val->final_balance, - "txns" => $val->final_n_tx - ]; - } - - function GetAddrInfo_BCH($addr) - { - $val = curl_json_get("https://bitcoincash.blockexplorer.com/api/addr/" . $addr . "/balance"); - return (object) [ - "balance" => $val->balance, - "txns" => $val->txApperances, - "new_addr" => $val->addrStr - ]; - } - - function GetAddrInfo_ETH_ERC20($contract, $addr) - { - $val = curl_json_get("https://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=" . $contract . "&address=" . $addr . "&tag=latest&apikey=" . _ETHERSCAN_API_KEY); - return (object) [ - "balance" => $val->response, - "txns" => 0 - ]; - } - - function GetAddrInfo_EOS($addr) - { - return GetAddrInfo_ETH_ERC20("0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0", $addr); - } - - function GetAddrInfo_TRX($addr) - { - return GetAddrInfo_ETH_ERC20("0xf230b790e05390fc8295f4d3f60332c93bed42e2", $addr); - } - - function GetAddrInfo_ETH($addr) - { - $val = curl_json_get("https://api.etherscan.io/api?module=account&action=balance&address=" . $addr . "&tag=latest&apikey=" . _ETHERSCAN_API_KEY); - return (object) [ - "balance" => $val->response, - "txns" => 0 - ]; - } - - function GetAddrInfo_ETC($addr) - { - $val = curl_json_get("https://etcchain.com/api/v1/getAddressBalance?address=" . $addr); - return (object) [ - "balance" => $val->balance, - "txns" => 0 - ]; - } - - function GetAddrInfo_BTG($addr) - { - $val = curl_get("https://btgexp.com/ext/getaddress/" . $addr); - return (object) [ - "balance" => floatval($val), - "txns" => 0 - ]; - } - - function GetAddrInfo_ZEC($addr) - { - $val = curl_get("https://api.zcha.in/v2/mainnet/accounts/" . $addr); - return (object) [ - "balance" => $val->balance, - "txns" => $val->recvCount - ]; - } - - function GetAddrInfo_XEM($addr) - { - //pick a random node to query - $nodes = curl_json_get("https://nodeexplorer.com/api_openapi_version"); - $api = array_rand($nodes->nodes); - - $val = curl_json_get("http://" . $nodes->nodes[$api] . "/account/get?address=" . $addr); - return (object) [ - "balance" => $val->account->balance, - "txns" => 0 - ]; - } - - function GetBTCPrice() - { - $val = curl_json_get("https://api.coinmarketcap.com/v2/ticker/1/"); - return $val->data->quotes->USD->price; - } - - function call_webhook($url, $data) { - curl_post($url, json_encode($data)); - } - - function send_pub_discord_msg($data) { - call_webhook(_DISCORD_WEBHOOK_PUB, $data); - } - - function send_discord_msg($data) { - call_webhook(_DISCORD_WEBHOOK, $data); - } - - function ga_collect($p) { - $url = "https://www.google-analytics.com/collect"; - $p["v"] = "1"; - $p["tid"] = _GA_SITE_CODE; - $p["cid"] = session_id(); - - curl_post($url, http_build_query($p)); - } - - function ga_page_view($redis){ - matomo_page_view($redis); - return; - - $msg = http_build_query(array( - "v" => "1", - "tid" => _GA_SITE_CODE, - "cid" => isset($_COOKIE["VC:UID"]) ? $_COOKIE["VC:UID"] : uniqid(), - "t" => "pageview", - "dh" => $_SERVER['HTTP_HOST'], - "dp" => $_SERVER['REQUEST_URI'], - "uip" => _UIP, - "ua" => isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : "", - "dr" => isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : "" - )); - - $redis->publish('ga-page-view', $msg); - } - - function matomo_page_view($redis){ - $msg = "?" . http_build_query(array( - "idsite" => 1, - "rec" => 1, - "apiv" => 1, - "_id" => isset($_COOKIE["VC:UID"]) ? $_COOKIE["VC:UID"] : uniqid(), - "url" => (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]", - "cip" => _UIP, - "ua" => isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : "", - "urlref" => isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : "" - )); - - $redis->publish('ga-page-view-matomo', $msg); - } - - function ga_event($cat, $act) { - ga_collect(array( - "t" => "event", - "ec" => $cat, - "ea" => $act - )); - } - - function clamav_scan_stream($res, $slen) { - $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); - socket_connect($socket, '127.0.0.1', 3310); - - $cs = 1 * 1000 * 1000; //1MB chunk size - $offset = 0; - - socket_write($socket, "zINSTREAM\0"); - while ($chunk = fread($res, $cs)) { - $size = pack('N', strlen($chunk)); - socket_write($socket, $size); - socket_write($socket, $chunk); - } - socket_write($socket, pack('N', 0)); - rewind($res); - - $response = null; - do { - $data = socket_read($socket, 128); - if($data === "") { - break; - } - $response .= $data; - - if(substr($response, -1) === "\0"){ - break; - } - }while(true); - - return substr($response, 0, -1); - } - - function CheckVirusTotal($h256) { - $post = array('apikey' => _VIRUSTOTAL_KEY, 'resource' => $h256); - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, 'https://www.virustotal.com/vtapi/v2/file/report'); - curl_setopt($ch, CURLOPT_POST,1); - curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); - curl_setopt($ch, CURLOPT_USERAGENT, "gzip, void.cat virus check"); - curl_setopt($ch, CURLOPT_RETURNTRANSFER ,true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $post); - - $result = curl_exec ($ch); - curl_close ($ch); - - $vtr = json_decode($result, true); - - if($vtr["response_code"] == 1 && $vtr["positives"] > 0){ - $discord_data = array("content" => "[VIRUS DETECTED] " . $vtr["permalink"]); - send_pub_discord_msg($discord_data); - } - - return $vtr; - } - - function ScanFile($res) { - $ch = curl_init(); - $bnd_id = "---------------------------735323031399963166993862150"; - - $post_data = "--$bnd_id\r\nContent-Disposition: form-data; name='apikey'\r\n\r\n" . _VIRUSTOTAL_KEY . "\r\n--$bnd_id\r\nContent-Disposition: form-data; name='file'; filename='binary'\r\nContent-Type: application/octet-stream\r\n\r\n" . stream_get_contents($res) . "\r\n--$bnd_id--"; - $options = array( - CURLOPT_URL => "https://www.virustotal.com/vtapi/v2/file/scan", - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "gzip,deflate", - CURLOPT_USERAGENT => "gzip, void.cat virus check", - CURLOPT_VERBOSE => true, - CURLOPT_HTTPHEADER => array( - "Content-Type: multipart/form-data; boundary=$bnd_id" - ), - CURLOPT_POST => true, - CURLOPT_POSTFIELDS => $post_data - ); - curl_setopt_array($ch, $options); - - $result = curl_exec($ch); - $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - - if($status_code != 200) { - return json_encode(array('response_code' => 0, 'verbose_msg' => 'Error, got status code: ' . $status_code), true); - } else { - return json_decode($result, true); - } - } - - function CheckVirusTotalCached($redis, $h256) { - $vr = $redis->get("VC:VT:" . $h256); - if($vr != FALSE) { - return json_decode($vr); - }else { - $vtr = CheckVirusTotal($h256); - if($vtr["response_code"] == 1 && $vtr["positives"] > 0) { - $redis->set("VC:VT:" . $h256, json_encode($vtr)); - } else { - $redis->setEx("VC:VT:" . $h256, 60 * 60 * 24, json_encode($vtr)); - } - - return $vtr; - } - } - - function AddFirewallRule($ip) { - $post = array( - 'mode' => 'challenge', - 'configuration' => array( - 'target' => 'ip', - 'value' => $ip - ), - 'notes' => 'blocked by: ' . $_SERVER['SERVER_NAME'] - ); - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, 'https://api.cloudflare.com/client/v4/zones/' . _CLOUDFLARE_ZONE . '/firewall/access_rules/rules'); - curl_setopt($ch, CURLOPT_POST,1); - curl_setopt($ch, CURLOPT_RETURNTRANSFER ,true); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post)); - curl_setopt($ch, CURLOPT_HTTPHEADER, array( - 'Content-Type: application/json', - 'X-Auth-Email: ' . _CLOUDFLARE_API_EMAIL, - 'X-Auth-Key: ' . _CLOUDFLARE_API_KEY - )); - $result = curl_exec ($ch); - curl_close ($ch); - - $cfr = json_decode($result, true); - - if($cfr['success'] == True){ - send_discord_msg(array("content" => "[IP BLOCKED] " . $ip)); - }else { - send_discord_msg(array("content" => "[IP BLOCK ERROR] " . $ip . "\n```json\n" . $result . "\n```")); - } - - return $cfr; - } -?> diff --git a/src/php/handler.php b/src/php/handler.php new file mode 100644 index 0000000..47d44cb --- /dev/null +++ b/src/php/handler.php @@ -0,0 +1,16 @@ +HandleRequest(); + } + } + } +?> \ No newline at end of file diff --git a/src/php/hasfile.php b/src/php/hasfile.php deleted file mode 100644 index 4a8ed18..0000000 --- a/src/php/hasfile.php +++ /dev/null @@ -1,6 +0,0 @@ - file_exists(_FILEPATH . $_GET["hash"]))); -?> \ No newline at end of file diff --git a/src/php/lightning-tip.php b/src/php/lightning-tip.php deleted file mode 100644 index 6450ff2..0000000 --- a/src/php/lightning-tip.php +++ /dev/null @@ -1,101 +0,0 @@ - - - - - ⚡ Tip! ⚡ - - - -
- result)) { - header("location: /src/php/lightning-tip.php?label=" . $id); - } else { - echo "
" . json_encode($inv) . "
"; - } - } else { - $id = $_GET["label"]; - $node = ln_query("getinfo", array()); - $inv = ln_query("listinvoices", array($id)); - if(isset($inv->result) && isset($inv->result->invoices[0])) { - $i = $inv->result->invoices[0]; - $n = $node->result; - - echo "
" . $n->id . "@" . $n->address[0]->address . ":" . $n->address[0]->port . "
"; - - echo "
" . $i->bolt11 . "
"; - - $fn = "/tmp/" . $id . ".png"; - if(!file_exists($fn)) { - $cmd = "/usr/local/bin/myqr lightning:" . $i->bolt11 . " -n " . $id . ".png -c -d /tmp/ 2>&1"; - $qr = shell_exec($cmd); - } - $img_b64 = base64_encode(file_get_contents($fn)); - - echo ""; - } else { - echo "
" . json_encode($inv) . "
"; - } - } - ?> -
- - \ No newline at end of file diff --git a/src/php/redis.php b/src/php/redis.php new file mode 100644 index 0000000..f1c9778 --- /dev/null +++ b/src/php/redis.php @@ -0,0 +1,12 @@ +pconnect($cfg->redis); + } + } +?> \ No newline at end of file diff --git a/src/php/requesthandler.php b/src/php/requesthandler.php new file mode 100644 index 0000000..17dcbd9 --- /dev/null +++ b/src/php/requesthandler.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/src/php/tip-list.php b/src/php/tip-list.php deleted file mode 100644 index 779ab17..0000000 --- a/src/php/tip-list.php +++ /dev/null @@ -1,65 +0,0 @@ -result; - $sp = GetBTCPrice(); -?> - - - - Tip List - - - -

BTC price: $

- - - - - - - - - - - - invoices as $inv) - { - $col = ""; - switch($inv->status) { - case "paid": $col = "#00ff00"; break; - case "unpaid": $col = "#ffb100"; break; - } - - $val = isset($inv->msatoshi_received) ? $inv->msatoshi_received : 0; - if($inv->status === "paid") { - $total += $val; - } - echo ""; - } - ?> - -
idmsatoshiUSDstatuspaid
" . $inv->label . "" . number_format($val, 8) . "" . number_format($val * $sp * MSAT, 4) . "" . $inv->status . "" . (isset($inv->paid_at) ? date('Y/m/d H:i:s', $inv->paid_at) : "") . "
- Total: $" . number_format($total * $sp * MSAT, 4) . " (BTC " . number_format($total * MSAT, 8) . ")"; ?> - - diff --git a/src/php/tip-me.php b/src/php/tip-me.php deleted file mode 100644 index 9a19bac..0000000 --- a/src/php/tip-me.php +++ /dev/null @@ -1,104 +0,0 @@ - "bitcoin:%s", - "BCH" => "bitcoincash:%s", - "BTG" => "bitcoingold:%s", - "DASH" => "dash:%s", - "LTC" => "litecoin:%s", - "ZEC" => "zcash:%s", - "ETH" => "ethereum:%s", - "EOS" => "ethereum:%s", - "TRX" => "ethereum:%s", - "ETC" => "ethereum:%s&id=61", - "XEM" => "nem:%s" - ); - - $redis = new Redis(); - $redis->pconnect(_REDIS_SERVER); - - $inf = array(); - $inf_cache = $redis->get("tip_info_cache"); - if($inf_cache == false) { - $inf = GetAllAddrInfo(_TIP_ADDRS); - $redis->setEx("tip_info_cache", 3600, json_encode($inf)); - }else{ - $inf = json_decode($inf_cache); - } -?> - - - - - Tips - - - -
-

Tips help me get drunk, please consider tipping if you like the service I am currenly paying all the server bills myself.

- currency)]) ? ("currency], $addr->address) . "\">" . $addr->address . "") : $addr->address); - echo "
currency) . ".png\"/>
" . $addr_name . "
" . strtoupper($addr->currency) . " " . number_format($addr->balance, 8) . "
"; - } - ?> -
- - \ No newline at end of file diff --git a/src/php/tracking.php b/src/php/tracking.php new file mode 100644 index 0000000..4a775b8 --- /dev/null +++ b/src/php/tracking.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/src/php/upload.php b/src/php/upload.php deleted file mode 100644 index b6fac71..0000000 --- a/src/php/upload.php +++ /dev/null @@ -1,181 +0,0 @@ - 0, - "msg" => null, - "hash" => null, - "publichash" => null, - "link" => null, - "mime" => null, - "filename" => null, - "upload" => json_encode($_FILES) - ); - - $isMultipart = strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== False; - - //check input size is large enough - $maxsizeM = ini_get('post_max_size'); - $maxsize = (int)(str_replace('M', '', $maxsizeM) * 1024 * 1024); - $fsize = $isMultipart ? $_FILES['files']['size'][0] : (int)$_SERVER['CONTENT_LENGTH']; - $mime = $isMultipart ? $_FILES['files']['type'][0] : (strlen($_SERVER['CONTENT_TYPE']) > 0 ? $_SERVER['CONTENT_TYPE'] : _DEFAULT_TYPE); - $fname = $isMultipart ? $_FILES['files']['name'][0] : $_GET["filename"]; - - if($fsize > $maxsize) - { - $response["msg"] = "File too big"; - } - else - { - $tmpf = 0; - - if ($isMultipart === False) - { - $source = isset($_GET["remote"]) ? $_GET["remote"] : "php://input"; - - $rawf = fopen($source, 'rb'); - - if(isset($_GET["remote"])){ - $meta_data = stream_get_meta_data($rawf); - foreach($meta_data["wrapper_data"] as $hd){ - if(strpos($hd, "Content-Type") === 0){ - $nt = explode(": ", $hd); - $mime = $nt[1]; - if(strpos($mime, ";") > 0){ - $ms = explode(";", $mime); - $mime = $ms[0]; - } - }else if(strpos($hd, "Content-Disposition") === 0){ - $nn = explode("filename=", $hd); - $fname = str_replace("\"", "", $nn[1]); - } - } - - if($fname == "remote"){ - //parse url if no content-disposition is set - preg_match('@^.*\/(.*\.[a-zA-Z0-9]{0,4})@i', $_GET["remote"], $matches); - if(count($matches) > 0){ - $fname = $matches[1]; - } - } - } - - $tmpf = fopen("php://temp", 'rb+'); - stream_copy_to_stream($rawf, $tmpf); - rewind($tmpf); - fclose($rawf); - } - else - { - $f = $_FILES['files']; - $tmpf = fopen($f['tmp_name'][0], 'rb'); - } - - //Connect to db - $db = new DB(); - - //get file hash - $hc = hash_init('sha256'); - hash_update_stream($hc, $tmpf); - $fh = hash_final($hc); - $response["hash"] = $fh; - rewind($tmpf); - - $response["filename"] = $fname; - - //check for dupes - $f_e = $db->Exists256($fh); - if($f_e->hash160 != NULL) - { - //file already exists - $response["status"] = 200; - $response["publichash"] = $f_e->hash160; - $response["link"] = _SITEURL . $f_e->hash160; - $response["mime"] = $f_e->mime; - - if($isMultipart) { - $response["success"] = true; - $response["files"] = array(array("url" => $response["link"])); - } - } - else - { - /* - //file does not exist - //check clamav - include_once('clamav.php'); - $sr = ScanStream($tmpf, $fsize); - if($sr !== "stream: OK"){ - $discord_data = array("content" => $sr); - include("discord.php"); - }else{ - $response["clamav"] = $sr; - }*/ - - //check with VT (max upload is 32MB) - /*if($fsize < 32 * 1000 * 1000) { - $redis = new Redis(); - $redis->pconnect(_REDIS_SERVER); - - include_once('virustotal.php'); - $vtr = CheckVirusTotalCached($redis, $fh); - if($vtr != null && isset($vtr->response_code) && $vtr->response_code == 0) { - $sr = ScanFile($tmpf); - $discord_data = array("content" => $sr->verbose_msg); - include("discord.php"); - } - }*/ - - //generate public hash - $phc = hash_init(_PUB_HASH); - hash_update($phc, $fh); - $ph = hash_final($phc); - $response["publichash"] = $ph; - - //save to disk - $op = _FILEPATH . $ph; - $fo = fopen($op, 'wb+'); - if($fo !== False){ - //save to db - $f_e = new FileUpload(); - $f_e->hash160 = $ph; - $f_e->hash256 = $fh; - $f_e->mime = $mime; - $f_e->size = $fsize; - $f_e->path = $op; - $f_e->filename = $fname; - - if($db->InsertFile($f_e)) { - stream_copy_to_stream($tmpf, $fo); - fclose($fo); - $discord_data = array("content" => _SITEURL . '#' . $f_e->hash160); - send_discord_msg($discord_data); - - $response["status"] = 200; - $response["link"] = _SITEURL . $f_e->hash160; - $response["mime"] = $mime; - - if($isMultipart) { - $response["success"] = true; - $response["files"] = array(array("url" => $response["link"])); - } - } else { - $response["status"] = 500; - $response["msg"] = "Server error!"; - } - } else { - $response["status"] = 500; - $response["msg"] = "Server error!"; - } - } - //close streams - fclose($tmpf); - } - - //return response - header('Content-Type: application/json'); - echo json_encode($response); -?>