Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server-side Verification of documents #412

Merged
merged 20 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9bfb0ac
Merge pull request #12 from ProxeusApp/preprod
tafonina Jun 9, 2023
9d3d6a2
fix web3.fromAscii to web3.utils.asciiToHex method in document floe
Jun 13, 2023
029ab3e
Merge pull request #14 from sprotest/feature/fix-web3-method-fromAscii
tafonina Jun 13, 2023
028563a
replace web3 to this.wallet.proxeusFS.web3 as metamask no longer inje…
Jun 13, 2023
b069463
Merge pull request #15 from sprotest/feature/fix-web3-method-fromAscii
tafonina Jun 13, 2023
a5e9d02
Merge pull request #16 from ProxeusApp/preprod
tafonina Oct 19, 2023
26ef319
remove outdated methods of old smart contract
slavas490 Oct 24, 2023
6b2c7fc
add public urls in case user doesnt have metamask
Oct 24, 2023
7bff03b
Merge pull request #18 from sprotest/feature/remove-old-smartcontract…
slavas490 Oct 24, 2023
614e5a9
Merge branch 'develop' into feature/verify-doc
tafonina Oct 27, 2023
3710bb3
Merge pull request #19 from sprotest/feature/verify-doc
tafonina Oct 27, 2023
18b6f1c
fix js frontend typos
slavas490 Nov 1, 2023
29e1324
use public url only if user doesnt have metamask installed
Nov 2, 2023
be08fea
Merge branch 'feature/verify-doc' of github.com:sprotest/proxeus-core…
Nov 2, 2023
e164676
use public url only if user doesnt have metamask installed
Nov 2, 2023
d700aa2
Merge branch 'develop' into feature/verify-doc
tafonina Nov 2, 2023
88dd2fd
Merge pull request #20 from sprotest/feature/verify-doc
tafonina Nov 2, 2023
f3ecefe
add wrong metamask network selected issue handler
slavas490 Nov 2, 2023
4a98f86
fix user validation network screen
slavas490 Nov 2, 2023
1d8af13
remove unnecessary html code from VerificationFileEntry component
slavas490 Nov 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion ui/core/src/baseApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ export default {
this.handleError(err)
})
},
setConfig (d) {
async setConfig (d) {
if (d.blockchainNet) {
this.blockchainNet = d.blockchainNet
}
Expand All @@ -395,6 +395,8 @@ export default {
}
if (this.blockchainNet && this.blockchainProxeusFSAddress) {
this.wallet = new WalletInterface(this.blockchainNet, this.blockchainProxeusFSAddress)

await this.wallet.validateUserNetwork(() => this.$root.$emit('service-off'), () => this.$root.$emit('service-on'))
}
},
acknowledgeFirstLogin () {
Expand Down
12 changes: 10 additions & 2 deletions ui/core/src/components/document/Verification.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<div class="light-text mx-auto mt-5"
v-show="!wallet || initialized === false">{{ $t('Connecting with the blockchain ...') }}
</div>
<div class="dropbox bg-white pl-0" v-if="initialized"
<div class="dropbox bg-white pl-0" v-if="initialized && !hasPreinitError"
:class="{hasDocuments}">
<file-drop-box @dropped="drop"></file-drop-box>
<p class="w-100 text-center" v-if="!hasDocuments">
Expand All @@ -15,11 +15,16 @@
</span>
</p>
</div>
<div class="stats col-sm-12 p-0" v-show="hasDocuments">
<div class="stats col-sm-12 p-0" v-show="hasDocuments && !hasPreinitError">
<verification-file-entry :singleFile="files.length === 1" v-for="file in files" :key="file.name" :file="file"
:wallet="wallet"
:thumbnail="thumbnail"></verification-file-entry>
</div>
<div class="stats col-sm-12 p-0" v-show="hasPreinitError">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using the same verification-file-entry component twice in a different way? Does it not always expect a file object? Perhaps we should have a separate component for showing network errors.

<verification-file-entry :hasPreinitError="true"
:wallet="wallet"
:thumbnail="thumbnail"></verification-file-entry>
</div>
</div>
</div>
<div class="powered-by row">
Expand Down Expand Up @@ -65,6 +70,9 @@ export default {
created () {
},
computed: {
hasPreinitError () {
return this.wallet().isIncorrectNetwork === true
}
},
methods: {
drop (file) {
Expand Down
131 changes: 79 additions & 52 deletions ui/core/src/components/document/VerificationFileEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
<spinner v-show="loading" background="transparent" color="#eee" :margin="10" cls="position-relative"></spinner>
<i v-show="valid" class="text-success material-icons md-60 mdi mdi-check-circle"></i>
<i v-show="notFound" class="text-danger material-icons md-60 mdi mdi-close-circle"></i>
<i v-show="invalid || errorValidating" class="text-danger material-icons md-60 mdi mdi-alert-circle"></i>
<i v-show="invalid || validationException" class="text-danger material-icons md-60 mdi mdi-alert-circle"></i>
</div>
<div v-if="!loading">
<div class="break-word mx-auto mt-2 mb-0">
<h4 v-show="valid"
class="text-success">{{ $t('Verified file is valid', 'The file {filename} is valid.', {filename: file.name}) }}</h4>
class="text-success">{{ $t('Verified file is valid', 'The file {filename} is valid.', {filename: file?.name}) }}</h4>
<h4 v-show="invalid"
class="text-danger">{{ $t('Verified file revoked', 'The file {filename} has been revoked.', {filename: file.name}) }}</h4>
class="text-danger">{{ $t('Verified file revoked', 'The file {filename} has been revoked.', {filename: file?.name}) }}</h4>
<h4 v-show="notFound"
class="text-danger">{{ $t('Verified file is invalid', 'The file {filename} is invalid.', {filename: file.name}) }}</h4>
class="text-danger">{{ $t('Verified file is invalid', 'The file {filename} is invalid.', {filename: file?.name}) }}</h4>
</div>
<div class="text-center mt-2">
<div v-show="valid" class="mb-2">
Expand All @@ -26,7 +26,7 @@
</a>
</div>
<div v-if="showDetails === true || !valid">
<hr v-show="!errorValidating" class="w-75"/>
<hr v-show="!validationException" class="w-75"/>
<div class="container text-md-left text-center">
<div v-show="timestamp" class="row mb-2">
<div
Expand Down Expand Up @@ -87,6 +87,8 @@
v-show="invalid">{{ $t('Verified file invalid explanation', 'This file has been recognised as authentic but has since been declared invalid. It may have expired or been recalled by the issuer.') }}</p>
<p
v-show="errorValidating">{{ $t('Error while verifying file', 'File hash could not been verified due to technical problems. Please try again.') }}</p>
<p
v-show="errorPublicRPC">{{ $t('Error while using public RPC', 'Please install Metamask extension to verify file.') }}</p>
</div>

<hr class="w-75" v-show="valid"/>
Expand All @@ -101,29 +103,47 @@
</div>

</div>
<div v-else-if="hasPreinitError" class="text-center p-3 border border-2 border-light">
<div class="pb-1">
<i class="text-danger material-icons md-60 mdi mdi-alert-circle"></i>
</div>
<div>
<div class="break-word mx-auto mt-2 mb-0">
<h4 class="text-danger">{{ $t('Unable to verify a document', 'Unable to verify a document') }}</h4>
</div>
<div class="text-center mt-2">
<div>
<div class="text-hint w-100 px-md-5 mt-2 pt-0">
<p
v-show="isIncorrectNetwork">{{ $t('Error incorrect network', 'Document can not be verified within incorrect network.') }}</p>
</div>
</div>
</div>
</div>
</div>
<div v-else class="border border-2 border-light mb-2 container">
<div class="row list-item">
<div class="bg-light col-lg-1 px-1 status-holder text-center">
<div class="check py-2">
<spinner v-show="loading" background="transparent" color="#eee" :margin="16"
cls="position-relative"></spinner>
<i v-show="notFound" class="text-danger material-icons md-36 mdi mdi-close-circle"></i>
<i v-show="invalid || errorValidating" class="text-danger material-icons md-36 mdi mdi-alert-circle"></i>
<i v-show="invalid || validationException || isIncorrectNetwork" class="text-danger material-icons md-36 mdi mdi-alert-circle"></i>
<i v-show="loading === false && status" class="text-success material-icons md-36 mdi mdi-check-circle"></i>
</div>
</div>
<div class="py-2 pl-3 pr-2 col-lg-8">
<div>
<p class="filename mb-0">{{ file.name }}</p>
<p class="filename mb-0">{{ file?.name }}</p>
<div v-show="!loading">
<small v-show="valid"
class="text-success">{{ $t('Verified file is valid', 'The file {filename} is valid.', {filename: file.name}) }}
class="text-success">{{ $t('Verified file is valid', 'The file {filename} is valid.', {filename: file?.name}) }}
</small>
<small v-show="invalid"
class="text-danger">{{ $t('Verified file revoked', 'The file {filename} has been revoked.', {filename: file.name}) }}
class="text-danger">{{ $t('Verified file revoked', 'The file {filename} has been revoked.', {filename: file?.name}) }}
</small>
<small v-show="notFound"
class="text-danger">{{ $t('Verified file is invalid', 'The file {filename} is invalid.', {filename: file.name}) }}
class="text-danger">{{ $t('Verified file is invalid', 'The file {filename} is invalid.', {filename: file?.name}) }}
</small>
</div>
</div>
Expand All @@ -145,6 +165,9 @@
<small class="text-hint" v-show="errorValidating">
{{ $t('Error while verifying file', 'File could not been verified due to technical problems. Please try again.') }}
</small>
<small class="text-hint" v-show="errorPublicRPC">
{{ $t('Error while using public RPC', 'Please install Metamask extension to verify file.') }}
</small>

<small v-show="showDetails" class="text-hint text-left">

Expand Down Expand Up @@ -203,7 +226,7 @@ import Spinner from '../Spinner'

export default {
name: 'verification-file-entry',
props: ['file', 'wallet', 'singleFile'],
props: ['file', 'wallet', 'singleFile', 'hasPreinitError'],
components: {
Spinner
},
Expand All @@ -220,23 +243,30 @@ export default {
signatures: [],
contract: undefined,
errorValidating: false,
errorPublicRPC: false,
validationException: false,
showDetails: false
}
},
mounted () {
this.verify()
if (!this.hasPreinitError) {
this.verify()
}
},
computed: {
valid () {
return this.errorValidating === false && this.loading === false && this.loading === false && this.status === true
return this.validationException === false && this.loading === false && this.loading === false && this.status === true
},
invalid () {
return this.errorValidating === false && this.loading === false && this.status === false &&
return this.validationException === false && this.loading === false && this.status === false &&
this.isFileInvalidated === true
},
notFound () {
return this.errorValidating === false && this.loading === false && this.status === false &&
this.isFileInvalidated !== true
return this.validationException === false && this.loading === false && this.status === false &&
this.isFileInvalidated !== true && !this.hasPreinitError
},
isIncorrectNetwork () {
return this.wallet().isIncorrectNetwork === true
}
},
filters: {
Expand All @@ -252,6 +282,7 @@ export default {
methods: {
async verify () {
this.loading = true

try {
// use hash if it already comes with the file object
if (this.file.hash) {
Expand All @@ -264,48 +295,44 @@ export default {

this.isFileInvalidated = false

let result
try {
result = await this.wallet().verifyHash(this.hash)
} catch (e) {
result = false
}
if (result) {
const transaction = await this.wallet().web3.eth.getTransaction(result)
this.creator = transaction.from
this.contract = transaction.to
const block = await this.wallet().web3.eth.getBlock(transaction.blockNumber)
// *1000 is conversion to seconds
this.timestamp = (new Date(block.timestamp * 1000)).toUTCString()
const result = await this.wallet().verifyHash(this.hash)

const signersArr = await this.wallet().proxeusFS.contract.methods.getFileSigners(this.hash).call()
Promise.all(signersArr.map(async signerAddr => {
const registrationTxBlock = await this.wallet().getRegistrationTxBlock(signerAddr)
return {
address: signerAddr,
txHash: registrationTxBlock.txHash,
block: block,
time: (new Date(registrationTxBlock.block.timestamp * 1000)).toUTCString()
}
})).then((sn) => {
this.signatures = sn
})
const transaction = await this.wallet().web3.eth.getTransaction(result)
this.creator = transaction.from
this.contract = transaction.to
const block = await this.wallet().web3.eth.getBlock(transaction.blockNumber)
// *1000 is conversion to seconds
this.timestamp = (new Date(block.timestamp * 1000)).toUTCString()

this.loading = false
this.tx = result
this.status = true
// emit event to alert parent component of status
this.$emit('updateFileState', true)
} else {
this.status = false
this.tx = null
this.loading = false
}
const signersArr = await this.wallet().proxeusFS.contract.methods.getFileSigners(this.hash).call()
Promise.all(signersArr.map(async signerAddr => {
const registrationTxBlock = await this.wallet().getRegistrationTxBlock(signerAddr)
return {
address: signerAddr,
txHash: registrationTxBlock.txHash,
block: block,
time: (new Date(registrationTxBlock.block.timestamp * 1000)).toUTCString()
}
})).then((sn) => {
this.signatures = sn
})

this.loading = false
this.tx = result
this.status = true
// emit event to alert parent component of status
this.$emit('updateFileState', true)
} catch (e) {
this.status = false
this.loading = false
this.tx = null
this.errorValidating = true
this.validationException = true

if (this.wallet().isPublicRPCUsing) {
this.errorPublicRPC = true
} else {
this.errorValidating = true
}
}
},
async hashFile (file) {
Expand Down
Loading