Bug fixes

This commit is contained in:
sairaj mote 2023-08-16 00:40:57 +05:30
parent b6d97322fd
commit 6b9623ada2
5 changed files with 117 additions and 96 deletions

View File

@ -813,13 +813,15 @@ h3 {
}
#verification_list {
display: grid;
display: flex;
flex-direction: column;
gap: 1rem;
}
.verification-item {
display: grid;
grid-template-columns: 6rem 1fr auto;
grid-template-columns: 1fr auto;
grid-template-areas: "time status" "doc-info doc-info";
align-items: center;
justify-content: space-between;
gap: 1rem;
@ -828,9 +830,16 @@ h3 {
background-color: rgba(var(--foreground-color), 1);
}
.verification-item time {
grid-area: time;
font-size: 0.9rem;
color: rgba(var(--text-color), 0.8);
}
.verification-item :nth-child(2) {
grid-area: doc-info;
}
.verification-item :nth-child(3) {
grid-area: status;
}
#verifier_wrapper > * {
background-color: rgba(var(--foreground-color), 1);
@ -879,6 +888,7 @@ h3 {
gap: 1rem;
font-weight: 500;
cursor: pointer;
flex: 1;
}
.revoke-card input {
accent-color: var(--accent-color);
@ -900,6 +910,7 @@ h3 {
#view_file_popup img {
max-width: 100%;
max-height: 100%;
margin: auto;
}
#commit_approvals {
@ -999,6 +1010,10 @@ h3 {
#approve_verifier_popup {
--width: min(32rem, 100%);
}
.verification-item {
grid-template-columns: 6rem 1fr auto;
grid-template-areas: "time doc-info status";
}
}
@media (any-hover: hover) {
::-webkit-scrollbar {

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -775,12 +775,14 @@ h3 {
}
}
#verification_list {
display: grid;
display: flex;
flex-direction: column;
gap: 1rem;
}
.verification-item {
display: grid;
grid-template-columns: 6rem 1fr auto;
grid-template-columns: 1fr auto;
grid-template-areas: "time status" "doc-info doc-info";
align-items: center;
justify-content: space-between;
gap: 1rem;
@ -788,9 +790,16 @@ h3 {
border-radius: 0.5rem;
background-color: rgba(var(--foreground-color), 1);
time {
grid-area: time;
font-size: 0.9rem;
color: rgba(var(--text-color), 0.8);
}
:nth-child(2) {
grid-area: doc-info;
}
:nth-child(3) {
grid-area: status;
}
}
#verifier_wrapper {
& > * {
@ -837,6 +846,7 @@ h3 {
gap: 1rem;
font-weight: 500;
cursor: pointer;
flex: 1;
}
input {
accent-color: var(--accent-color);
@ -859,6 +869,7 @@ h3 {
img {
max-width: 100%;
max-height: 100%;
margin: auto;
}
}
#commit_approvals {
@ -947,6 +958,10 @@ h3 {
#approve_verifier_popup {
--width: min(32rem, 100%);
}
.verification-item {
grid-template-columns: 6rem 1fr auto;
grid-template-areas: "time doc-info status";
}
}
@media (any-hover: hover) {
::-webkit-scrollbar {

View File

@ -15,10 +15,9 @@
/* Constants for FLO blockchain operations !!Make sure to add this at beginning!! */
const floGlobals = {
blockchain: "FLO",
adminID: "FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf",
application: "TEST_MODE",
SNStorageID: "FSF5igBd9xC7ZBB511DZG8PVB2eT93YE3M",
masterAddress: 'FRSUrLuy5nhz6PCyuxMmo7vg9JmTFX5Goi'
adminID: "FJ4KcVQ6HeHZ54DjrtE3rUYmYjV3FHhXSM",
application: "KYC_Docs",
SNStorageID: "FSF5igBd9xC7ZBB511DZG8PVB2eT93YE3M"
}
</script>
</head>
@ -149,7 +148,7 @@
<script src="scripts/compactIDB.js"></script>
<script src="scripts/floCloudAPI.js"></script>
<script src="scripts/floDapps.js"></script>
<script src="scripts/main.js"></script>
<!-- <script src="scripts/main.js"></script> -->
<script>
const { html, render: renderElem } = uhtml;
// Use instead of document.getElementById
@ -500,6 +499,7 @@
`);
if (!floGlobals.isPrivKeySecured)
getRef('private_key_field').customValidation = floCrypto.getPubKeyHex;
getRef('private_key_field').focusIn();
})
function handleSignUp() {
const privKey = getRef('generated_private_key').value.trim();
@ -619,9 +619,11 @@
})
const kycRequests = getUserKycRequests(floAddress);
const verifiedRequest = Object.values(kycRequests).find(request => {
const wasSentByAddress = request.senderID === floAddress || request.senderID === btcAddress
const isApproved = request.tag?.includes('approved')
return wasSentByAddress && isApproved
const { senderID, tag_key, tag } = request;
const wasSentByAddress = senderID === floAddress || senderID === btcAddress
const isApproved = tag?.includes('approved')
const isApprovedByValidVerifier = floGlobals.subAdmins.some(subAdmin => floCrypto.isSameAddr(subAdmin, floCrypto.getFloID(tag_key)))
return wasSentByAddress && isApproved && isApprovedByValidVerifier
});
if (verifiedRequest) {
const { tag_key, tag_time } = verifiedRequest;
@ -660,7 +662,10 @@
<div class="grid justify-items-center text-center gap-0-5" style="margin: 2rem">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/></svg>
<h4>KYC data not found</h4>
<a class="button button--primary" href="#/sign_in">Sign in to apply for KYC</a>
${myFloID ?
html`<a class="button button--primary" href="#/home">Start KYC process</a>` :
html`<a class="button button--primary" href="#/sign_in">Sign in to apply for KYC</a>`
}
</div>
`);
getRef('verification_result').dataset.status = 'invalid';
@ -702,19 +707,9 @@
`
},
pendingKycRequest(request) {
const { senderID, time, files } = request;
const { message: { docType, docVectorClock }, vectorClock, senderID, time, } = request;
const floAddress = getFloAddress(senderID)
const btcAddress = getBtcAddress(floAddress)
const fileButtons = files.map(file => {
const { message: { docType, docVectorClock }, vectorClock } = file;
return html`
<div class="multi-state-button">
<button class="button button--primary" .dataset=${{ requestVC: vectorClock, docVC: docVectorClock }} onclick=${viewFile}>
Check ${docTypeNames[docType]}
</button>
</div>
`
})
return html`
<li class="kyc-request">
<time>${getFormattedTime(time)}</time>
@ -726,38 +721,36 @@
<p>FLO Address</p>
<sm-copy value=${floAddress}></sm-copy>
</div>
<div class="flex gap-1 flex-wrap">${fileButtons}</div>
<div class="multi-state-button margin-right-auto">
<button class="button button--primary" .dataset=${{ requestVC: vectorClock, docVC: docVectorClock }} onclick=${viewFile}>
Check ${docTypeNames[docType]}
</button>
</div>
</li>`
},
approvedKycRequest(request) {
const { senderID, time, files, tag } = request;
const { message: { docType, docVectorClock }, vectorClock, senderID, time, } = request;
const floAddress = getFloAddress(senderID)
const btcAddress = getBtcAddress(floAddress)
const fileButtons = files.map(file => {
const { message: { docType, docVectorClock }, vectorClock, tag } = file;
return html`
<div class="multi-state-button">
<button class="button button--primary" .dataset=${{ requestVC: vectorClock, docVC: docVectorClock }} onclick=${viewFile}>
View ${docTypeNames[docType]}
</button>
</div>
`
})
return html`
<li class="revoke-card">
<label class="flex align-center">
<input type="checkbox" value=${floAddress}/>
<input type="checkbox" value=${floAddress} .dataset=${{ requestVC: vectorClock, docVC: docVectorClock }}/>
<div class="grid gap-0-3">
<span class="wrap-around">BTC: ${btcAddress}</span>
<span class="wrap-around">FLO: ${floAddress}</span>
</div>
</label>
<div class="flex gap-1 flex-wrap">${fileButtons}</div>
<div class="multi-state-button margin-right-auto">
<button class="button button--primary" .dataset=${{ requestVC: vectorClock, docVC: docVectorClock }} onclick=${viewFile}>
View ${docTypeNames[docType]}
</button>
</div>
</li>
`
},
rejectedKycRequest(request) {
const { senderID, time, files } = request;
const { message: { docType, docVectorClock }, vectorClock, senderID, time, } = request;
const floAddress = getFloAddress(senderID)
const btcAddress = getBtcAddress(floAddress)
return html`
@ -784,24 +777,9 @@
kycRequests(options = {}) {
const { status = 'pending', address } = options;
const kycRequests = floDapps.getNextGeneralData('userKycRequests', '0');
const filteredRequests = {};
// group requests by senderID
for (const [key, request] of Object.entries(kycRequests)) {
const { message, senderID, time, tag, vectorClock, note } = request;
const floAddress = getFloAddress(senderID)
if (!filteredRequests[floAddress]) {
filteredRequests[floAddress] = {
time,
tag: tag?.includes('approved') ? 'approved' : tag,
files: [],
note
};
}
filteredRequests[floAddress].files.push({ message, vectorClock, tag });
}
const result = []
Object.entries(filteredRequests).forEach(([senderID, request]) => {
const { time, tag, files, note } = request;
const filteredRequests = [];
Object.values(kycRequests).forEach((request) => {
const { time, tag, note, senderID } = request;
const floAddress = getFloAddress(senderID)
if (status) {
switch (status) {
@ -820,16 +798,16 @@
const query = address.toLowerCase();
if (!floAddress.toLowerCase().includes(query) && !getBtcAddress(floAddress).toLowerCase().includes(query)) return;
}
switch (tag || note) {
switch (tag?.split('|')[0] || note) {
case 'approved':
return result.push(render.approvedKycRequest({ senderID: floAddress, time, tag, files }));
return filteredRequests.push(render.approvedKycRequest(request));
case 'rejected':
return result.push(render.rejectedKycRequest({ senderID: floAddress, time, tag, files }));
return filteredRequests.push(render.rejectedKycRequest(request));
default:
return result.push(render.pendingKycRequest({ senderID: floAddress, time, tag, files }));
return filteredRequests.push(render.pendingKycRequest(request));
}
})
return result.reverse();
return filteredRequests.reverse();
},
userRequests() {
let isVerified = false;
@ -837,24 +815,32 @@
const requests = getUserKycRequests();
let hasUploaded = {}
const renderedRequests = Object.keys(requests).map((key) => {
const { time, tag, message: { docType } } = requests[key];
const { time, tag, message: { docType }, note } = requests[key];
const txId = tag?.split('|')[1] || undefined;
if (!isVerified && tag?.includes('approved'))
isVerified = true;
if (!tag) {
if (!tag && !note) {
concurrentRequests++;
hasUploaded[docType] = true;
}
return html`
<li class="verification-item">
<time>${getFormattedTime(time)}</time>
<h4>${docTypeNames[docType]}</h4>
<div class="flex flex-direction-column gap-0-5">
<h4>${docTypeNames[docType]}</h4>
${txId ? html`
<a href=${`https://blockbook.ranchimall.net/tx/${txId}`} target="_blank">
Check on blockchain
</a>
`: ''}
</div>
${isVerified ? html`
<div class="flex gap-0-3 align-center">
<svg class="icon"style="fill: var(--green)" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><path d="M23,12l-2.44-2.79l0.34-3.69l-3.61-0.82L15.4,1.5L12,2.96L8.6,1.5L6.71,4.69L3.1,5.5L3.44,9.2L1,12l2.44,2.79l-0.34,3.7 l3.61,0.82L8.6,22.5l3.4-1.47l3.4,1.46l1.89-3.19l3.61-0.82l-0.34-3.69L23,12z M10.09,16.72l-3.8-3.81l1.48-1.48l2.32,2.33 l5.85-5.87l1.48,1.48L10.09,16.72z"/></g></svg>
<b>Verified</b>
</div>
`: html`
<p>Status: <b>${tag || 'Processing'}</b></p>
<p>Status: <b>${tag || note || 'Processing'}</b></p>
`}
</li>
`;
@ -895,9 +881,8 @@
<h3>KYC requests</h3>
<sm-chips id="kyc_request_filter" onchange=${handleRequestFilter}>
<sm-chip value="pending" ?selected=${filter === "pending"}>Pending</sm-chip>
<sm-chip value="rejected" ?selected=${filter === "rejected"}>Rejected</sm-chip>
<sm-chip value="approved" ?selected=${filter === "approved"}>Approved</sm-chip>
<sm-chip value="all" ?selected=${filter === "all"}>All</sm-chip>
<sm-chip value="rejected" ?selected=${filter === "rejected"}>Rejected</sm-chip>
</sm-chips>
</div>
<sm-input id="search_approved" type="search" placeholder="Search address" oninput=${handleRequestSearch}>
@ -912,7 +897,7 @@
<button id="revoke_kyc_button" class="button button--primary" onclick=${revokeKycs}>Revoke selected</button>
</div>
</div>
${filter === "approved" ? html`
${filter === "approved" && renderedKycRequests?.length ? html`
<p>Select KYC verification to revoke</p>
`: ''}
<ul id="kyc_requests_list" class="flex flex-direction-column gap-0-5" onchange=${handleAddressSelection}>
@ -938,7 +923,7 @@
</div>
</div>
<ul id="approved_verifiers_list" onchange=${handleVerifierSelection}>
${renderedSubAdmins}
${renderedSubAdmins.length ? renderedSubAdmins : html`<li style="padding: 1rem 0;">No KYC verifiers found</li>`}
</ul>
<div class="multi-state-button margin-right-auto">
<button id="add_sub_admin_button" class="button button--small button--colored" onclick=${() => openPopup('approve_verifier_popup')}>
@ -1019,7 +1004,7 @@
</section>
`;
const tooManyRequestsSection = html`
<section class="flex flex-direction-column gap-1 card justify-center">
<section class="flex flex-direction-column gap-1 card justify-items-center">
<h2 class="text-center">Request limit reached</h2>
<p class="text-center">You have reached KYC verification request limit. Wait until your previous requests are processed.</p>
</section>
@ -1039,7 +1024,7 @@
</section>
`: ''}
` : html`
<section class="flex flex-direction-column gap-1 card justify-center">
<section class="flex flex-direction-column gap-1 card justify-items-center">
<h2 class="text-center">No KYC verifiers found</h2>
<p class="text-center">No KYC verifiers are available at the moment. Please try again later.</p>
</section>
@ -1295,14 +1280,14 @@
const addressesToRevoke = new Map()
function handleAddressSelection(e) {
if (e.target.checked) {
const floData = `KYC|REVOKE_KYC|${[...addressesToRevoke.keys()].join(',')}`
if (floData.length > 1040) {
return notify('Maximum limit reached for this batch. Revoke selected and continue the process.', 'error')
}
addressesToRevoke.set(e.target.value, {
requestVC: e.target.dataset.requestVC,
docVC: e.target.dataset.docVC,
})
const floData = `KYC|REVOKE_KYC|${[...addressesToRevoke.keys()].join(',')}`
if (floData.length > 1040) {
return notify('Maximum limit reached for this batch. Revoke selected and continue the process.', 'error')
}
} else {
addressesToRevoke.delete(e.target.value)
}
@ -1387,7 +1372,9 @@
renderElem(getRef('commit_approvals_popup__content'), html`
<div class="flex gap-1 align-center space-between">
<h4>KYCs to commit</h4>
<button class="button button--primary" onclick=${commitApprovals}>Commit</button>
<div class="multi-state-button">
<button id="approve_kyc_button" class="button button--primary" onclick=${commitApprovals}>Commit</button>
</div>
</div>
<ul class="grid gap-1-5">
${approvedAddress}
@ -1412,14 +1399,14 @@
const addresses = [...floGlobals.approvalsToBeCommitted.keys()]
// create multiple txs if addresses exceed 1040 characters
const addressesPerTx = 30
const chunks = Math.ceil(addresses.size / addressesPerTx)
const chunks = Math.ceil(addresses.length / addressesPerTx)
let txPromises = []
for (let i = 0; i < chunks; i++) {
const chunk = addresses.slice(i * addressesPerTx, (i + 1) * addressesPerTx)
const floData = `KYC|APPROVE_KYC|${chunk.join('+')}`
txPromises.push(floBlockchainAPI.writeData(floGlobals.myFloID, floData, approverPrivateKey, floGlobals.myFloID))
}
buttonLoader(getRef('submit_kyc'), true)
buttonLoader(getRef('approve_kyc_button'), true)
try {
const txIds = await Promise.all(txPromises)
const cloudPromises = [...floGlobals.approvalsToBeCommitted.values()].flatMap(({ requestVC, docVC }) => {
@ -1429,6 +1416,7 @@
floCloudAPI.tagApplicationData(docVC, `approved|${txIds.join('+')}`)
]
})
await Promise.all(cloudPromises)
console.log(`Approval request submitted. TXIDs: ${txIds.join(', ')}`)
notify('Users approved successfully', 'success');
floGlobals.approvalsToBeCommitted.clear()
@ -1439,7 +1427,7 @@
console.error(err)
notify('Error approving users', 'error');
} finally {
buttonLoader(getRef('submit_kyc'), false)
buttonLoader(getRef('approve_kyc_button'), false)
setTimeout(() => {
checkBalance()
}, 1000)
@ -1464,11 +1452,11 @@
})
if (!confirmation) return
buttonLoader(getRef('revoke_kyc_button'), true)
const cloudPromises = [...addressesToRevoke.keys()].flatMap((address, { requestVC, docVC }) => {
const cloudPromises = [...addressesToRevoke.values()].flatMap(({ requestVC, docVC }) => {
floGlobals.generalData[floCloudAPI.util.filterKey('userKycRequests')][requestVC].tag = 'revoked'
return [
floCloudAPI.tagApplicationData(requestVC, 'revoked'),
floCloudAPI.tagApplicationData(docVC, undefined)
floCloudAPI.tagApplicationData(docVC, 'revoked')
]
})
const [txId, ...cloudResponses] = await Promise.all([
@ -1478,7 +1466,6 @@
notify(`Revoke request submitted. TXID: ${txId}`, 'success');
addressesToRevoke.clear()
clearSelection()
renderHome()
} catch (e) {
notify(e, 'error')
} finally {
@ -1486,7 +1473,10 @@
setTimeout(() => {
checkBalance()
}, 1000)
getRef('selected_addresses').textContent = ``
getRef('selected_wrapper').classList.add('hidden')
getRef('kyc_requests_header').classList.remove('hidden')
renderHome()
}
}
function setApproverName() {
@ -1580,15 +1570,16 @@
buttonLoader(getRef('approve_verifier_button'), true)
try {
const adminPrivateKey = await floDapps.user.private
const floData = `KYC|APPROVE_AGGREGATOR|${addresses.join('+')}`
if (floData.length > 1040) {
return notify('Too many addresses added. Try removing one.', 'error')
}
const [txId] = await Promise.all([
floBlockchainAPI.writeData(floGlobals.myFloID, floData, adminPrivateKey, floGlobals.myFloID),
floDapps.manageAppConfig(adminPrivateKey, addresses)
])
notify(`Verifiers approval request submitted. TXID: ${txId}`, 'success');
// const floData = `KYC|APPROVE_AGGREGATOR|${addresses.join('+')}`
// if (floData.length > 1040) {
// return notify('Too many addresses added. Try removing one.', 'error')
// }
// const [txId] = await Promise.all([
// floBlockchainAPI.writeData(floGlobals.myFloID, floData, adminPrivateKey, floGlobals.myFloID),
// floDapps.manageAppConfig(adminPrivateKey, addresses)
// ])
await floDapps.manageAppConfig(adminPrivateKey, addresses)
notify(`Verifiers approval request submitted. May take upto 30 mins to complete.`, 'success');
floGlobals.subAdmins = [...new Set([...floGlobals.subAdmins, ...addresses])]
closePopup()
renderHome()

View File

@ -1,11 +1,11 @@
function checkIfSentByMasterAddress(tx) {
return tx.vin.some(vin => vin.addresses[0] === floGlobals.masterAddress);
return tx.vin.some(vin => vin.addresses[0] === floGlobals.adminID);
}
function getApprovedAggregators() {
floGlobals.approvedKycAggregators = {};
return new Promise((resolve, reject) => {
floBlockchainAPI.readAllTxs(floGlobals.masterAddress).then(({ items: transactions }) => {
floBlockchainAPI.readAllTxs(floGlobals.adminID).then(({ items: transactions }) => {
console.log(transactions);
transactions.filter(tx => checkIfSentByMasterAddress(tx) && tx.floData.startsWith('KYC'))
.reverse()