From 5a2708c9808efab7cb2a2378b2c09539e80a90a6 Mon Sep 17 00:00:00 2001 From: Evan Feenstra <evan@evanfeenstra.com> Date: Sun, 1 Sep 2019 11:48:31 -0500 Subject: [PATCH] fix spammer route, add error message if unauthorized --- plugins/ui/files.go | 64 ++++++++++++++++++++++++----------- plugins/ui/src/index.html | 5 ++- plugins/ui/src/js/initials.js | 1 + plugins/ui/src/js/main.js | 18 +++++++--- plugins/ui/src/js/utils.js | 40 +++++++++++++++------- 5 files changed, 90 insertions(+), 38 deletions(-) diff --git a/plugins/ui/files.go b/plugins/ui/files.go index 9af8e513..9bd67d4b 100644 --- a/plugins/ui/files.go +++ b/plugins/ui/files.go @@ -241,7 +241,10 @@ body.fade { <span>Password:</span> <input class="input" placeholder="Username" name="password"> </div> - <button type="submit" class="button is-primary">Login</button> + <button type="submit" :disabled="loginError?true:false" + :class="loginError?'button is-danger':'button is-primary'"> + {{ loginButtonText }} + </button> </form> </div> @@ -452,6 +455,7 @@ Vue.component('empty-icon', { info: {}, selectedTxHash:null, tps:0, + loginError:'', } `, "js/main.js":`new Vue({ @@ -469,9 +473,14 @@ Vue.component('empty-icon', { const formData = new FormData(e.target); const pass = formData.get('password') const user = formData.get('username') - const r = await api.get('login?username='+user+'&password='+pass) - if(r.token){ - this.init() + try{ + const r = await api.get('login?username='+user+'&password='+pass) + if(r.token){ + this.init() + } + }catch(e){ + this.loginError = 'Not Authorized' + setTimeout(()=>this.loginError='',2000) } }, async init() { @@ -499,11 +508,11 @@ Vue.component('empty-icon', { }, footerContainerStyle() { const size = Math.max(window.innerHeight-this.headerSize, 300) - return 'height:calc('+(size-1 )+'px - 3.6rem);' + return 'height:calc('+(size-1)+'px - 3.6rem);' }, startSpam() { console.log('start spam', this.tpsToSpam) - api.get('spammer?cmd=start&tps='+this.tpsToSpam+')') + api.get('spammer?cmd=start&tps='+this.tpsToSpam) }, stopSpam() { console.log('stop spam') @@ -576,6 +585,9 @@ Vue.component('empty-icon', { infoKeys() { return ['TPS', 'Node ID', 'Neighbors', 'Peers', 'Uptime'] }, + loginButtonText() { + return this.loginError || 'Login' + }, infoValues() { const i = this.info return i.id ? [ @@ -922,23 +934,37 @@ const logLevels = [{ const api = { get: async function(u) { const url = this.trim('/'+u) - const r = await fetch(this.addToken(url)) - const j = await r.json() - if(url.startsWith('login') && j.token) { - localStorage.setItem('token', j.token) - await sleep(1) + try{ + const r = await fetch(this.addToken(url)) + const j = await r.json() + if (!(r.status >= 200 && r.status < 300)) { + throw new Error(j) + } + if(url.startsWith('login') && j.token) { + localStorage.setItem('token', j.token) + await sleep(1) + } + return j + } catch(e) { + throw e } - return j }, post: async function(u, data){ const url = this.trim('/'+u) - const r = await fetch(this.addToken(url), { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - data: JSON.stringify(data) - }) - const j = await r.json() - return j + try{ + const r = await fetch(this.addToken(url), { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + data: JSON.stringify(data) + }) + const j = await r.json() + if (!(r.status >= 200 && r.status < 300)) { + throw new Error(j) + } + return j + } catch(e) { + throw e + } }, trim: function(s) { return s.replace(/^\//, ''); diff --git a/plugins/ui/src/index.html b/plugins/ui/src/index.html index 92448db2..b3825fe0 100644 --- a/plugins/ui/src/index.html +++ b/plugins/ui/src/index.html @@ -33,7 +33,10 @@ <span>Password:</span> <input class="input" placeholder="Username" name="password"> </div> - <button type="submit" class="button is-primary">Login</button> + <button type="submit" :disabled="loginError?true:false" + :class="loginError?'button is-danger':'button is-primary'"> + {{ loginButtonText }} + </button> </form> </div> diff --git a/plugins/ui/src/js/initials.js b/plugins/ui/src/js/initials.js index 93157c1a..d059a9d2 100644 --- a/plugins/ui/src/js/initials.js +++ b/plugins/ui/src/js/initials.js @@ -10,4 +10,5 @@ var initialData = { info: {}, selectedTxHash:null, tps:0, + loginError:'', } diff --git a/plugins/ui/src/js/main.js b/plugins/ui/src/js/main.js index c007ef90..17f5a388 100644 --- a/plugins/ui/src/js/main.js +++ b/plugins/ui/src/js/main.js @@ -13,9 +13,14 @@ new Vue({ const formData = new FormData(e.target); const pass = formData.get('password') const user = formData.get('username') - const r = await api.get('login?username='+user+'&password='+pass) - if(r.token){ - this.init() + try{ + const r = await api.get('login?username='+user+'&password='+pass) + if(r.token){ + this.init() + } + }catch(e){ + this.loginError = 'Not Authorized' + setTimeout(()=>this.loginError='',2000) } }, async init() { @@ -43,11 +48,11 @@ new Vue({ }, footerContainerStyle() { const size = Math.max(window.innerHeight-this.headerSize, 300) - return 'height:calc('+(size-1 )+'px - 3.6rem);' + return 'height:calc('+(size-1)+'px - 3.6rem);' }, startSpam() { console.log('start spam', this.tpsToSpam) - api.get('spammer?cmd=start&tps='+this.tpsToSpam+')') + api.get('spammer?cmd=start&tps='+this.tpsToSpam) }, stopSpam() { console.log('stop spam') @@ -120,6 +125,9 @@ new Vue({ infoKeys() { return ['TPS', 'Node ID', 'Neighbors', 'Peers', 'Uptime'] }, + loginButtonText() { + return this.loginError || 'Login' + }, infoValues() { const i = this.info return i.id ? [ diff --git a/plugins/ui/src/js/utils.js b/plugins/ui/src/js/utils.js index d61b55e1..5f99f30f 100644 --- a/plugins/ui/src/js/utils.js +++ b/plugins/ui/src/js/utils.js @@ -36,23 +36,37 @@ const logLevels = [{ const api = { get: async function(u) { const url = this.trim('/'+u) - const r = await fetch(this.addToken(url)) - const j = await r.json() - if(url.startsWith('login') && j.token) { - localStorage.setItem('token', j.token) - await sleep(1) + try{ + const r = await fetch(this.addToken(url)) + const j = await r.json() + if (!(r.status >= 200 && r.status < 300)) { + throw new Error(j) + } + if(url.startsWith('login') && j.token) { + localStorage.setItem('token', j.token) + await sleep(1) + } + return j + } catch(e) { + throw e } - return j }, post: async function(u, data){ const url = this.trim('/'+u) - const r = await fetch(this.addToken(url), { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - data: JSON.stringify(data) - }) - const j = await r.json() - return j + try{ + const r = await fetch(this.addToken(url), { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + data: JSON.stringify(data) + }) + const j = await r.json() + if (!(r.status >= 200 && r.status < 300)) { + throw new Error(j) + } + return j + } catch(e) { + throw e + } }, trim: function(s) { return s.replace(/^\//, ''); -- GitLab