diff options
| author | 8cy <[email protected]> | 2020-05-23 02:24:18 -0700 |
|---|---|---|
| committer | 8cy <[email protected]> | 2020-05-23 02:24:18 -0700 |
| commit | 454825558aef4320c82b3d3148537038364c9427 (patch) | |
| tree | fc8366ce0203fd58bb65d843c04608d25a08ab16 /public | |
| download | strelizia-master.tar.xz strelizia-master.zip | |
Diffstat (limited to 'public')
30 files changed, 1122 insertions, 0 deletions
diff --git a/public/css/style.css b/public/css/style.css new file mode 100644 index 0000000..993811e --- /dev/null +++ b/public/css/style.css @@ -0,0 +1,121 @@ +section#home { + user-select: none; +} + +section#home .link { + user-select: all; +} + +/* ------------------ + HOME +------------------ */ + +section#home #b { + -webkit-animation-delay: 0.5s; + animation-delay: 0.5s; + -webkit-animation-duration: 1.5s; + animation-duration: 1.5s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + -webkit-animation-name: floatUp; + animation-name: floatUp; + -webkit-animation-timing-function: cubic-bezier(0, 0.71, 0.29, 1); + animation-timing-function: cubic-bezier(0, 0.71, 0.29, 1); + border-radius: 24px; + display: inline-block; + height: 240px; + margin-bottom: 40px; + position: relative; + vertical-align: top; + width: 240px; + box-shadow: 0 20px 60px rgba(10, 10, 10, 0.05), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2); +} + +section#home div#dropzone { + border: 1px solid #dbdbdb; + background-color: rgba(0, 0, 0, 0); + border-color: #ff3860; + color: #ff3860; + display: none; + width: 100%; + border-radius: 3px; + box-shadow: none; + height: 2.5em; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + user-select: none; + justify-content: center; + padding-left: .75em; + padding-right: .75em; + text-align: center; + cursor: pointer; +} + +section#home div#uploads, section#home p#tokenContainer, section#home a#panel { display: none; } +section#home div#dropzone:hover { background-color: #ff3860; border-color: #ff3860; color: #fff; } +section#home h3#maxFileSize { font-size: 14px; } +section#home h3#links span { padding-left: 5px; padding-right: 5px; } +section#home img.logo { height: 200px; margin-top: 20px; } +section#home .dz-preview .dz-details { display: flex; } +section#home .dz-preview .dz-details .dz-size, section#home .dz-preview .dz-details .dz-filename { flex: 1; } +section#home .dz-preview img, section#home .dz-preview .dz-success-mark, section#home .dz-preview .dz-error-mark { display: none; } +section#home div#uploads { margin-bottom: 25px; } + +@keyframes floatUp { + 0% { + opacity: 0; + box-shadow: 0 0 0 rgba(10, 10, 10, 0), 0 0 0 rgba(10, 10, 10, 0), 0 0 0 rgba(10, 10, 10, 0); + -webkit-transform: scale(0.86); + transform: scale(0.86); + } + 25% { opacity: 100; } + 67% { + box-shadow: 0 0 0 rgba(10, 10, 10, 0), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2); + -webkit-transform: scale(1); + transform: scale(1); + } + 100% { + box-shadow: 0 20px 60px rgba(10, 10, 10, 0.05), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2); + -webkit-transform: scale(1); + transform: scale(1); + } +} + +/* ------------------ + PANEL +------------------ */ + +section#login input, section#login p.control a.button { + border-left: 0px; + border-top: 0px; + border-right: 0px; + border-radius: 0px; + box-shadow: 0 0 0; +} + +section#login p.control a.button { margin-left: 10px; } +section#login p.control a#loginBtn { border-right: 0px; } +section#login p.control a#registerBtn { border-left: 0px; } + + +section#auth, section#dashboard { display: none } +section#auth input { background: rgba(0, 0, 0, 0); } +section#auth input, section#auth a { + border-left: 0px; + border-top: 0px; + border-right: 0px; + border-radius: 0px; + box-shadow: 0 0 0; +} + +section#dashboard .table { font-size: 12px } +section#dashboard div#table div.column { display:flex; width: 200px; height: 220px; margin: 9px; background: #f9f9f9; overflow: hidden; flex-wrap: wrap; align-items: center; } +section#dashboard div#table div.column a { width: 100%; } +section#dashboard div#table div.column a:first-child { height: 180px; } +section#dashboard div#table div.column a img { width:200px; } + +.select-wrapper { + text-align: center; + margin-bottom: 10px; +} diff --git a/public/images/backup/logo.png b/public/images/backup/logo.png Binary files differnew file mode 100644 index 0000000..96916c0 --- /dev/null +++ b/public/images/backup/logo.png diff --git a/public/images/backup/logo_big.png b/public/images/backup/logo_big.png Binary files differnew file mode 100644 index 0000000..b935a28 --- /dev/null +++ b/public/images/backup/logo_big.png diff --git a/public/images/backup/logo_smol.png b/public/images/backup/logo_smol.png Binary files differnew file mode 100644 index 0000000..94b6797 --- /dev/null +++ b/public/images/backup/logo_smol.png diff --git a/public/images/backup/logo_square.png b/public/images/backup/logo_square.png Binary files differnew file mode 100644 index 0000000..0c296b1 --- /dev/null +++ b/public/images/backup/logo_square.png diff --git a/public/images/fb_share.png b/public/images/fb_share.png Binary files differnew file mode 100644 index 0000000..d5fc25b --- /dev/null +++ b/public/images/fb_share.png diff --git a/public/images/icons/android-chrome-192x192.png b/public/images/icons/android-chrome-192x192.png Binary files differnew file mode 100644 index 0000000..316c49a --- /dev/null +++ b/public/images/icons/android-chrome-192x192.png diff --git a/public/images/icons/android-chrome-384x384.png b/public/images/icons/android-chrome-384x384.png Binary files differnew file mode 100644 index 0000000..d513acc --- /dev/null +++ b/public/images/icons/android-chrome-384x384.png diff --git a/public/images/icons/apple-touch-icon.png b/public/images/icons/apple-touch-icon.png Binary files differnew file mode 100644 index 0000000..080f791 --- /dev/null +++ b/public/images/icons/apple-touch-icon.png diff --git a/public/images/icons/backup/android-chrome-192x192.png b/public/images/icons/backup/android-chrome-192x192.png Binary files differnew file mode 100644 index 0000000..1e77f89 --- /dev/null +++ b/public/images/icons/backup/android-chrome-192x192.png diff --git a/public/images/icons/backup/android-chrome-384x384.png b/public/images/icons/backup/android-chrome-384x384.png Binary files differnew file mode 100644 index 0000000..c07f93c --- /dev/null +++ b/public/images/icons/backup/android-chrome-384x384.png diff --git a/public/images/icons/backup/apple-touch-icon.png b/public/images/icons/backup/apple-touch-icon.png Binary files differnew file mode 100644 index 0000000..3590469 --- /dev/null +++ b/public/images/icons/backup/apple-touch-icon.png diff --git a/public/images/icons/backup/favicon-16x16.png b/public/images/icons/backup/favicon-16x16.png Binary files differnew file mode 100644 index 0000000..bf15749 --- /dev/null +++ b/public/images/icons/backup/favicon-16x16.png diff --git a/public/images/icons/backup/favicon-32x32.png b/public/images/icons/backup/favicon-32x32.png Binary files differnew file mode 100644 index 0000000..e213772 --- /dev/null +++ b/public/images/icons/backup/favicon-32x32.png diff --git a/public/images/icons/backup/favicon.ico b/public/images/icons/backup/favicon.ico Binary files differnew file mode 100644 index 0000000..f18ab34 --- /dev/null +++ b/public/images/icons/backup/favicon.ico diff --git a/public/images/icons/backup/mstile-150x150.png b/public/images/icons/backup/mstile-150x150.png Binary files differnew file mode 100644 index 0000000..a84a7e4 --- /dev/null +++ b/public/images/icons/backup/mstile-150x150.png diff --git a/public/images/icons/backup/safari-pinned-tab.svg b/public/images/icons/backup/safari-pinned-tab.svg new file mode 100644 index 0000000..5c1c698 --- /dev/null +++ b/public/images/icons/backup/safari-pinned-tab.svg @@ -0,0 +1,47 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" + width="16.000000pt" height="16.000000pt" viewBox="0 0 16.000000 16.000000" + preserveAspectRatio="xMidYMid meet"> +<metadata> +Created by potrace 1.11, written by Peter Selinger 2001-2013 +</metadata> +<g transform="translate(0.000000,16.000000) scale(0.003765,-0.003765)" +fill="#000000" stroke="none"> +<path d="M2397 4143 c-3 -3 -19 -7 -34 -8 -162 -16 -259 -56 -351 -144 -65 +-64 -123 -152 -156 -239 -22 -61 -27 -80 -40 -148 -6 -29 -18 -161 -20 -209 +-1 -40 -2 -40 -81 -80 l-81 -40 58 -50 c32 -28 70 -55 85 -62 l28 -11 -25 -10 +-25 -10 29 -13 28 -13 -6 -106 c-3 -58 -7 -114 -9 -125 -3 -11 -8 -45 -11 -76 +-4 -31 -9 -67 -11 -80 -3 -13 -12 -60 -20 -104 -21 -108 -99 -327 -177 -497 +-29 -64 -32 -67 -62 -64 -17 2 -36 4 -42 5 -25 2 -95 171 -108 259 -9 62 -14 +55 -73 -98 -35 -89 -48 -133 -59 -190 -2 -14 -6 -34 -9 -45 -21 -99 -22 -255 +-2 -370 8 -44 14 -81 13 -82 -5 -6 -97 76 -131 117 -47 57 -97 151 -111 205 +-30 123 -36 217 -19 300 8 41 -6 24 -48 -60 -36 -72 -72 -169 -81 -221 -3 -16 +-10 -44 -16 -63 -10 -36 -7 -255 4 -304 4 -16 15 -51 26 -79 11 -28 17 -54 15 +-58 -14 -22 -177 11 -235 48 l-25 16 16 -25 c27 -42 141 -127 204 -153 33 -14 +86 -32 117 -41 48 -14 58 -20 63 -44 3 -15 31 -65 61 -112 31 -46 68 -109 84 +-139 15 -31 41 -67 57 -80 16 -14 45 -45 64 -70 19 -25 37 -47 40 -50 3 -3 34 +-43 69 -90 109 -146 240 -259 412 -353 25 -14 65 -38 89 -53 48 -30 175 -79 +229 -88 117 -19 211 -37 250 -49 47 -14 85 -14 160 -3 131 21 171 87 171 281 +-1 73 -3 93 -12 110 -4 6 -9 22 -13 37 -6 26 -54 109 -159 278 -26 41 -55 85 +-63 97 -14 20 -14 23 -2 23 9 0 32 -21 52 -47 99 -128 366 -377 506 -473 12 +-8 43 -30 68 -49 38 -29 57 -35 116 -41 128 -13 166 5 214 103 81 161 76 270 +-19 438 -23 41 -45 76 -48 79 -3 3 -31 34 -61 70 -30 36 -57 67 -61 70 -15 13 +-169 222 -169 231 0 6 7 23 15 38 26 51 56 185 61 271 3 47 7 93 9 103 5 27 +-8 20 -38 -22 -15 -22 -45 -54 -67 -71 l-40 -32 -1 89 c0 48 -3 81 -7 73 -11 +-25 -41 -64 -46 -59 -2 2 -7 33 -11 69 -7 65 -7 66 22 80 15 7 30 14 33 14 3 +1 26 13 52 28 56 34 121 97 157 153 22 35 30 41 47 34 47 -17 103 -115 91 +-160 -6 -22 8 -26 17 -4 3 8 8 36 12 63 10 79 -28 143 -98 165 -15 5 -15 10 +-4 49 31 104 15 279 -35 384 -19 40 -29 78 -29 107 0 48 -12 61 -43 45 -9 -5 +-23 -5 -31 -1 -31 19 -74 61 -91 91 -13 21 -35 38 -62 48 -24 10 -42 22 -40 +28 3 6 9 10 15 9 9 -2 52 84 67 137 4 14 25 42 47 62 22 20 37 42 33 48 -3 5 +-11 7 -17 4 -6 -4 -6 1 1 14 6 12 16 24 22 27 6 4 23 25 39 47 29 40 29 41 10 +57 -17 13 -18 22 -11 54 5 21 7 50 6 65 -2 15 -6 52 -9 82 -10 114 -77 279 +-158 387 -46 63 -167 162 -247 202 -97 49 -263 91 -276 70 -4 -5 -13 -5 -24 1 +-10 5 -21 7 -24 3z"/> +<path d="M3111 3011 c-13 -13 -21 -35 -22 -58 0 -21 -1 -53 -2 -71 -1 -17 2 +-32 6 -32 4 0 29 11 55 24 74 37 87 86 27 98 -12 2 -19 10 -17 20 1 8 -4 21 +-12 27 -12 10 -19 8 -35 -8z"/> +</g> +</svg> diff --git a/public/images/icons/browserconfig.xml b/public/images/icons/browserconfig.xml new file mode 100644 index 0000000..f95ebd2 --- /dev/null +++ b/public/images/icons/browserconfig.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<browserconfig> + <msapplication> + <tile> + <square150x150logo src="/images/icons/mstile-150x150.png?v=XBreOJMe24"/> + <TileColor>#00aba9</TileColor> + </tile> + </msapplication> +</browserconfig> diff --git a/public/images/icons/favicon-16x16.png b/public/images/icons/favicon-16x16.png Binary files differnew file mode 100644 index 0000000..3ffa533 --- /dev/null +++ b/public/images/icons/favicon-16x16.png diff --git a/public/images/icons/favicon-32x32.png b/public/images/icons/favicon-32x32.png Binary files differnew file mode 100644 index 0000000..6896449 --- /dev/null +++ b/public/images/icons/favicon-32x32.png diff --git a/public/images/icons/favicon.ico b/public/images/icons/favicon.ico Binary files differnew file mode 100644 index 0000000..39ac387 --- /dev/null +++ b/public/images/icons/favicon.ico diff --git a/public/images/icons/manifest.json b/public/images/icons/manifest.json new file mode 100644 index 0000000..c5e008f --- /dev/null +++ b/public/images/icons/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "strelizia", + "icons": [ + { + "src": "/images/icons/android-chrome-192x192.png?v=XBreOJMe24", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/images/icons/android-chrome-384x384.png?v=XBreOJMe24", + "sizes": "384x384", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +}
\ No newline at end of file diff --git a/public/images/logo.png b/public/images/logo.png Binary files differnew file mode 100644 index 0000000..124ca01 --- /dev/null +++ b/public/images/logo.png diff --git a/public/images/logo_big.png b/public/images/logo_big.png Binary files differnew file mode 100644 index 0000000..ad81912 --- /dev/null +++ b/public/images/logo_big.png diff --git a/public/images/logo_smol.png b/public/images/logo_smol.png Binary files differnew file mode 100644 index 0000000..0ca96d2 --- /dev/null +++ b/public/images/logo_smol.png diff --git a/public/images/logo_square.png b/public/images/logo_square.png Binary files differnew file mode 100644 index 0000000..cd840d1 --- /dev/null +++ b/public/images/logo_square.png diff --git a/public/js/auth.js b/public/js/auth.js new file mode 100644 index 0000000..1ae9e4d --- /dev/null +++ b/public/js/auth.js @@ -0,0 +1,56 @@ +var page = {}; + +page.do = function(dest){ + + var user = document.getElementById('user').value; + var pass = document.getElementById('pass').value; + + if(user === undefined || user === null || user === '') + return swal('Error', 'You need to specify a username', 'error'); + if(pass === undefined || pass === null || pass === '') + return swal('Error', 'You need to specify a username', 'error'); + + axios.post('/api/' + dest, { + username: user, + password: pass + }) + .then(function (response) { + + if(response.data.success === false) + return swal('Error', response.data.description, 'error'); + + localStorage.token = response.data.token; + window.location = '/dashboard'; + + }) + .catch(function (error) { + return swal('An error ocurred', 'There was an error with the request, please check the console for more information.', 'error'); + console.log(error); + }); +}; + +page.verify = function(){ + page.token = localStorage.token; + if(page.token === undefined) return; + + axios.post('/api/tokens/verify', { + token: page.token + }) + .then(function (response) { + + if(response.data.success === false) + return swal('Error', response.data.description, 'error'); + + window.location = '/dashboard'; + + }) + .catch(function (error) { + return swal('An error ocurred', 'There was an error with the request, please check the console for more information.', 'error'); + console.log(error); + }); + +}; + +window.onload = function () { + page.verify(); +};
\ No newline at end of file diff --git a/public/js/dashboard.js b/public/js/dashboard.js new file mode 100644 index 0000000..b080402 --- /dev/null +++ b/public/js/dashboard.js @@ -0,0 +1,620 @@ +let panel = {}; + +panel.page; +panel.username; +panel.token = localStorage.token; +panel.filesView = localStorage.filesView; + +panel.preparePage = function(){ + if(!panel.token) return window.location = '/auth'; + panel.verifyToken(panel.token, true); +}; + +panel.verifyToken = function(token, reloadOnError){ + if(reloadOnError === undefined) + reloadOnError = false; + + axios.post('/api/tokens/verify', { + token: token + }) + .then(function (response) { + + if(response.data.success === false){ + swal({ + title: "An error ocurred", + text: response.data.description, + type: "error" + }, function(){ + if(reloadOnError){ + localStorage.removeItem("token"); + location.location = '/auth'; + } + }); + return; + } + + axios.defaults.headers.common['token'] = token; + localStorage.token = token; + panel.token = token; + panel.username = response.data.username; + return panel.prepareDashboard(); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + +}; + +panel.prepareDashboard = function(){ + panel.page = document.getElementById('page'); + document.getElementById('auth').style.display = 'none'; + document.getElementById('dashboard').style.display = 'block'; + + document.getElementById('itemUploads').addEventListener('click', function(){ + panel.setActiveMenu(this); + }); + + document.getElementById('itemManageGallery').addEventListener('click', function(){ + panel.setActiveMenu(this); + }); + + document.getElementById('itemTokens').addEventListener('click', function(){ + panel.setActiveMenu(this); + }); + + document.getElementById('itemPassword').addEventListener('click', function(){ + panel.setActiveMenu(this); + }); + + document.getElementById('itemLogout').innerHTML = `Logout ( ${panel.username} )`; + + panel.getAlbumsSidebar(); +}; + +panel.logout = function(){ + localStorage.removeItem("token"); + location.reload('/'); +}; + +panel.getUploads = function(album = undefined, page = undefined){ + + if(page === undefined) page = 0; + + let url = '/api/uploads/' + page; + if(album !== undefined) + url = '/api/album/' + album + '/' + page; + + axios.get(url).then(function (response) { + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + var prevPage = 0; + var nextPage = page + 1; + + if(response.data.files.length < 25) + nextPage = page; + + if(page > 0) prevPage = page - 1; + + panel.page.innerHTML = ''; + var container = document.createElement('div'); + var pagination = `<nav class="pagination is-centered"> + <a class="pagination-previous" onclick="panel.getUploads(${album}, ${prevPage} )">Previous</a> + <a class="pagination-next" onclick="panel.getUploads(${album}, ${nextPage} )">Next page</a> + </nav>`; + var listType = ` + <div class="columns"> + <div class="column"> + <a class="button is-small is-outlined is-danger" title="List view" onclick="panel.setFilesView('list', ${album}, ${page})"> + <span class="icon is-small"> + <i class="fa fa-list-ul"></i> + </span> + </a> + <a class="button is-small is-outlined is-danger" title="List view" onclick="panel.setFilesView('thumbs', ${album}, ${page})"> + <span class="icon is-small"> + <i class="fa fa-th-large"></i> + </span> + </a> + </div> + </div>`; + + if(panel.filesView === 'thumbs'){ + + container.innerHTML = ` + ${pagination} + <hr> + ${listType} + <div class="columns is-multiline is-mobile" id="table"> + + </div> + ${pagination} + `; + + panel.page.appendChild(container); + var table = document.getElementById('table'); + + for(var item of response.data.files){ + + var div = document.createElement('div'); + div.className = "column is-2"; + if(item.thumb !== undefined) + div.innerHTML = `<a href="${item.file}" target="_blank"><img src="${item.thumb}"/></a><a class="button is-small is-danger is-outlined" title="Delete file" onclick="panel.deleteFile(${item.id})"><span class="icon is-small"><i class="fa fa-trash-o"></i></span></a>`; + else + div.innerHTML = `<a href="${item.file}" target="_blank"><h1 class="title">.${item.file.split('.').pop()}</h1></a><a class="button is-small is-danger is-outlined" title="Delete file" onclick="panel.deleteFile(${item.id})"><span class="icon is-small"><i class="fa fa-trash-o"></i></span></a>`; + table.appendChild(div); + + } + + }else{ + + var albumOrUser = 'Album'; + if(panel.username === 'root') + albumOrUser = 'User'; + + container.innerHTML = ` + ${pagination} + <hr> + ${listType} + <table class="table is-striped is-narrow is-left"> + <thead> + <tr> + <th>File</th> + <th>${albumOrUser}</th> + <th>Date</th> + <th></th> + </tr> + </thead> + <tbody id="table"> + </tbody> + </table> + <hr> + ${pagination} + `; + + panel.page.appendChild(container); + var table = document.getElementById('table'); + + for(var item of response.data.files){ + + var tr = document.createElement('tr'); + + var displayAlbumOrUser = item.album; + if(panel.username === 'root'){ + displayAlbumOrUser = ''; + if(item.username !== undefined) + displayAlbumOrUser = item.username; + } + + tr.innerHTML = ` + <tr> + <th><a href="${item.file}" target="_blank">${item.file}</a></th> + <th>${displayAlbumOrUser}</th> + <td>${item.date}</td> + <td> + <a class="button is-small is-danger is-outlined" title="Delete album" onclick="panel.deleteFile(${item.id})"> + <span class="icon is-small"> + <i class="fa fa-trash-o"></i> + </span> + </a> + </td> + </tr> + `; + + table.appendChild(tr); + } + } + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + +}; + +panel.setFilesView = function(view, album, page){ + localStorage.filesView = view; + panel.filesView = view; + panel.getUploads(album, page); +}; + +panel.deleteFile = function(id){ + swal({ + title: "Are you sure?", + text: "You wont be able to recover the file!", + type: "warning", + showCancelButton: true, + confirmButtonColor: "#ff3860", + confirmButtonText: "Yes, delete it!", + closeOnConfirm: false + }, + function(){ + + axios.post('/api/upload/delete', { + id: id + }) + .then(function (response) { + + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + swal("Deleted!", "The file has been deleted.", "success"); + panel.getUploads(); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + + } + ); +}; + +panel.getAlbums = function(){ + + axios.get('/api/albums').then(function (response) { + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + panel.page.innerHTML = ''; + var container = document.createElement('div'); + container.className = "container"; + container.innerHTML = ` + <h2 class="subtitle">Create new album</h2> + + <p class="control has-addons has-addons-centered"> + <input id="albumName" class="input" type="text" placeholder="Name"> + <a id="submitAlbum" class="button is-primary">Submit</a> + </p> + + <h2 class="subtitle">List of albums</h2> + + <table class="table is-striped is-narrow"> + <thead> + <tr> + <th>Name</th> + <th>Files</th> + <th>Created At</th> + <th>Public link</th> + <th></th> + </tr> + </thead> + <tbody id="table"> + </tbody> + </table>`; + + panel.page.appendChild(container); + var table = document.getElementById('table'); + + for(var item of response.data.albums){ + + var tr = document.createElement('tr'); + tr.innerHTML = ` + <tr> + <th>${item.name}</th> + <th>${item.files}</th> + <td>${item.date}</td> + <td><a href="${item.identifier}" target="_blank">Album link</a></td> + <td> + <a class="button is-small is-primary is-outlined" title="Edit name" onclick="panel.renameAlbum(${item.id})"> + <span class="icon is-small"> + <i class="fa fa-pencil"></i> + </span> + </a> + <a class="button is-small is-danger is-outlined" title="Delete album" onclick="panel.deleteAlbum(${item.id})"> + <span class="icon is-small"> + <i class="fa fa-trash-o"></i> + </span> + </a> + </td> + </tr> + `; + + table.appendChild(tr); + } + + document.getElementById('submitAlbum').addEventListener('click', function(){ + panel.submitAlbum(); + }); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + +}; + +panel.renameAlbum = function(id){ + + swal({ + title: "Rename album", + text: "New name you want to give the album:", + type: "input", + showCancelButton: true, + closeOnConfirm: false, + animation: "slide-from-top", + inputPlaceholder: "My super album" + },function(inputValue){ + if (inputValue === false) return false; + if (inputValue === "") { + swal.showInputError("You need to write something!"); + return false; + } + + axios.post('/api/albums/rename', { + id: id, + name: inputValue + }) + .then(function (response) { + + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else if(response.data.description === 'Name already in use') swal.showInputError("That name is already in use!"); + else swal("An error ocurred", response.data.description, "error"); + return; + } + + swal("Success!", "Your album was renamed to: " + inputValue, "success"); + panel.getAlbumsSidebar(); + panel.getAlbums(); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + + }); + +}; + +panel.deleteAlbum = function(id){ + swal({ + title: "Are you sure?", + text: "This won't delete your files, only the album!", + type: "warning", + showCancelButton: true, + confirmButtonColor: "#ff3860", + confirmButtonText: "Yes, delete it!", + closeOnConfirm: false + }, + function(){ + + axios.post('/api/albums/delete', { + id: id + }) + .then(function (response) { + + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + swal("Deleted!", "Your album has been deleted.", "success"); + panel.getAlbumsSidebar(); + panel.getAlbums(); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + + } + ); + +}; + +panel.submitAlbum = function(){ + + axios.post('/api/albums', { + name: document.getElementById('albumName').value + }) + .then(function (response) { + + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + swal("Woohoo!", "Album was added successfully", "success"); + panel.getAlbumsSidebar(); + panel.getAlbums(); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + +}; + +panel.getAlbumsSidebar = function(){ + + axios.get('/api/albums/sidebar') + .then(function (response) { + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + var albumsContainer = document.getElementById('albumsContainer'); + albumsContainer.innerHTML = ''; + + if(response.data.albums === undefined) return; + + for(var album of response.data.albums){ + + li = document.createElement('li'); + a = document.createElement('a'); + a.id = album.id; + a.innerHTML = album.name; + + a.addEventListener('click', function(){ + panel.getAlbum(this); + }); + + li.appendChild(a); + albumsContainer.appendChild(li); + } + + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + +}; + +panel.getAlbum = function(item){ + panel.setActiveMenu(item); + panel.getUploads(item.id); +}; + +panel.changeToken = function(){ + + axios.get('/api/tokens') + .then(function (response) { + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + panel.page.innerHTML = ''; + var container = document.createElement('div'); + container.className = "container"; + container.innerHTML = ` + <h2 class="subtitle">Manage your token</h2> + + <label class="label">Your current token:</label> + <p class="control has-addons"> + <input id="token" readonly class="input is-expanded" type="text" placeholder="Your token" value="${response.data.token}"> + <a id="getNewToken" class="button is-primary">Request new token</a> + </p> + `; + + panel.page.appendChild(container); + + document.getElementById('getNewToken').addEventListener('click', function(){ + panel.getNewToken(); + }); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + +}; + +panel.getNewToken = function(){ + + axios.post('/api/tokens/change') + .then(function (response) { + + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + swal({ + title: "Woohoo!", + text: 'Your token was changed successfully.', + type: "success" + }, function(){ + localStorage.token = response.data.token; + location.reload(); + }); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + +}; + +panel.changePassword = function(){ + + panel.page.innerHTML = ''; + var container = document.createElement('div'); + container.className = "container"; + container.innerHTML = ` + <h2 class="subtitle">Change your password</h2> + + <label class="label">New password:</label> + <p class="control has-addons"> + <input id="password" class="input is-expanded" type="password" placeholder="Your new password"> + </p> + <label class="label">Confirm password:</label> + <p class="control has-addons"> + <input id="passwordConfirm" class="input is-expanded" type="password" placeholder="Verify your new password"> + <a id="sendChangePassword" class="button is-primary">Set new password</a> + </p> + `; + + panel.page.appendChild(container); + + document.getElementById('sendChangePassword').addEventListener('click', function(){ + if (document.getElementById('password').value === document.getElementById('passwordConfirm').value) { + panel.sendNewPassword(document.getElementById('password').value); + } else { + swal({ + title: "Password mismatch!", + text: 'Your passwords do not match, please try again.', + type: "error" + }, function() { + panel.changePassword(); + }); + } + }); +}; + +panel.sendNewPassword = function(pass){ + + axios.post('/api/password/change', {password: pass}) + .then(function (response) { + + if(response.data.success === false){ + if(response.data.description === 'No token provided') return panel.verifyToken(panel.token); + else return swal("An error ocurred", response.data.description, "error"); + } + + swal({ + title: "Woohoo!", + text: 'Your password was changed successfully.', + type: "success" + }, function(){ + location.reload(); + }); + + }) + .catch(function (error) { + return swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + console.log(error); + }); + +}; + +panel.setActiveMenu = function(item){ + var menu = document.getElementById('menu'); + var items = menu.getElementsByTagName('a'); + for(var i = 0; i < items.length; i++) + items[i].className = ""; + + item.className = 'is-active'; +}; + +window.onload = function () { + panel.preparePage(); +}; diff --git a/public/js/home.js b/public/js/home.js new file mode 100644 index 0000000..0f5b1ee --- /dev/null +++ b/public/js/home.js @@ -0,0 +1,226 @@ +var upload = {}; + +upload.isPrivate = true; +upload.token = localStorage.token; +upload.maxFileSize; +// add the album var to the upload so we can store the album id in there +upload.album; +upload.myDropzone; + +upload.checkIfPublic = function(){ + axios.get('/api/check') + .then(function (response) { + upload.isPrivate= response.data.private; + upload.maxFileSize = response.data.maxFileSize; + upload.preparePage(); + }) + .catch(function (error) { + swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + return console.log(error); + }); +} + +upload.preparePage = function(){ + if(!upload.isPrivate) return upload.prepareUpload(); + if(!upload.token) return document.getElementById('loginToUpload').style.display = 'inline-flex'; + upload.verifyToken(upload.token, true); +}; + +upload.verifyToken = function(token, reloadOnError){ + if(reloadOnError === undefined) + reloadOnError = false; + + axios.post('/api/tokens/verify', { + token: token + }) + .then(function (response) { + + if(response.data.success === false){ + swal({ + title: "An error ocurred", + text: response.data.description, + type: "error" + }, function(){ + if(reloadOnError){ + localStorage.removeItem("token"); + location.reload(); + } + }); + return; + } + + localStorage.token = token; + upload.token = token; + return upload.prepareUpload(); + + }) + .catch(function (error) { + swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + return console.log(error); + }); + +}; + +upload.prepareUpload = function(){ + // I think this fits best here because we need to check for a valid token before we can get the albums + if (upload.token) { + var select = document.getElementById('albumSelect'); + + select.addEventListener('change', function() { + upload.album = select.value; + }); + + axios.get('/api/albums', { headers: { token: upload.token }}) + .then(function(res) { + var albums = res.data.albums; + + // if the user doesn't have any albums we don't really need to display + // an album selection + if (albums.length === 0) return; + + // loop through the albums and create an option for each album + for (var i = 0; i < albums.length; i++) { + var opt = document.createElement('option'); + opt.value = albums[i].id; + opt.innerHTML = albums[i].name; + select.appendChild(opt); + } + // display the album selection + document.getElementById('albumDiv').style.display = 'block'; + }) + .catch(function(e) { + swal("An error ocurred", 'There was an error with the request, please check the console for more information.', "error"); + return console.log(e); + }); + } + + div = document.createElement('div'); + div.id = 'dropzone'; + div.innerHTML = 'Click here or drag and drop files'; + div.style.display = 'flex'; + + $.getJSON("../json/quotes.json", (data) => { + var items = []; + let quoteNum = Math.floor(Math.random() * data.length); + document.getElementById('quotes').innerHTML = data[quoteNum]; + }); + + document.getElementById('maxFileSize').innerHTML = 'Maximum upload size per file is 1024TB' /*+ upload.maxFileSize*/; + document.getElementById('loginToUpload').style.display = 'none'; + + if(upload.token === undefined) + document.getElementById('loginLinkText').innerHTML = 'Create an account and keep track of your uploads'; + + document.getElementById('uploadContainer').appendChild(div); + + upload.prepareDropzone(); + +}; + +upload.prepareDropzone = function(){ + var previewNode = document.querySelector('#template'); + previewNode.id = ''; + var previewTemplate = previewNode.parentNode.innerHTML; + previewNode.parentNode.removeChild(previewNode); + + var dropzone = new Dropzone('div#dropzone', { + url: '/api/upload', + paramName: 'files[]', + maxFilesize: upload.maxFileSize.slice(0, -2), + parallelUploads: 2, + uploadMultiple: false, + previewsContainer: 'div#uploads', + previewTemplate: previewTemplate, + createImageThumbnails: false, + maxFiles: 1000, + autoProcessQueue: true, + headers: { + 'token': upload.token + }, + init: function() { + upload.myDropzone = this; + this.on('addedfile', function(file) { + document.getElementById('uploads').style.display = 'block'; + }); + // add the selected albumid, if an album is selected, as a header + this.on('sending', function(file, xhr) { + if (upload.album) { + xhr.setRequestHeader('albumid', upload.album); + } + }); + } + }); + + // Update the total progress bar + dropzone.on('uploadprogress', function(file, progress) { + file.previewElement.querySelector('.progress').setAttribute('value', progress); + file.previewElement.querySelector('.progress').innerHTML = progress + '%'; + }); + + dropzone.on('success', function(file, response) { + + // Handle the responseText here. For example, add the text to the preview element: + + if (response.success === false) { + var p = document.createElement('p'); + p.innerHTML = response.description; + file.previewTemplate.querySelector('.link').appendChild(p); + } + + if (response.files[0].url) { + a = document.createElement('a'); + a.href = response.files[0].url; + a.target = '_blank'; + a.innerHTML = response.files[0].url; + file.previewTemplate.querySelector('.link').appendChild(a); + + file.previewTemplate.querySelector('.progress').style.display = 'none'; + } + + }); + + upload.prepareShareX(); +}; + +upload.prepareShareX = function(){ + if (upload.token) { + var sharex_element = document.getElementById("ShareX"); + var sharex_file = "{\r\n\ + \"Name\": \"" + location.hostname + "\",\r\n\ + \"DestinationType\": \"ImageUploader, FileUploader\",\r\n\ + \"RequestType\": \"POST\",\r\n\ + \"RequestURL\": \"" + location.origin + "/api/upload\",\r\n\ + \"FileFormName\": \"files[]\",\r\n\ + \"Headers\": {\r\n\ + \"token\": \"" + upload.token + "\"\r\n\ + },\r\n\ + \"ResponseType\": \"Text\",\r\n\ + \"URL\": \"$json:files[0].url$\",\r\n\ + \"ThumbnailURL\": \"$json:files[0].url$\"\r\n\ +}"; + var sharex_blob = new Blob([sharex_file], {type: "application/octet-binary"}); + sharex_element.setAttribute("href", URL.createObjectURL(sharex_blob)); + sharex_element.setAttribute("download", location.hostname + ".sxcu"); + } +}; + +//Handle image paste event +window.addEventListener('paste', function(event) { + var items = (event.clipboardData || event.originalEvent.clipboardData).items; + for (index in items) { + var item = items[index]; + if (item.kind === 'file') { + var blob = item.getAsFile(); + console.log(blob.type); + var file = new File([blob], "pasted-image."+blob.type.match(/(?:[^\/]*\/)([^;]*)/)[1]); + file.type = blob.type; + console.log(file); + upload.myDropzone.addFile(file); + } + } +}); + +window.onload = function () { + upload.checkIfPublic(); +}; + diff --git a/public/json/quotes.json b/public/json/quotes.json new file mode 100644 index 0000000..9c82bca --- /dev/null +++ b/public/json/quotes.json @@ -0,0 +1,25 @@ +[ + "gang shit bitch", + "sin is a loser", + "why are u even on here???", + "gang gang", + "uwu", + "gang shit darling", + "gang gang darling", + "wtf", + "its one of you slipsteam kids reading this isn't it?", + "zero two gang uwu", + "fbi ain't got shit on this", + "if u the fbi please go away", + "~uwu", + "fbi pwease go away ~uwu", + "please don't tell me its one of you slipstream kids", + "u want an invite don't you", + "whats up normie", + "hello no name", + "whats up no name", + "oh look, its another no namer", + "hi newfag", + "why u snoopin", + "you will never amount to anything" +]
\ No newline at end of file |