added option to set password
This commit is contained in:
parent
2e753968b8
commit
6bff6c476b
30
index.html
30
index.html
@ -788,6 +788,16 @@
|
||||
</div>
|
||||
<sm-button class="danger justify-self-start" onclick="signOut()">Sign out</sm-button>
|
||||
</div>
|
||||
<div class="grid gap-1 card">
|
||||
<h4>Secure private key</h4>
|
||||
<p>
|
||||
You can set a password to secure your private key and use the password instead of private key.
|
||||
This is applied to this browser only.
|
||||
</p>
|
||||
<button id="secure_pwd_button" class="button button--primary justify-self-start secure-priv-key"
|
||||
onclick="openPopup('secure_pwd_popup')">Set
|
||||
password</button>
|
||||
</div>
|
||||
<div class="grid gap-1 user-element card">
|
||||
<h4>My UPI IDs</h4>
|
||||
<ul id="saved_upi_ids_list" class="observe-empty-state"></ul>
|
||||
@ -1434,6 +1444,26 @@
|
||||
</div>
|
||||
</div>
|
||||
</sm-popup>
|
||||
<sm-popup id="secure_pwd_popup">
|
||||
<header slot="header" class="popup__header">
|
||||
<button class="popup__header__close justify-self-start">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
|
||||
fill="#000000">
|
||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||
<path
|
||||
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||
</svg>
|
||||
</button>
|
||||
<h3 id="secure_pwd_title">Set password</h3>
|
||||
</header>
|
||||
<sm-form>
|
||||
<sm-input id="secure_pwd_input" type="password" placeholder="Password" animate required autofocus>
|
||||
</sm-input>
|
||||
<button class="button button--primary cta secure-priv-key" type="submit" onclick="setSecurePassword()">
|
||||
Set
|
||||
</button>
|
||||
</sm-form>
|
||||
</sm-popup>
|
||||
|
||||
<!-- Cashier popups -->
|
||||
<sm-popup id="confirm_topup_popup">
|
||||
|
||||
@ -1117,13 +1117,13 @@ customElements.define('sm-notifications', class extends HTMLElement {
|
||||
|
||||
createNotification(message, options = {}) {
|
||||
const { pinned = false, icon = '', action } = options;
|
||||
const notification = document.createElement('output')
|
||||
const notification = document.createElement('div')
|
||||
notification.id = this.randString(8)
|
||||
notification.classList.add('notification');
|
||||
let composition = ``;
|
||||
composition += `
|
||||
<div class="icon-container">${icon}</div>
|
||||
<p>${message}</p>
|
||||
<output>${message}</output>
|
||||
`;
|
||||
if (action) {
|
||||
composition += `
|
||||
@ -1177,6 +1177,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
|
||||
}
|
||||
|
||||
removeNotification(notification, direction = 'left') {
|
||||
if (!notification) return;
|
||||
const sign = direction === 'left' ? '-' : '+';
|
||||
notification.animate([
|
||||
{
|
||||
@ -1218,8 +1219,10 @@ customElements.define('sm-notifications', class extends HTMLElement {
|
||||
|
||||
this.mediaQuery.addEventListener('change', this.handleOrientationChange);
|
||||
this.notificationPanel.addEventListener('pointerdown', e => {
|
||||
if (e.target.closest('.notification')) {
|
||||
this.swipeThreshold = this.clientWidth / 2;
|
||||
if (e.target.closest('.close')) {
|
||||
this.removeNotification(e.target.closest('.notification'));
|
||||
} else if (e.target.closest('.notification')) {
|
||||
this.swipeThreshold = e.target.closest('.notification').getBoundingClientRect().width / 2;
|
||||
this.currentTarget = e.target.closest('.notification');
|
||||
this.currentTarget.setPointerCapture(e.pointerId);
|
||||
this.startTime = Date.now();
|
||||
@ -1262,12 +1265,6 @@ customElements.define('sm-notifications', class extends HTMLElement {
|
||||
this.notificationPanel.releasePointerCapture(e.pointerId);
|
||||
this.currentX = 0;
|
||||
});
|
||||
this.notificationPanel.addEventListener('click', e => {
|
||||
if (e.target.closest('.close')) {
|
||||
this.removeNotification(e.target.closest('.notification'));
|
||||
}
|
||||
});
|
||||
|
||||
const observer = new MutationObserver(mutationList => {
|
||||
mutationList.forEach(mutation => {
|
||||
if (mutation.type === 'childList') {
|
||||
|
||||
156
scripts/fn_ui.js
156
scripts/fn_ui.js
@ -11,9 +11,16 @@
|
||||
const relativeTime = new RelativeTime({ style: 'narrow' });
|
||||
|
||||
// use floDapps.storeContact() to store contacts that can be used by other apps on same device
|
||||
function syncUserData(obsName, data) {
|
||||
const dataToSend = Crypto.AES.encrypt(JSON.stringify(data), myPrivKey);
|
||||
return floCloudAPI.sendApplicationData(dataToSend, obsName, { receiverID: floDapps.user.id });
|
||||
async function syncUserData(obsName, data) {
|
||||
floDapps.user.private.then(privateKey => {
|
||||
if (!privateKey) return;
|
||||
const encryptedData = Crypto.AES.encrypt(JSON.stringify(data), privateKey);
|
||||
return floCloudAPI.sendApplicationData(encryptedData, obsName, { receiverID: floDapps.user.id });
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
notify('Invalid password', 'error');
|
||||
return false;
|
||||
})
|
||||
}
|
||||
// store user data in separate IDB
|
||||
async function organizeSyncedData(obsName) {
|
||||
@ -21,13 +28,20 @@ async function organizeSyncedData(obsName) {
|
||||
if (fetchedData.length && await compactIDB.readData(obsName, 'lastSyncTime') !== fetchedData[0].time) {
|
||||
await compactIDB.clearData(obsName);
|
||||
const dataToDecrypt = floCloudAPI.util.decodeMessage(fetchedData[0].message);
|
||||
const decryptedData = JSON.parse(Crypto.AES.decrypt(dataToDecrypt, myPrivKey));
|
||||
for (let key in decryptedData) {
|
||||
floGlobals[obsName][key] = decryptedData[key];
|
||||
compactIDB.addData(obsName, decryptedData[key], key);
|
||||
}
|
||||
compactIDB.addData(obsName, fetchedData[0].time, 'lastSyncTime');
|
||||
return true;
|
||||
floDapps.user.private.then(privateKey => {
|
||||
if (!privateKey) return;
|
||||
const decryptedData = JSON.parse(Crypto.AES.decrypt(dataToDecrypt, privateKey));
|
||||
for (let key in decryptedData) {
|
||||
floGlobals[obsName][key] = decryptedData[key];
|
||||
compactIDB.addData(obsName, decryptedData[key], key);
|
||||
}
|
||||
compactIDB.addData(obsName, fetchedData[0].time, 'lastSyncTime');
|
||||
return true;
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
notify('Invalid password', 'error');
|
||||
return false;
|
||||
})
|
||||
} else {
|
||||
const idbData = await compactIDB.readAllData(obsName);
|
||||
for (const key in idbData) {
|
||||
@ -121,22 +135,30 @@ function withdrawMoneyFromWallet() {
|
||||
function transferToExchange() {
|
||||
const amount = parseFloat(getRef('exchange_transfer__amount').value.trim());
|
||||
buttonLoader('exchange_transfer__button', true);
|
||||
floExchangeAPI.depositToken('rupee', amount, floDapps.user.id, 'FRJkPqdbbsug3TtQRAWviqvTL9Qr2EMnrm', myPrivKey).then(txid => {
|
||||
console.log(txid);
|
||||
showChildElement('exchange_transfer_process', 1);
|
||||
getRef('exchange_transfer__success_message').textContent = `Transferred ${formatAmount(amount)} to exchange`;
|
||||
}).catch(error => {
|
||||
floDapps.user.private.then(privateKey => {
|
||||
if (!privateKey) return;
|
||||
floExchangeAPI.depositToken('rupee', amount, floDapps.user.id, 'FRJkPqdbbsug3TtQRAWviqvTL9Qr2EMnrm', privateKey).then(txid => {
|
||||
console.log(txid);
|
||||
showChildElement('exchange_transfer_process', 1);
|
||||
getRef('exchange_transfer__success_message').textContent = `Transferred ${formatAmount(amount)} to exchange`;
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
if (error.code) {
|
||||
error = error.message;
|
||||
}
|
||||
if (error === 'Insufficient rupee# balance')
|
||||
error = 'Insufficient rupee token balance in your wallet, please top-up your wallet.';
|
||||
getRef('exchange_transfer__failed_reason').textContent = error;
|
||||
showChildElement('exchange_transfer_process', 2);
|
||||
}).finally(() => {
|
||||
buttonLoader('exchange_transfer__button', false);
|
||||
});
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
if (error.code) {
|
||||
error = error.message;
|
||||
}
|
||||
if (error === 'Insufficient rupee# balance')
|
||||
error = 'Insufficient rupee token balance in your wallet, please top-up your wallet.';
|
||||
getRef('exchange_transfer__failed_reason').textContent = error;
|
||||
showChildElement('exchange_transfer_process', 2);
|
||||
}).finally(() => {
|
||||
buttonLoader('exchange_transfer__button', false);
|
||||
});
|
||||
notify('Invalid password', 'error');
|
||||
closePopup();
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
async function renderSavedUpiIds() {
|
||||
@ -470,12 +492,13 @@ function declineTopUp() {
|
||||
}
|
||||
|
||||
|
||||
function completeTokenToCashRequest(request) {
|
||||
async function completeTokenToCashRequest(request) {
|
||||
const { vectorClock, senderID, message: { token_txid, amount, upi_id } } = request;
|
||||
var upiID;
|
||||
if (upi_id instanceof Object && "secret" in upi_id) {
|
||||
try {
|
||||
upiID = floCrypto.decryptData(upi_id, myPrivKey);
|
||||
const privateKey = await floGlobals.user.private
|
||||
upiID = floCrypto.decryptData(upi_id, privateKey);
|
||||
} catch (error) {
|
||||
console.error("UPI ID is not encrypted with a proper key", error);
|
||||
return notify("Invalid UPI ID", 'error');
|
||||
@ -1197,17 +1220,26 @@ function getSignedIn(passwordType) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
console.log(floDapps.user.id)
|
||||
|
||||
getPromptInput('Enter password', '', {
|
||||
isPassword: true,
|
||||
}).then(password => {
|
||||
if (password) {
|
||||
resolve(password)
|
||||
}
|
||||
})
|
||||
}catch(err) {
|
||||
if (passwordType === 'PIN/Password') {
|
||||
floGlobals.isPrivKeySecured = true;
|
||||
getRef('private_key_field').removeAttribute('data-private-key');
|
||||
getRef('private_key_field').setAttribute('placeholder', 'Password');
|
||||
getRef('private_key_field').customValidation = null
|
||||
|
||||
getRef('secure_pwd_button').closest('.card').classList.add('hidden');
|
||||
} else {
|
||||
floGlobals.isPrivKeySecured = false;
|
||||
getRef('private_key_field').dataset.privateKey = ''
|
||||
getRef('private_key_field').setAttribute('placeholder', 'FLO private key');
|
||||
getRef('private_key_field').customValidation = floCrypto.getPubKeyHex
|
||||
getRef('private_key_field').customValidation = floCrypto.getPubKeyHex;
|
||||
getRef('secure_pwd_button').closest('.card').classList.remove('hidden');
|
||||
}
|
||||
if (window.location.hash.includes('sign_in') || window.location.hash.includes('sign_up')) {
|
||||
showPage(window.location.hash);
|
||||
@ -1227,6 +1259,19 @@ function getSignedIn(passwordType) {
|
||||
}
|
||||
});
|
||||
}
|
||||
function setSecurePassword() {
|
||||
if (!floGlobals.isPrivKeySecured) {
|
||||
const password = getRef('secure_pwd_input').value.trim();
|
||||
floDapps.securePrivKey(password).then(() => {
|
||||
floGlobals.isPrivKeySecured = true;
|
||||
notify('Password set successfully', 'success');
|
||||
getRef('secure_pwd_button').closest('.card').classList.add('hidden');
|
||||
closePopup();
|
||||
}).catch(err => {
|
||||
notify(err, 'error');
|
||||
})
|
||||
}
|
||||
}
|
||||
function signOut() {
|
||||
getConfirmation('Sign out?', 'You are about to sign out of the app, continue?', 'Stay', 'Leave')
|
||||
.then(async (res) => {
|
||||
@ -1372,31 +1417,38 @@ getRef('fees_selector').addEventListener('change', e => {
|
||||
})
|
||||
|
||||
|
||||
getRef('send_transaction').onclick = evt => {
|
||||
getRef('send_transaction').onclick = evt => {
|
||||
buttonLoader('send_transaction', true)
|
||||
const senders = btc_api.convert.legacy2bech(floDapps.user.id);
|
||||
const privKeys = btc_api.convert.wif(myPrivKey);
|
||||
const receivers = [...getRef('receiver_container').querySelectorAll('.receiver-input')].map(input => input.value.trim());
|
||||
const amounts = [...getRef('receiver_container').querySelectorAll('.amount-input')].map(input => {
|
||||
return parseFloat(input.value.trim())
|
||||
});
|
||||
const fee = parseFloat(getRef('send_fee').value.trim());
|
||||
console.debug(senders, receivers, amounts, fee);
|
||||
btc_api.sendTx(senders, privKeys, receivers, amounts, fee).then(result => {
|
||||
console.log(result);
|
||||
closePopup();
|
||||
getRef('txid').value = result.txid;
|
||||
openPopup('txid_popup');
|
||||
getRef('send_tx').reset()
|
||||
getExchangeRate().then(() => {
|
||||
calculateBtcFees()
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
floGlobals.user.private.then(privateKey => {
|
||||
const privKeys = btc_api.convert.wif(privateKey);
|
||||
const senders = btc_api.convert.legacy2bech(floDapps.user.id);
|
||||
const receivers = [...getRef('receiver_container').querySelectorAll('.receiver-input')].map(input => input.value.trim());
|
||||
const amounts = [...getRef('receiver_container').querySelectorAll('.amount-input')].map(input => {
|
||||
return parseFloat(input.value.trim())
|
||||
});
|
||||
const fee = parseFloat(getRef('send_fee').value.trim());
|
||||
console.debug(senders, receivers, amounts, fee);
|
||||
btc_api.sendTx(senders, privKeys, receivers, amounts, fee).then(result => {
|
||||
console.log(result);
|
||||
closePopup();
|
||||
getRef('txid').value = result.txid;
|
||||
openPopup('txid_popup');
|
||||
getRef('send_tx').reset()
|
||||
getExchangeRate().then(() => {
|
||||
calculateBtcFees()
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
}).catch(error => {
|
||||
notify(`Error sending transaction \n ${error}`, 'error');
|
||||
}).finally(_ => {
|
||||
buttonLoader('send_transaction', false)
|
||||
})
|
||||
}).catch(error => {
|
||||
notify(`Error sending transaction \n ${error}`, 'error');
|
||||
}).finally(_ => {
|
||||
buttonLoader('send_transaction', false)
|
||||
console.log(error);
|
||||
notify('Invalid password', 'error');
|
||||
closePopup();
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -134,6 +134,7 @@ document.addEventListener('popupclosed', e => {
|
||||
break;
|
||||
case 'transfer_to_exchange_popup':
|
||||
showChildElement('exchange_transfer_process', 0);
|
||||
buttonLoader('exchange_transfer__button', false);
|
||||
break;
|
||||
case 'confirm_topup_popup':
|
||||
showChildElement('confirm_topup_wrapper', 0);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user