4
1
mirror of https://github.com/Qortal/qortal-ui.git synced 2025-02-11 17:55:51 +00:00

Add lock screens

This commit is contained in:
AlphaX-Projects 2023-06-27 17:53:44 +02:00
parent 8bfc0a850c
commit bdf68eeea2
5 changed files with 1305 additions and 70 deletions

View File

@ -4,20 +4,26 @@ import { store } from '../store.js'
import { Epml } from '../epml.js'
import { addTradeBotRoutes } from '../tradebot/addTradeBotRoutes.js'
import { get, translate, translateUnsafeHTML } from 'lit-translate'
import localForage from "localforage";
import localForage from 'localforage'
import { encryptData, decryptData } from '../lockScreen.js'
import { setChatLastSeen } from '../redux/app/app-actions.js'
const chatLastSeen = localForage.createInstance({
name: "chat-last-seen",
})
import '@material/mwc-button'
import '@material/mwc-icon'
import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/paper-progress/paper-progress.js'
import '@polymer/paper-dialog/paper-dialog.js'
import '@polymer/iron-icons/iron-icons.js'
import '@polymer/app-layout/app-layout.js'
import '@polymer/paper-ripple'
import '@vaadin/button'
import '@vaadin/icon'
import '@vaadin/icons'
import '@vaadin/password-field'
import '@vaadin/text-field'
import '@vaadin/tooltip'
@ -35,7 +41,6 @@ import '../functional-components/side-menu.js'
import '../functional-components/side-menu-item.js'
import './start-minting.js'
import './notification-view/notification-bell.js'
import { setChatLastSeen } from '../redux/app/app-actions.js'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
@ -111,7 +116,16 @@ class AppView extends connect(store)(LitElement) {
botDgbBuyAtAddress: { type: String },
botRvnBuyAtAddress: { type: String },
botArrrBuyAtAddress: { type: String },
balanceTicker: { type: String }
balanceTicker: { type: String },
salt: { type: String },
storageData: { type: String },
lockScreenPass: { type: String },
lockScreenSet: { type: String },
lockPass: { type: String },
lockSet: { type: String },
myLockScreenPass: { type: String },
myLockScreenSet: { type: String },
helperMessage: { type: String }
}
}
@ -347,6 +361,65 @@ class AppView extends connect(store)(LitElement) {
padding-top: 5px;
padding-bottom: 5px;
}
.red {
--mdc-theme-primary: #C6011F;
}
.setpass-wrapper {
width: 100%;
min-width: 400px;
max-width: 450px;
text-align: center;
background: var(--white);
border: 1px solid var(--black);
border-radius: 15px;
padding: 10px 10px 0px;
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
}
.lock-wrapper {
width: 100%;
height: 100%;
min-width: 600px;
max-width: 600px;
min-height: 400px;
max-height: 400px;
text-align: center;
background: url("/img/qortal-lock.jpg");
border: 1px solid var(--black);
border-radius: 25px;
padding: 10px 10px 0px;
}
.text-wrapper {
width: 100%;
height: 100%;
min-width: 280px;
max-width: 280px;
min-height: 64px;
max-height: 64px;
text-align: center;
margin-left: 35px;
margin-top: 125px;
overflow: hidden;
}
.lock-title-white {
font-family: 'magistralbold';
font-weight: 700;
font-size: 26px;
line-height: 32px;
color: #ffffff;
}
.lock-title-red {
font-family: 'magistralbold';
font-weight: 700;
font-size: 26px;
line-height: 32px;
color: #df3636;
}
`
]
}
@ -426,6 +499,15 @@ class AppView extends connect(store)(LitElement) {
<div class="balancelist"></div>
</div>
`
this.salt = ''
this.storageData = ''
this.lockScreenPass = ''
this.lockScreenSet = ''
this.lockPass = ''
this.lockSet = ''
this.myLockScreenPass = ''
this.myLockScreenSet = ''
this.helperMessage = ''
}
render() {
@ -484,6 +566,8 @@ class AppView extends connect(store)(LitElement) {
<div>&nbsp;&nbsp;&nbsp;&nbsp;</div>
<theme-toggle></theme-toggle>
<div>&nbsp;&nbsp;</div>
${this.renderLockButton()}
<div>&nbsp;&nbsp;</div>
<search-modal></search-modal>
<div>&nbsp;&nbsp;</div>
<div style="display: inline;">
@ -504,6 +588,59 @@ class AppView extends connect(store)(LitElement) {
<user-info-view></user-info-view>
<user-settings></user-settings>
<logout-view></logout-view>
<paper-dialog class="setpass-wrapper" id="setLockScreenPass" modal>
<div style="text-align: center;">
<h2 style="color: var(--black);">Qortal UI ${translate("login.lp1")}</h2>
<hr>
</div>
<div style="text-align: center;">
<h3 style="color: var(--black);">${translate("login.lp2")}</h3>
<h4 style="color: var(--black);">${translate("login.lp3")}</h4>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.password")}" id="lockPassword" autofocus></vaadin-password-field>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.confirmpass")}" id="lockPasswordConfirm"></vaadin-password-field>
</div>
<div style="display: flex; justify-content: space-between;">
<mwc-button class="red" @click="${() => this.closeSetScreenLockPass()}">${translate("login.lp4")}</mwc-button>
<mwc-button @click="${() => this.checkPass()}">${translate("login.lp5")}</mwc-button>
</div>
</paper-dialog>
<paper-dialog class="setpass-wrapper" id="extraConfirmPass" modal>
<div style="text-align: center;">
<h2 style="color: var(--black);">Qortal UI ${translate("login.lp1")}</h2>
<hr>
</div>
<div style="text-align: center;">
<h3 style="color: var(--black);">${translate("login.lessthen8")}</h3>
</div>
<div style="display: flex; justify-content: space-between;">
<mwc-button class="red" @click="${() => this.closExtraConfirmPass()}">${translate("login.lp4")}</mwc-button>
<mwc-button @click="${() => this.setNewScreenPass()}">${translate("login.lp5")}</mwc-button>
</div>
</paper-dialog>
<paper-dialog class="lock-wrapper" id="lockScreenActive" modal>
<div class="text-wrapper">
<span class="lock-title-white">UI </span><br/>
<span class="lock-title-white">${translate("login.lp9")} </span>
<span class="lock-title-red">${translate("login.lp10")}</span>
</div>
<div style="display:flex; margin-top: 5px;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 45%;" label="${translate("login.password")}" id="unlockPassword" @keydown="${this.passKeyListener}" autofocus>
<div slot="helper">
${this.helperMessage}
</div>
</vaadin-password-field>
</div>
<div style="display: flex; margin-top: 35px;">
<mwc-button dense unelevated label="${translate("login.lp7")}" icon="lock_open" @click="${() => this.closeLockScreenActive()}"></mwc-button>
</div>
</paper-dialog>
`
}
@ -512,6 +649,44 @@ class AppView extends connect(store)(LitElement) {
addTradeBotRoutes(parentEpml)
parentEpml.imReady()
this.helperMessage = this.renderHelperPass()
this.salt = ''
this.salt = Base58.encode(store.getState().app.wallet._addresses[0].keyPair.privateKey)
this.storageData = ''
this.storageData = store.getState().app.selectedAddress.address
this.lockScreenPass = ''
this.lockScreenPass = 'lockScreenPass-' + this.storageData
this.lockScreenSet = ''
this.lockScreenSet = 'lockScreenSet-' + this.storageData
this.lockPass = ''
this.lockPass = encryptData(false, this.salt)
this.lockSet = ''
this.lockSet = encryptData(false, this.salt)
if (localStorage.getItem(this.lockScreenPass) === null && localStorage.getItem(this.lockScreenSet) === null) {
localStorage.setItem(this.lockScreenPass, this.lockPass)
localStorage.setItem(this.lockScreenSet, this.lockSet)
this.myLockScreenPass = ''
this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt)
this.myLockScreenSet = ''
this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt)
} else {
this.myLockScreenPass = ''
this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt)
this.myLockScreenSet = ''
this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt)
}
if (this.myLockScreenSet === true) {
this.shadowRoot.getElementById('lockScreenActive').open()
}
var drawerTog = this.shadowRoot.getElementById("mb")
var drawerOut = this.shadowRoot.getElementById("appsidebar")
@ -1566,6 +1741,139 @@ class AppView extends connect(store)(LitElement) {
}
}
renderLockButton() {
if (this.myLockScreenPass === false && this.myLockScreenSet === false) {
return html`
<div style="display: inline;">
<paper-icon-button icon="icons:lock-open" @click=${() => this.openSetScreenLockPass()} title="${translate("login.lp11")}"></paper-icon-button>
</div>
`
} else if (this.myLockScreenSet === false) {
return html`
<div style="display: inline;">
<paper-icon-button icon="icons:lock-open" @click=${() => this.setLockQortal()} title="${translate("login.lp11")}"></paper-icon-button>
</div>
`
} else if (this.myLockScreenSet === true) {
return html`
<div style="display: inline;">
<paper-icon-button icon="icons:lock" title="${translate("login.lp10")}"></paper-icon-button>
</div>
`
}
}
openSetScreenLockPass() {
this.shadowRoot.getElementById('lockPassword').value = ''
this.shadowRoot.getElementById('lockPasswordConfirm').value = ''
this.shadowRoot.getElementById('setLockScreenPass').open()
}
closeSetScreenLockPass() {
this.shadowRoot.getElementById('setLockScreenPass').close()
}
checkPass() {
const password = this.shadowRoot.getElementById('lockPassword').value
const rePassword = this.shadowRoot.getElementById('lockPasswordConfirm').value
if (password === '') {
let snackbar1string = get("login.pleaseenter")
parentEpml.request('showSnackBar', `${snackbar1string}`)
return
}
if (password != rePassword) {
let snackbar2string = get("login.notmatch")
parentEpml.request('showSnackBar', `${snackbar2string}`)
return
}
if (password.length < 8) {
let snackbar3string = get("login.lessthen8")
parentEpml.request('showSnackBar', `${snackbar3string}`)
this.lowPass = ''
this.lowPass = password
this.extraConfirm()
}
if (password.length >= 8) {
this.setNewScreenPass()
let snackbar4string = get("login.lp6")
parentEpml.request('showSnackBar', `${snackbar4string}`)
}
}
extraConfirm() {
this.shadowRoot.getElementById('setLockScreenPass').close()
this.shadowRoot.getElementById('extraConfirmPass').open()
}
closExtraConfirmPass() {
this.shadowRoot.getElementById('extraConfirmPass').close()
this.shadowRoot.getElementById('lockPassword').value = ''
this.shadowRoot.getElementById('lockPasswordConfirm').value = ''
}
setNewScreenPass() {
const rawPassword = this.shadowRoot.getElementById('lockPassword').value
const cryptPassword = encryptData(rawPassword, this.salt)
localStorage.setItem(this.lockScreenPass, cryptPassword)
this.myLockScreenPass = ''
this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt)
this.shadowRoot.getElementById('setLockScreenPass').close()
this.shadowRoot.getElementById('extraConfirmPass').close()
this.shadowRoot.getElementById('lockPassword').value = ''
this.shadowRoot.getElementById('lockPasswordConfirm').value = ''
}
setLockQortal() {
this.helperMessage = this.renderHelperPass()
this.lockSet = ''
this.lockSet = encryptData(true, this.salt)
localStorage.setItem(this.lockScreenSet, this.lockSet)
this.myLockScreenSet = ''
this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt)
this.shadowRoot.getElementById('lockScreenActive').open()
}
passKeyListener(e) {
if (e.key === 'Enter') {
this.closeLockScreenActive()
}
}
async closeLockScreenActive() {
const myPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt)
const checkPass = this.shadowRoot.getElementById('unlockPassword').value
const errDelay = ms => new Promise(res => setTimeout(res, ms))
if (checkPass === myPass) {
this.lockSet = ''
this.lockSet = encryptData(false, this.salt)
localStorage.setItem(this.lockScreenSet, this.lockSet)
this.myLockScreenSet = ''
this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt)
this.shadowRoot.getElementById('lockScreenActive').close()
this.shadowRoot.getElementById('unlockPassword').value = ''
this.helperMessage = this.renderHelperPass()
} else {
this.shadowRoot.getElementById('unlockPassword').value = ''
this.helperMessage = this.renderHelperErr()
await errDelay(3000)
this.helperMessage = this.renderHelperPass()
return
}
}
renderHelperPass() {
return html`<span style="color: #fff; font-size: 13px; font-weight: bold; float: left;">${translate("login.pleaseenter")}</span>`
}
renderHelperErr() {
return html`<span style="color: var(--mdc-theme-error); font-size: 13px; font-weight: bold; float: right;">${translate("login.lp8")}</span>`
}
renderNodeManagement() {
const checkNodeManagement = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
if ((checkNodeManagement.enableManagement = true)) {

11
core/src/lockScreen.js Normal file
View File

@ -0,0 +1,11 @@
import CryptoJS from 'crypto-js'
export const encryptData = (data, salt) => CryptoJS.AES.encrypt(JSON.stringify(data), salt).toString()
export const decryptData = (ciphertext, salt) => {
const bytes = CryptoJS.AES.decrypt(ciphertext, salt)
try {
return JSON.parse(bytes.toString(CryptoJS.enc.Utf8))
} catch(err) {
return null
}
}

View File

@ -3,6 +3,8 @@ import { render } from 'lit/html.js'
import { Epml } from '../../../epml.js'
import isElectron from 'is-electron'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
import Base58 from '../../../../crypto/api/deps/Base58.js'
import { encryptData, decryptData } from '../../../../core/src/lockScreen.js'
registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
@ -24,6 +26,7 @@ import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@vaadin/grid'
import '@vaadin/grid/vaadin-grid-sorter'
import '@vaadin/password-field'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
@ -76,7 +79,16 @@ class TradeBotPortal extends LitElement {
tradeBotDogeBook: { type: Array },
tradeBotDgbBook: { type: Array },
tradeBotRvnBook: { type: Array },
tradeBotArrrBook: { type: Array }
tradeBotArrrBook: { type: Array },
autoSalt: { type: String },
autoStorageData: { type: String },
autoLockScreenPass: { type: String },
autoLockScreenSet: { type: String },
autoLockPass: { type: String },
autoLockSet: { type: String },
myAutoLockScreenPass: { type: String },
myAutoLockScreenSet: { type: String },
autoHelperMessage: { type: String }
}
}
@ -86,17 +98,17 @@ class TradeBotPortal extends LitElement {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-theme-error: rgb(255, 89, 89);
--mdc-text-field-outlined-idle-border-color: var(--txtfieldborder);
--mdc-text-field-outlined-idle-border-color: var(--txtfieldborder);
--mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder);
--mdc-text-field-label-ink-color: var(--black);
--mdc-text-field-ink-color: var(--black);
--mdc-select-outlined-idle-border-color: var(--txtfieldborder);
--mdc-select-outlined-idle-border-color: var(--txtfieldborder);
--mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder);
--mdc-select-label-ink-color: var(--black);
--mdc-select-ink-color: var(--black);
--mdc-theme-surface: var(--white);
--mdc-dialog-content-ink-color: var(--black);
--mdc-dialog-shape-radius: 25px;
--mdc-dialog-shape-radius: 25px;
--paper-input-container-focus-color: var(--mdc-theme-primary);
--lumo-primary-text-color: rgb(0, 167, 245);
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
@ -569,6 +581,56 @@ class TradeBotPortal extends LitElement {
.close-icon:hover {
cursor: pointer;
opacity: .6;
}
.setpass-wrapper {
width: 100%;
min-width: 400px;
max-width: 450px;
text-align: center;
background: var(--white);
border: 1px solid var(--black);
border-radius: 15px;
padding: 10px 10px 0px;
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
}
.lock-wrapper {
width: 100%;
height: 100%;
min-width: 600px;
max-width: 600px;
min-height: 400px;
max-height: 400px;
text-align: center;
background: url("/img/qortal-lock.jpg");
border: 1px solid var(--black);
border-radius: 25px;
padding: 10px 10px 0px;
}
.text-wrapper {
width: 100%;
height: 100%;
min-width: 280px;
max-width: 280px;
min-height: 64px;
max-height: 64px;
text-align: center;
margin-left: 35px;
margin-top: 125px;
overflow: hidden;
}
.lock-title-white {
font-family: 'magistralbold';
font-weight: 700;
font-size: 26px;
line-height: 32px;
color: #ffffff;
}
.lock-title-red {
font-family: 'magistralbold';
font-weight: 700;
font-size: 26px;
line-height: 32px;
color: #df3636;
}
@media (min-width: 701px) {
* {
@ -827,6 +889,15 @@ class TradeBotPortal extends LitElement {
this.tradeBotDgbBook = []
this.tradeBotRvnBook = []
this.tradeBotArrrBook = []
this.autoSalt = ''
this.autoStorageData = ''
this.autoLockScreenPass = ''
this.autoLockScreenSet = ''
this.autoLockPass = ''
this.autoLockSet = ''
this.myAutoLockScreenPass = ''
this.myAutoLockScreenSet = ''
this.autoHelperMessage = ''
}
openTradesTemplate() {
@ -1470,11 +1541,14 @@ class TradeBotPortal extends LitElement {
<mwc-list-item value="DOGECOIN"><span class="coinName doge" style="color: var(--black);">DOGE / QORT</span></mwc-list-item>
<mwc-list-item value="DIGIBYTE"><span class="coinName dgb" style="color: var(--black);">DGB / QORT</span></mwc-list-item>
<mwc-list-item value="RAVENCOIN"><span class="coinName rvn" style="color: var(--black);">RVN / QORT</span></mwc-list-item>
<mwc-list-item value="PIRATECHAIN"><span class="coinName arrr" style="color: var(--black);">ARRR / QORT</span></mwc-list-item>
<mwc-list-item value="PIRATECHAIN"><span class="coinName arrr" style="color: var(--black);">ARRR / QORT</span></mwc-list-item>
</mwc-select>
<div style="padding-left: 20px; padding-top: 5px;">
<mwc-fab mini icon="info" title="${translate("info.inf7")}" @click=${() => this.shadowRoot.getElementById('buyInfoDialog').open()}></mwc-fab>
</div>
<div style="padding-left: 20px; padding-top: 5px;">
<mwc-fab mini icon="info" title="${translate("info.inf7")}" @click=${() => this.shadowRoot.getElementById('buyInfoDialog').open()}></mwc-fab>
</div>
<div style="padding-left: 10px; padding-top: 12px; color: var(--black);">
${this.renderAutoLockButton()}
</div>
</div>
<div></div>
</div>
@ -1969,6 +2043,59 @@ class TradeBotPortal extends LitElement {
<h2>${translate("info.inf12")}</h2>
</div>
</paper-dialog>
<paper-dialog class="setpass-wrapper" id="setAutoLockScreenPass" modal>
<div style="text-align: center;">
<h2 style="color: var(--black);">Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}</h2>
<hr>
</div>
<div style="text-align: center;">
<h3 style="color: var(--black);">${translate("login.lp2")}</h3>
<h4 style="color: var(--black);">${translate("login.lp3")}</h4>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.password")}" id="autoLockPassword" autofocus></vaadin-password-field>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.confirmpass")}" id="autoLockPasswordConfirm"></vaadin-password-field>
</div>
<div style="display: flex; justify-content: space-between;">
<mwc-button class="red" @click="${() => this.closewAutoSetScreenLockPass()}">${translate("login.lp4")}</mwc-button>
<mwc-button @click="${() => this.autoCheckPass()}">${translate("login.lp5")}</mwc-button>
</div>
</paper-dialog>
<paper-dialog class="setpass-wrapper" id="autoExtraConfirmPass" modal>
<div style="text-align: center;">
<h2 style="color: var(--black);">Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}</h2>
<hr>
</div>
<div style="text-align: center;">
<h3 style="color: var(--black);">${translate("login.lessthen8")}</h3>
</div>
<div style="display: flex; justify-content: space-between;">
<mwc-button class="red" @click="${() => this.closAutoExtraConfirmPass()}">${translate("login.lp4")}</mwc-button>
<mwc-button @click="${() => this.setAutoNewScreenPass()}">${translate("login.lp5")}</mwc-button>
</div>
</paper-dialog>
<paper-dialog class="lock-wrapper" id="autoLockScreenActive" modal>
<div class="text-wrapper">
<span class="lock-title-white">${translate("tradepage.tchange46")}</span><br/>
<span class="lock-title-white">${translate("login.lp9")} </span>
<span class="lock-title-red">${translate("login.lp10")}</span>
</div>
<div style="display:flex; margin-top: 5px;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 45%;" label="${translate("login.password")}" id="autoUnlockPassword" @keydown="${this.autoPassKeyListener}" autofocus>
<div slot="helper">
${this.autoHelperMessage}
</div>
</vaadin-password-field>
</div>
<div style="display: flex; margin-top: 35px;">
<mwc-button dense unelevated label="${translate("login.lp7")}" icon="lock_open" @click="${() => this.closeAutoLockScreenActive()}"></mwc-button>
</div>
</paper-dialog>
`
}
@ -1978,6 +2105,45 @@ class TradeBotPortal extends LitElement {
this.changeTheme()
this.changeLanguage()
this.autoHelperMessage = this.renderAutoHelperPass()
this.autoSalt = ''
this.autoSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey)
this.autoStorageData = ''
this.autoStorageData = window.parent.reduxStore.getState().app.selectedAddress.address
this.autoLockScreenPass = ''
this.autoLockScreenPass = 'autoLockScreenPass-' + this.autoStorageData
this.autoLockScreenSet = ''
this.autoLockScreenSet = 'autoLockScreenSet-' + this.autoStorageData
this.autoLockPass = ''
this.autoLockPass = encryptData(false, this.autoSalt)
this.autoLockSet = ''
this.autoLockSet = encryptData(false, this.autoSalt)
if (localStorage.getItem(this.autoLockScreenPass) === null && localStorage.getItem(this.autoLockScreenSet) === null) {
localStorage.setItem(this.autoLockScreenPass, this.autoLockPass)
localStorage.setItem(this.autoLockScreenSet, this.autoLockSet)
this.myAutoLockScreenPass = ''
this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt)
this.myAutoLockScreenSet = ''
this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt)
} else {
this.myAutoLockScreenPass = ''
this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt)
this.myAutoLockScreenSet = ''
this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt)
}
if (this.myAutoLockScreenSet === true) {
this.shadowRoot.getElementById('autoLockScreenActive').open()
}
this.updateWalletBalance()
this.fetchWalletAddress(this.selectedCoin)
@ -2117,6 +2283,137 @@ class TradeBotPortal extends LitElement {
this.arrrTradebook()
}
renderAutoLockButton() {
if (this.myAutoLockScreenPass === false && this.myAutoLockScreenSet === false) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock-open" @click=${() => this.openAutoSetScreenLockPass()} title="${translate("login.lp11")}"></paper-icon-button>
</div>
`
} else if (this.myAutoLockScreenSet === false) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock-open" @click=${() => this.setAutoLockQortal()} title="${translate("login.lp11")}"></paper-icon-button>
</div>
`
} else if (this.myAutoLockScreenSet === true) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock" title="${translate("login.lp10")}"></paper-icon-button>
</div>
`
}
}
openAutoSetScreenLockPass() {
this.shadowRoot.getElementById('autoLockPassword').value = ''
this.shadowRoot.getElementById('autoLockPasswordConfirm').value = ''
this.shadowRoot.getElementById('setAutoLockScreenPass').open()
}
closewAutoSetScreenLockPass() {
this.shadowRoot.getElementById('setAutoLockScreenPass').close()
}
autoCheckPass() {
const autoPassword = this.shadowRoot.getElementById('autoLockPassword').value
const autoRePassword = this.shadowRoot.getElementById('autoLockPasswordConfirm').value
if (autoPassword === '') {
let snackbar1string = get("login.pleaseenter")
parentEpml.request('showSnackBar', `${snackbar1string}`)
return
}
if (autoPassword != autoRePassword) {
let snackbar2string = get("login.notmatch")
parentEpml.request('showSnackBar', `${snackbar2string}`)
return
}
if (autoPassword.length < 8) {
let snackbar3string = get("login.lessthen8")
parentEpml.request('showSnackBar', `${snackbar3string}`)
this.autoExtraConfirm()
}
if (autoPassword.length >= 8) {
this.setAutoNewScreenPass()
let snackbar4string = get("login.lp6")
parentEpml.request('showSnackBar', `${snackbar4string}`)
}
}
autoExtraConfirm() {
this.shadowRoot.getElementById('setAutoLockScreenPass').close()
this.shadowRoot.getElementById('autoExtraConfirmPass').open()
}
closAutoExtraConfirmPass() {
this.shadowRoot.getElementById('autoExtraConfirmPass').close()
this.shadowRoot.getElementById('autoLockPassword').value = ''
this.shadowRoot.getElementById('autoLockPasswordConfirm').value = ''
}
setAutoNewScreenPass() {
const autoRawPassword = this.shadowRoot.getElementById('autoLockPassword').value
const autoCryptPassword = encryptData(autoRawPassword, this.autoSalt)
localStorage.setItem(this.autoLockScreenPass, autoCryptPassword)
this.myAutoLockScreenPass = ''
this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt)
this.shadowRoot.getElementById('setAutoLockScreenPass').close()
this.shadowRoot.getElementById('autoExtraConfirmPass').close()
this.shadowRoot.getElementById('autoLockPassword').value = ''
this.shadowRoot.getElementById('autoLockPasswordConfirm').value = ''
}
setAutoLockQortal() {
this.autoHelperMessage = this.renderAutoHelperPass()
this.autoLockSet = ''
this.autoLockSet = encryptData(true, this.autoSalt)
localStorage.setItem(this.autoLockScreenSet, this.autoLockSet)
this.myAutoLockScreenSet = ''
this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt)
this.shadowRoot.getElementById('autoLockScreenActive').open()
}
autoPassKeyListener(e) {
if (e.key === 'Enter') {
this.closeAutoLockScreenActive()
}
}
async closeAutoLockScreenActive() {
const myAutoPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt)
const autoCheckPass = this.shadowRoot.getElementById('autoUnlockPassword').value
const errDelay = ms => new Promise(res => setTimeout(res, ms))
if (autoCheckPass === myAutoPass) {
this.autoLockSet = ''
this.autoLockSet = encryptData(false, this.autoSalt)
localStorage.setItem(this.autoLockScreenSet, this.autoLockSet)
this.myAutoLockScreenSet = ''
this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt)
this.shadowRoot.getElementById('autoLockScreenActive').close()
this.shadowRoot.getElementById('autoUnlockPassword').value = ''
this.autoHelperMessage = this.renderAutoHelperPass()
} else {
this.shadowRoot.getElementById('autoUnlockPassword').value = ''
this.autoHelperMessage = this.renderAutoHelperErr()
await errDelay(3000)
this.autoHelperMessage = this.renderAutoHelperPass()
return
}
}
renderAutoHelperPass() {
return html`<span style="color: #fff; font-weight: bold; font-size: 13px; float: left;">${translate("login.pleaseenter")}</span>`
}
renderAutoHelperErr() {
return html`<span style="color: var(--mdc-theme-error); font-weight: bold; font-size: 13px; float: right;">${translate("login.lp8")}</span>`
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
this.theme = (checkTheme === 'dark') ? 'dark' : 'light'

View File

@ -3,6 +3,8 @@ import { render } from 'lit/html.js'
import { Epml } from '../../../epml.js'
import isElectron from 'is-electron'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
import Base58 from '../../../../crypto/api/deps/Base58.js'
import { encryptData, decryptData } from '../../../../core/src/lockScreen.js'
registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
@ -24,6 +26,7 @@ import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@vaadin/grid'
import '@vaadin/grid/vaadin-grid-sorter'
import '@vaadin/password-field'
import chartsbtc from './charts/btc-charts.js'
import chartsltc from './charts/ltc-charts.js'
import chartsdoge from './charts/doge-charts.js'
@ -78,7 +81,16 @@ class TradePortal extends LitElement {
dgbqort: { type: Number },
rvnqort: { type: Number },
arrrqort: { type: Number },
qortRatio: {type: Number}
qortRatio: {type: Number},
tradeSalt: { type: String },
tradeStorageData: { type: String },
tradeLockScreenPass: { type: String },
tradeLockScreenSet: { type: String },
tradeLockPass: { type: String },
tradeLockSet: { type: String },
myTradeLockScreenPass: { type: String },
myTradeLockScreenSet: { type: String },
tradeHelperMessage: { type: String }
}
}
@ -88,17 +100,17 @@ class TradePortal extends LitElement {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-theme-error: rgb(255, 89, 89);
--mdc-text-field-outlined-idle-border-color: var(--txtfieldborder);
--mdc-text-field-outlined-idle-border-color: var(--txtfieldborder);
--mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder);
--mdc-text-field-label-ink-color: var(--black);
--mdc-text-field-ink-color: var(--black);
--mdc-select-outlined-idle-border-color: var(--txtfieldborder);
--mdc-select-outlined-idle-border-color: var(--txtfieldborder);
--mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder);
--mdc-select-label-ink-color: var(--black);
--mdc-select-ink-color: var(--black);
--mdc-theme-surface: var(--white);
--mdc-dialog-content-ink-color: var(--black);
--mdc-dialog-shape-radius: 25px;
--mdc-dialog-shape-radius: 25px;
--paper-input-container-focus-color: var(--mdc-theme-primary);
--lumo-primary-text-color: rgb(0, 167, 245);
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
@ -585,41 +597,97 @@ class TradePortal extends LitElement {
cursor: pointer;
opacity: .6;
}
@media (min-width: 701px) {
* {
}
#trade-portal {}
#first-trade-section {
display: grid;
grid-template-columns:1fr 1fr 2fr;
grid-auto-rows: max(450px);
column-gap: 0.5em;
row-gap: 0.4em;
justify-items: stretch;
align-items: stretch;
margin-bottom: 10px;
}
#second-trade-section {
display: grid;
grid-template-columns: 2fr 1fr;
grid-auto-rows: max(450px);
column-gap: 0.5em;
row-gap: 0.4em;
justify-items: stretch;
align-items: stretch;
margin-bottom: 10px;
}
#third-trade-section {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-auto-rows: max(200px);
column-gap: 0.5em;
row-gap: 0.4em;
justify-items: stretch;
align-items: stretch;
margin-bottom: 10px;
}
}
.setpass-wrapper {
width: 100%;
min-width: 400px;
max-width: 450px;
text-align: center;
background: var(--white);
border: 1px solid var(--black);
border-radius: 15px;
padding: 10px 10px 0px;
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
}
.lock-wrapper {
width: 100%;
height: 100%;
min-width: 600px;
max-width: 600px;
min-height: 400px;
max-height: 400px;
text-align: center;
background: url("/img/qortal-lock.jpg");
border: 1px solid var(--black);
border-radius: 25px;
padding: 10px 10px 0px;
}
.text-wrapper {
width: 100%;
height: 100%;
min-width: 280px;
max-width: 280px;
min-height: 64px;
max-height: 64px;
text-align: center;
margin-left: 35px;
margin-top: 125px;
overflow: hidden;
}
.lock-title-white {
font-family: 'magistralbold';
font-weight: 700;
font-size: 26px;
line-height: 32px;
color: #ffffff;
}
.lock-title-red {
font-family: 'magistralbold';
font-weight: 700;
font-size: 26px;
line-height: 32px;
color: #df3636;
}
@media (min-width: 701px) {
* {
}
#trade-portal {}
#first-trade-section {
display: grid;
grid-template-columns:1fr 1fr 2fr;
grid-auto-rows: max(450px);
column-gap: 0.5em;
row-gap: 0.4em;
justify-items: stretch;
align-items: stretch;
margin-bottom: 10px;
}
#second-trade-section {
display: grid;
grid-template-columns: 2fr 1fr;
grid-auto-rows: max(450px);
column-gap: 0.5em;
row-gap: 0.4em;
justify-items: stretch;
align-items: stretch;
margin-bottom: 10px;
}
#third-trade-section {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-auto-rows: max(200px);
column-gap: 0.5em;
row-gap: 0.4em;
justify-items: stretch;
align-items: stretch;
margin-bottom: 10px;
}
}
`
}
@ -817,6 +885,15 @@ class TradePortal extends LitElement {
this.displayTradeAddress = ''
this.displayTradeLevel = ''
this.displayTradeBalance = ''
this.tradeSalt = ''
this.tradeStorageData = ''
this.tradeLockScreenPass = ''
this.tradeLockScreenSet = ''
this.tradeLockPass = ''
this.tradeLockSet = ''
this.myTradeLockScreenPass = ''
this.myTradeLockScreenSet = ''
this.tradeHelperMessage = ''
}
historicTradesTemplate() {
@ -1211,13 +1288,16 @@ class TradePortal extends LitElement {
<mwc-list-item value="RAVENCOIN"><span class="coinName rvn" style="color: var(--black);">QORT / RVN</span></mwc-list-item>
<mwc-list-item value="PIRATECHAIN"><span class="coinName arrr" style="color: var(--black);">QORT / ARRR</span></mwc-list-item>
</mwc-select>
<div style="padding-left: 20px; padding-top: 5px;">
<mwc-fab mini icon="info" title="${translate("info.inf1")}" @click=${() => this.shadowRoot.getElementById('tradeInfoDialog').open()}></mwc-fab>
</div>
<div style="padding-left: 20px; padding-top: 15px;">
${this.chartShowCoin()}
</div>
<div style="padding-left: 20px; padding-top: 5px;">
<mwc-fab mini icon="info" title="${translate("info.inf1")}" @click=${() => this.shadowRoot.getElementById('tradeInfoDialog').open()}></mwc-fab>
</div>
<div style="padding-left: 20px; padding-top: 15px;">
${this.chartShowCoin()}
</div>
<div style="padding-left: 10px; padding-top: 12px; color: var(--black);">
${this.renderTradeLockButton()}
</div>
</div>
<div id="trade-portal">
<div id="first-trade-section">
@ -1269,6 +1349,59 @@ class TradePortal extends LitElement {
<h1 style="text-align: center;">${translate("info.inf6")}</h1>
</div>
</paper-dialog>
<paper-dialog class="setpass-wrapper" id="setTradeLockScreenPass" modal>
<div style="text-align: center;">
<h2 style="color: var(--black);">Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}</h2>
<hr>
</div>
<div style="text-align: center;">
<h3 style="color: var(--black);">${translate("login.lp2")}</h3>
<h4 style="color: var(--black);">${translate("login.lp3")}</h4>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.password")}" id="tradeLockPassword" autofocus></vaadin-password-field>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.confirmpass")}" id="tradeLockPasswordConfirm"></vaadin-password-field>
</div>
<div style="display: flex; justify-content: space-between;">
<mwc-button class="red" @click="${() => this.closewTradeSetScreenLockPass()}">${translate("login.lp4")}</mwc-button>
<mwc-button @click="${() => this.tradeCheckPass()}">${translate("login.lp5")}</mwc-button>
</div>
</paper-dialog>
<paper-dialog class="setpass-wrapper" id="tradeExtraConfirmPass" modal>
<div style="text-align: center;">
<h2 style="color: var(--black);">Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}</h2>
<hr>
</div>
<div style="text-align: center;">
<h3 style="color: var(--black);">${translate("login.lessthen8")}</h3>
</div>
<div style="display: flex; justify-content: space-between;">
<mwc-button class="red" @click="${() => this.closTradeExtraConfirmPass()}">${translate("login.lp4")}</mwc-button>
<mwc-button @click="${() => this.setTradeNewScreenPass()}">${translate("login.lp5")}</mwc-button>
</div>
</paper-dialog>
<paper-dialog class="lock-wrapper" id="tradeLockScreenActive" modal>
<div class="text-wrapper">
<span class="lock-title-white">${translate("sidemenu.tradeportal")}</span><br/>
<span class="lock-title-white">${translate("login.lp9")} </span>
<span class="lock-title-red">${translate("login.lp10")}</span>
</div>
<div style="display:flex; margin-top: 5px;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 45%;" label="${translate("login.password")}" id="tradeUnlockPassword" @keydown="${this.tradePassKeyListener}" autofocus>
<div slot="helper">
${this.tradeHelperMessage}
</div>
</vaadin-password-field>
</div>
<div style="display: flex; margin-top: 35px;">
<mwc-button dense unelevated label="${translate("login.lp7")}" icon="lock_open" @click="${() => this.closeTradeLockScreenActive()}"></mwc-button>
</div>
</paper-dialog>
<trader-info-view></trader-info-view>
`
}
@ -1279,6 +1412,45 @@ class TradePortal extends LitElement {
this.changeTheme()
this.changeLanguage()
this.tradeHelperMessage = this.renderTradeHelperPass()
this.tradeSalt = ''
this.tradeSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey)
this.tradeStorageData = ''
this.tradeStorageData = window.parent.reduxStore.getState().app.selectedAddress.address
this.tradeLockScreenPass = ''
this.tradeLockScreenPass = 'tradeLockScreenPass-' + this.tradeStorageData
this.tradeLockScreenSet = ''
this.tradeLockScreenSet = 'tradeLockScreenSet-' + this.tradeStorageData
this.tradeLockPass = ''
this.tradeLockPass = encryptData(false, this.tradeSalt)
this.tradeLockSet = ''
this.tradeLockSet = encryptData(false, this.tradeSalt)
if (localStorage.getItem(this.tradeLockScreenPass) === null && localStorage.getItem(this.tradeLockScreenSet) === null) {
localStorage.setItem(this.tradeLockScreenPass, this.tradeLockPass)
localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet)
this.myTradeLockScreenPass = ''
this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt)
this.myTradeLockScreenSet = ''
this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt)
} else {
this.myTradeLockScreenPass = ''
this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt)
this.myTradeLockScreenSet = ''
this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt)
}
if (this.myTradeLockScreenSet === true) {
this.shadowRoot.getElementById('tradeLockScreenActive').open()
}
this.updateWalletBalance()
this.fetchWalletAddress(this.selectedCoin)
@ -1434,6 +1606,137 @@ class TradePortal extends LitElement {
setTimeout(() => this.shadowRoot.querySelector('[slot="vaadin-grid-cell-content-3"]').setAttribute('title', 'Last Seen'), 3000)
}
renderTradeLockButton() {
if (this.myTradeLockScreenPass === false && this.myTradeLockScreenSet === false) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock-open" @click=${() => this.openTradeSetScreenLockPass()} title="${translate("login.lp11")}"></paper-icon-button>
</div>
`
} else if (this.myTradeLockScreenSet === false) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock-open" @click=${() => this.setTradeLockQortal()} title="${translate("login.lp11")}"></paper-icon-button>
</div>
`
} else if (this.myTradeLockScreenSet === true) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock" title="${translate("login.lp10")}"></paper-icon-button>
</div>
`
}
}
openTradeSetScreenLockPass() {
this.shadowRoot.getElementById('tradeLockPassword').value = ''
this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = ''
this.shadowRoot.getElementById('setTradeLockScreenPass').open()
}
closewTradeSetScreenLockPass() {
this.shadowRoot.getElementById('setTradeLockScreenPass').close()
}
tradeCheckPass() {
const tradePassword = this.shadowRoot.getElementById('tradeLockPassword').value
const tradeRePassword = this.shadowRoot.getElementById('tradeLockPasswordConfirm').value
if (tradePassword === '') {
let snackbar1string = get("login.pleaseenter")
parentEpml.request('showSnackBar', `${snackbar1string}`)
return
}
if (tradePassword != tradeRePassword) {
let snackbar2string = get("login.notmatch")
parentEpml.request('showSnackBar', `${snackbar2string}`)
return
}
if (tradePassword.length < 8) {
let snackbar3string = get("login.lessthen8")
parentEpml.request('showSnackBar', `${snackbar3string}`)
this.tradeExtraConfirm()
}
if (tradePassword.length >= 8) {
this.setTradeNewScreenPass()
let snackbar4string = get("login.lp6")
parentEpml.request('showSnackBar', `${snackbar4string}`)
}
}
tradeExtraConfirm() {
this.shadowRoot.getElementById('setTradeLockScreenPass').close()
this.shadowRoot.getElementById('tradeExtraConfirmPass').open()
}
closTradeExtraConfirmPass() {
this.shadowRoot.getElementById('tradeExtraConfirmPass').close()
this.shadowRoot.getElementById('tradeLockPassword').value = ''
this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = ''
}
setTradeNewScreenPass() {
const tradeRawPassword = this.shadowRoot.getElementById('tradeLockPassword').value
const tradeCryptPassword = encryptData(tradeRawPassword, this.tradeSalt)
localStorage.setItem(this.tradeLockScreenPass, tradeCryptPassword)
this.myTradeLockScreenPass = ''
this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt)
this.shadowRoot.getElementById('setTradeLockScreenPass').close()
this.shadowRoot.getElementById('tradeExtraConfirmPass').close()
this.shadowRoot.getElementById('tradeLockPassword').value = ''
this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = ''
}
setTradeLockQortal() {
this.tradeHelperMessage = this.renderTradeHelperPass()
this.tradeLockSet = ''
this.tradeLockSet = encryptData(true, this.tradeSalt)
localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet)
this.myTradeLockScreenSet = ''
this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt)
this.shadowRoot.getElementById('tradeLockScreenActive').open()
}
tradePassKeyListener(e) {
if (e.key === 'Enter') {
this.closeTradeLockScreenActive()
}
}
async closeTradeLockScreenActive() {
const myTradePass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt)
const tradeCheckPass = this.shadowRoot.getElementById('tradeUnlockPassword').value
const errDelay = ms => new Promise(res => setTimeout(res, ms))
if (tradeCheckPass === myTradePass) {
this.tradeLockSet = ''
this.tradeLockSet = encryptData(false, this.tradeSalt)
localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet)
this.myTradeLockScreenSet = ''
this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt)
this.shadowRoot.getElementById('tradeLockScreenActive').close()
this.shadowRoot.getElementById('tradeUnlockPassword').value = ''
this.tradeHelperMessage = this.renderTradeHelperPass()
} else {
this.shadowRoot.getElementById('tradeUnlockPassword').value = ''
this.tradeHelperMessage = this.renderTradeHelperErr()
await errDelay(3000)
this.tradeHelperMessage = this.renderTradeHelperPass()
return
}
}
renderTradeHelperPass() {
return html`<span style="color: #fff; font-weight: bold; font-size: 13px; float: left;">${translate("login.pleaseenter")}</span>`
}
renderTradeHelperErr() {
return html`<span style="color: var(--mdc-theme-error); font-weight: bold; font-size: 13px; float: right;">${translate("login.lp8")}</span>`
}
requestTraderInfo(traderAddress) {
let getAddress = traderAddress
const theInfoView = this.shadowRoot.querySelector('trader-info-view')

View File

@ -3,6 +3,8 @@ import { render } from 'lit/html.js'
import { Epml } from '../../../epml.js'
import isElectron from 'is-electron'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
import Base58 from '../../../../crypto/api/deps/Base58.js'
import { encryptData, decryptData } from '../../../../core/src/lockScreen.js'
registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
@ -21,6 +23,7 @@ import '@material/mwc-icon'
import '@material/mwc-icon-button'
import '@material/mwc-tab-bar'
import '@material/mwc-textfield'
import '@polymer/paper-dialog/paper-dialog.js'
import '@polymer/paper-progress/paper-progress.js'
import '@polymer/paper-slider/paper-slider.js'
import '@polymer/paper-spinner/paper-spinner-lite.js'
@ -30,6 +33,7 @@ import '@vaadin/button'
import '@vaadin/grid'
import '@vaadin/icon'
import '@vaadin/icons'
import '@vaadin/password-field'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
@ -97,7 +101,16 @@ class MultiWallet extends LitElement {
dgbBookAddress: { type: String },
rvnBookAddress: { type: String },
arrrBookAddress: { type: String },
myElementId: { type: String }
myElementId: { type: String },
walletSalt: { type: String },
walletStorageData: { type: String },
walletLockScreenPass: { type: String },
walletLockScreenSet: { type: String },
walletLockPass: { type: String },
walletLockSet: { type: String },
myWalletLockScreenPass: { type: String },
myWalletLockScreenSet: { type: String },
walletHelperMessage: { type: String }
}
}
@ -112,6 +125,7 @@ class MultiWallet extends LitElement {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-theme-surface: var(--white);
--mdc-theme-error: rgb(255, 89, 89);
--mdc-dialog-content-ink-color: var(--black);
--mdc-dialog-min-width: 400px;
--mdc-dialog-max-width: 1024px;
@ -121,6 +135,8 @@ class MultiWallet extends LitElement {
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
--lumo-primary-color: hsl(199, 100%, 48%);
--lumo-base-color: var(--white);
--lumo-secondary-text-color: var(--sectxt);
--lumo-contrast-60pct: var(--vdicon);
--lumo-body-text-color: var(--black);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
@ -219,6 +235,18 @@ class MultiWallet extends LitElement {
font-family: 'Open Sans', sans-serif;
}
.magistral {
font-family: 'magistralbold';
}
.montserrat {
font-family: 'Montserrat', sans-serif;
}
.maven {
font-family: 'MavenPro', sans-serif;
}
.weight-100 {
font-weight: 100;
}
@ -318,6 +346,7 @@ class MultiWallet extends LitElement {
}
.header-title {
display: inlinr;
font-size: 32px;
color: var(--black);
font-weight: 600;
@ -592,18 +621,18 @@ class MultiWallet extends LitElement {
cursor: pointer;
}
.warning-text {
animation: blinker 1.5s linear infinite;
text-align: center;
margin-top: 10px;
color: rgb(255, 89, 89);
}
.warning-text {
animation: blinker 1.5s linear infinite;
text-align: center;
margin-top: 10px;
color: rgb(255, 89, 89);
}
@keyframes blinker {
50% {
opacity: 0;
}
}
@keyframes blinker {
50% {
opacity: 0;
}
}
@media (max-width: 764px) {
.wallet {
@ -641,6 +670,61 @@ class MultiWallet extends LitElement {
font: 18px/24px 'Open Sans', sans-serif;
}
}
.setpass-wrapper {
width: 100%;
min-width: 400px;
max-width: 450px;
text-align: center;
background: var(--white);
border: 1px solid var(--black);
border-radius: 15px;
padding: 10px 10px 0px;
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
}
.lock-wrapper {
width: 100%;
height: 100%;
min-width: 600px;
max-width: 600px;
min-height: 400px;
max-height: 400px;
text-align: center;
background: url("/img/qortal-lock.jpg");
border: 1px solid var(--black);
border-radius: 25px;
padding: 10px 10px 0px;
}
.text-wrapper {
width: 100%;
height: 100%;
min-width: 280px;
max-width: 280px;
min-height: 64px;
max-height: 64px;
text-align: center;
margin-left: 35px;
margin-top: 125px;
overflow: hidden;
}
.lock-title-white {
font-family: 'magistralbold';
font-weight: 700;
font-size: 26px;
line-height: 32px;
color: #ffffff;
}
.lock-title-red {
font-family: 'magistralbold';
font-weight: 700;
font-size: 26px;
line-height: 32px;
color: #df3636;
}
`
}
@ -719,6 +803,15 @@ class MultiWallet extends LitElement {
this.rvnFeePerByte = 1125
this.rvnSatMinFee = 1000
this.rvnSatMaxFee = 10000
this.walletSalt = ''
this.walletStorageData = ''
this.walletLockScreenPass = ''
this.walletLockScreenSet = ''
this.walletLockPass = ''
this.walletLockSet = ''
this.myWalletLockScreenPass = ''
this.myWalletLockScreenSet = ''
this.walletHelperMessage = ''
this.wallets = new Map()
@ -764,7 +857,7 @@ class MultiWallet extends LitElement {
return html`
<div class="wrapper">
<div class="header-title sans">
${translate("walletpage.wchange22")}
${translate("walletpage.wchange22")} ${this.renderWalletLockButton()}
</div>
<div class="fullWidth">
@ -2627,6 +2720,59 @@ class MultiWallet extends LitElement {
</mwc-button>
</mwc-dialog>
</div>
<paper-dialog class="setpass-wrapper" id="setWalletLockScreenPass" modal>
<div style="text-align: center;">
<h2 style="color: var(--black);">Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}</h2>
<hr>
</div>
<div style="text-align: center;">
<h3 style="color: var(--black);">${translate("login.lp2")}</h3>
<h4 style="color: var(--black);">${translate("login.lp3")}</h4>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.password")}" id="walletLockPassword" autofocus></vaadin-password-field>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.confirmpass")}" id="walletLockPasswordConfirm"></vaadin-password-field>
</div>
<div style="display: flex; justify-content: space-between;">
<mwc-button class="red" @click="${() => this.closewWalletSetScreenLockPass()}">${translate("login.lp4")}</mwc-button>
<mwc-button @click="${() => this.walletCheckPass()}">${translate("login.lp5")}</mwc-button>
</div>
</paper-dialog>
<paper-dialog class="setpass-wrapper" id="walletExtraConfirmPass" modal>
<div style="text-align: center;">
<h2 style="color: var(--black);">Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}</h2>
<hr>
</div>
<div style="text-align: center;">
<h3 style="color: var(--black);">${translate("login.lessthen8")}</h3>
</div>
<div style="display: flex; justify-content: space-between;">
<mwc-button class="red" @click="${() => this.closWalletExtraConfirmPass()}">${translate("login.lp4")}</mwc-button>
<mwc-button @click="${() => this.setWalletNewScreenPass()}">${translate("login.lp5")}</mwc-button>
</div>
</paper-dialog>
<paper-dialog class="lock-wrapper" id="walletLockScreenActive" modal>
<div class="text-wrapper">
<span class="lock-title-white">${translate("sidemenu.wallets")}</span><br/>
<span class="lock-title-white">${translate("login.lp9")} </span>
<span class="lock-title-red">${translate("login.lp10")}</span>
</div>
<div style="display:flex; margin-top: 5px;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width: 45%;" label="${translate("login.password")}" id="walletUnlockPassword" @keydown="${this.walletPassKeyListener}" autofocus>
<div slot="helper">
${this.walletHelperMessage}
</div>
</vaadin-password-field>
</div>
<div style="display: flex; margin-top: 35px;">
<mwc-button dense unelevated label="${translate("login.lp7")}" icon="lock_open" @click="${() => this.closeWalletLockScreenActive()}"></mwc-button>
</div>
</paper-dialog>
`
}
@ -2634,6 +2780,45 @@ class MultiWallet extends LitElement {
this.changeTheme()
this.changeLanguage()
this.walletHelperMessage = this.renderWalletHelperPass()
this.walletSalt = ''
this.walletSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey)
this.walletStorageData = ''
this.walletStorageData = window.parent.reduxStore.getState().app.selectedAddress.address
this.walletLockScreenPass = ''
this.walletLockScreenPass = 'walletLockScreenPass-' + this.walletStorageData
this.walletLockScreenSet = ''
this.walletLockScreenSet = 'walletLockScreenSet-' + this.walletStorageData
this.walletLockPass = ''
this.walletLockPass = encryptData(false, this.walletSalt)
this.walletLockSet = ''
this.walletLockSet = encryptData(false, this.walletSalt)
if (localStorage.getItem(this.walletLockScreenPass) === null && localStorage.getItem(this.walletLockScreenSet) === null) {
localStorage.setItem(this.walletLockScreenPass, this.walletLockPass)
localStorage.setItem(this.walletLockScreenSet, this.walletLockSet)
this.myWalletLockScreenPass = ''
this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt)
this.myWalletLockScreenSet = ''
this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt)
} else {
this.myWalletLockScreenPass = ''
this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt)
this.myWalletLockScreenSet = ''
this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt)
}
if (this.myWalletLockScreenSet === true) {
this.shadowRoot.getElementById('walletLockScreenActive').open()
}
this.qortAddressbook()
this.btcAddressbook()
this.ltcAddressbook()
@ -2669,6 +2854,137 @@ class MultiWallet extends LitElement {
}
}
renderWalletLockButton() {
if (this.myWalletLockScreenPass === false && this.myWalletLockScreenSet === false) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock-open" @click=${() => this.openWalletSetScreenLockPass()} title="${translate("login.lp11")}"></paper-icon-button>
</div>
`
} else if (this.myWalletLockScreenSet === false) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock-open" @click=${() => this.setWalletLockQortal()} title="${translate("login.lp11")}"></paper-icon-button>
</div>
`
} else if (this.myWalletLockScreenSet === true) {
return html`
<div style="display: inline;">
<paper-icon-button style="padding-bottom: 12px;" icon="icons:lock" title="${translate("login.lp10")}"></paper-icon-button>
</div>
`
}
}
openWalletSetScreenLockPass() {
this.shadowRoot.getElementById('walletLockPassword').value = ''
this.shadowRoot.getElementById('walletLockPasswordConfirm').value = ''
this.shadowRoot.getElementById('setWalletLockScreenPass').open()
}
closewWalletSetScreenLockPass() {
this.shadowRoot.getElementById('setWalletLockScreenPass').close()
}
walletCheckPass() {
const walletPassword = this.shadowRoot.getElementById('walletLockPassword').value
const walletRePassword = this.shadowRoot.getElementById('walletLockPasswordConfirm').value
if (walletPassword === '') {
let snackbar1string = get("login.pleaseenter")
parentEpml.request('showSnackBar', `${snackbar1string}`)
return
}
if (walletPassword != walletRePassword) {
let snackbar2string = get("login.notmatch")
parentEpml.request('showSnackBar', `${snackbar2string}`)
return
}
if (walletPassword.length < 8) {
let snackbar3string = get("login.lessthen8")
parentEpml.request('showSnackBar', `${snackbar3string}`)
this.walletExtraConfirm()
}
if (walletPassword.length >= 8) {
this.setWalletNewScreenPass()
let snackbar4string = get("login.lp6")
parentEpml.request('showSnackBar', `${snackbar4string}`)
}
}
walletExtraConfirm() {
this.shadowRoot.getElementById('setWalletLockScreenPass').close()
this.shadowRoot.getElementById('walletExtraConfirmPass').open()
}
closWalletExtraConfirmPass() {
this.shadowRoot.getElementById('walletExtraConfirmPass').close()
this.shadowRoot.getElementById('walletLockPassword').value = ''
this.shadowRoot.getElementById('walletLockPasswordConfirm').value = ''
}
setWalletNewScreenPass() {
const walletRawPassword = this.shadowRoot.getElementById('walletLockPassword').value
const walletCryptPassword = encryptData(walletRawPassword, this.walletSalt)
localStorage.setItem(this.walletLockScreenPass, walletCryptPassword)
this.myWalletLockScreenPass = ''
this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt)
this.shadowRoot.getElementById('setWalletLockScreenPass').close()
this.shadowRoot.getElementById('walletExtraConfirmPass').close()
this.shadowRoot.getElementById('walletLockPassword').value = ''
this.shadowRoot.getElementById('walletLockPasswordConfirm').value = ''
}
setWalletLockQortal() {
this.walletHelperMessage = this.renderWalletHelperPass()
this.walletLockSet = ''
this.walletLockSet = encryptData(true, this.walletSalt)
localStorage.setItem(this.walletLockScreenSet, this.walletLockSet)
this.myWalletLockScreenSet = ''
this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt)
this.shadowRoot.getElementById('walletLockScreenActive').open()
}
walletPassKeyListener(e) {
if (e.key === 'Enter') {
this.closeWalletLockScreenActive()
}
}
async closeWalletLockScreenActive() {
const myWalletPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt)
const walletCheckPass = this.shadowRoot.getElementById('walletUnlockPassword').value
const errDelay = ms => new Promise(res => setTimeout(res, ms))
if (walletCheckPass === myWalletPass) {
this.walletLockSet = ''
this.walletLockSet = encryptData(false, this.walletSalt)
localStorage.setItem(this.walletLockScreenSet, this.walletLockSet)
this.myWalletLockScreenSet = ''
this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt)
this.shadowRoot.getElementById('walletLockScreenActive').close()
this.shadowRoot.getElementById('walletUnlockPassword').value = ''
this.walletHelperMessage = this.renderWalletHelperPass()
} else {
this.shadowRoot.getElementById('walletUnlockPassword').value = ''
this.walletHelperMessage = this.renderWalletHelperErr()
await errDelay(3000)
this.walletHelperMessage = this.renderWalletHelperPass()
return
}
}
renderWalletHelperPass() {
return html`<span style="color: #fff; font-weight: bold; font-size: 13px; float: left;">${translate("login.pleaseenter")}</span>`
}
renderWalletHelperErr() {
return html`<span style="color: var(--mdc-theme-error); font-weight: bold; font-size: 13px; float: right;">${translate("login.lp8")}</span>`
}
renderWarning() {
return html`<span class="warning-text">${translate("tradepage.tchange48")} QORT</span>`
}