Browse Source

Add functionality to verify sender on reads

master
nitowa 1 year ago
parent
commit
04dab07fb5
4 changed files with 45 additions and 20 deletions
  1. 1
    1
      package.json
  2. 2
    1
      src/util/errors.ts
  3. 10
    7
      src/xrpIO/xrpl-binding.ts
  4. 32
    11
      test/primitives.ts

+ 1
- 1
package.json View File

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "xrpio",
3
-  "version": "0.2.0",
3
+  "version": "0.2.1",
4 4
   "repository": {
5 5
     "type": "git",
6 6
     "url": "https://gitea.nitowa.xyz/npm-packages/xrpio.git"

+ 2
- 1
src/util/errors.ts View File

@@ -1 +1,2 @@
1
-export const ERR_BAD_TX_HASH = (hash:string) => new Error(`Bad tx hash format: "${hash}"`)
1
+export const ERR_BAD_TX_HASH = (hash:string) => new Error(`Bad tx hash format: "${hash}"`)
2
+export const ERR_NO_VERIFY_OWNER = (hash: string, actualAccount: string, desiredAccount: string) => new Error(`Expected tx "${hash}" to be initiated by ${desiredAccount} but was ${actualAccount}`)

+ 10
- 7
src/xrpIO/xrpl-binding.ts View File

@@ -4,7 +4,7 @@ import { Client, Payment, TxResponse, Wallet } from 'xrpl'
4 4
 import * as zlib from 'zlib'
5 5
 import * as util from 'util'
6 6
 import { NON_ZERO_TX_HASH } from '../util/protocol.constants'
7
-import { ERR_BAD_TX_HASH } from '../util/errors'
7
+import { ERR_BAD_TX_HASH, ERR_NO_VERIFY_OWNER } from '../util/errors'
8 8
 
9 9
 const compressB64 = async (data: string) => (await util.promisify(zlib.deflate)(Buffer.from(data, 'utf-8'))).toString('base64')
10 10
 const decompressB64 = async (data: string) => (await util.promisify(zlib.inflate)(Buffer.from(data, 'base64'))).toString('utf-8')
@@ -125,13 +125,16 @@ export class xrpIO {
125 125
     }
126 126
   }
127 127
 
128
-  public async readRaw(hash: string): Promise<Memo> {
129
-
128
+  public async readRaw(hash: string, verifyOwner?: string): Promise<Memo> {
130 129
     if (!NON_ZERO_TX_HASH.test(hash)) {
131 130
       throw ERR_BAD_TX_HASH(hash)
132 131
     }
133
-
134 132
     const tx = await this.getTransaction(hash)
133
+
134
+    if(verifyOwner && tx.result.Account != verifyOwner){
135
+      throw ERR_NO_VERIFY_OWNER(hash, tx.result.Account, verifyOwner)
136
+    }
137
+
135 138
     const memo = tx.result.Memos[0].Memo
136 139
     const memoParsed = {
137 140
       data: hexDecode(memo.MemoData),
@@ -156,16 +159,16 @@ export class xrpIO {
156 159
     return await this.treeWrite(JSON.stringify(hashes), to, secret, 'N')
157 160
   }
158 161
 
159
-  public async treeRead(hashes: string[]): Promise<string> {
162
+  public async treeRead(hashes: string[], verifyOwner?:string): Promise<string> {
160 163
     const bad_hash = hashes.find(hash => !NON_ZERO_TX_HASH.test(hash))
161 164
     if (bad_hash)
162 165
       throw ERR_BAD_TX_HASH(bad_hash)
163 166
 
164
-    const memos = await Promise.all(hashes.map(hash => this.readRaw(hash)))
167
+    const memos = await Promise.all(hashes.map(hash => this.readRaw(hash, verifyOwner)))
165 168
     const payload: string = await decompressB64(memos.map(memo => memo.data).join(''))
166 169
 
167 170
     if (memos.some(memo => memo.format === 'N')) {
168
-      return await this.treeRead(JSON.parse(payload))
171
+      return await this.treeRead(JSON.parse(payload), verifyOwner)
169 172
     }
170 173
 
171 174
     return payload

+ 32
- 11
test/primitives.ts View File

@@ -36,7 +36,6 @@ describe('XRPIO', () => {
36 36
     })
37 37
 
38 38
     it('getAccountSequence', async function(){
39
-        //this.skip()
40 39
         this.timeout(10000)
41 40
         const seq = await api.getAccountSequence(sendWallet.address)
42 41
         expect(seq).to.exist
@@ -44,7 +43,7 @@ describe('XRPIO', () => {
44 43
     })
45 44
 
46 45
     it('estimateFee', async function () {
47
-        this.timeout(2000)
46
+        this.timeout(10000)
48 47
         const cost = await api.estimateFee(longText)
49 48
         expect(cost).to.be.a('number')
50 49
         expect(cost).to.be.lessThan(50)
@@ -53,7 +52,6 @@ describe('XRPIO', () => {
53 52
 
54 53
     let txHash
55 54
     it('writeRaw', async function(){
56
-        //this.skip()
57 55
         this.timeout(15000)
58 56
         txHash = await api.writeRaw({data: TEST_DATA}, receiveWallet.address, sendWallet.secret);
59 57
         expect(txHash).to.exist
@@ -61,13 +59,26 @@ describe('XRPIO', () => {
61 59
     })
62 60
 
63 61
     it('readRaw', async function () {
64
-        //this.skip()
65 62
         this.timeout(15000)
66 63
         const memo = await api.readRaw(txHash)
67 64
         expect(memo).to.exist
68 65
         expect(memo.data).to.be.equal(TEST_DATA)
69 66
     })
70 67
 
68
+    it('verifyOwner readRaw', async function (){
69
+        this.timeout(15000)
70
+        const memo = await api.readRaw(txHash, sendWallet.address)
71
+        expect(memo).to.exist
72
+        expect(memo.data).to.be.equal(TEST_DATA)
73
+    })
74
+
75
+    it('verifyOwner readRaw bad owner', function (done){
76
+        this.timeout(15000)
77
+        api.readRaw(txHash, "not the owner")
78
+        .then(_ => done(new Error('Expected error but succeeded')))
79
+        .catch(_ => done())
80
+    })
81
+
71 82
     it('readRaw bad hash', function (done){
72 83
         this.timeout(150000)
73 84
         api.readRaw("123")
@@ -76,7 +87,6 @@ describe('XRPIO', () => {
76 87
     })
77 88
 
78 89
     it('treeWrite', async function(){
79
-//        this.skip()
80 90
         this.timeout(45000)
81 91
         txHash = await api.treeWrite(longText, receiveWallet.address, sendWallet.secret)
82 92
         expect(txHash).to.exist
@@ -84,15 +94,27 @@ describe('XRPIO', () => {
84 94
     })
85 95
 
86 96
     it('treeRead', async function(){
87
-//        this.skip()
88 97
         this.timeout(45000)
89
-        txHash = await api.treeRead([txHash])
90
-        expect(txHash).to.exist
91
-        expect(txHash).to.be.equal(longText)
98
+        const data = await api.treeRead([txHash])
99
+        expect(data).to.exist
100
+        expect(data).to.be.equal(longText)
101
+    })
102
+
103
+    it('treeRead verify owner', async function(){
104
+        this.timeout(45000)
105
+        const data = await api.treeRead([txHash], sendWallet.address)
106
+        expect(data).to.exist
107
+        expect(data).to.be.equal(longText)
108
+    })
109
+
110
+    it('verifyOwner treeRead bad owner', function(done){
111
+        this.timeout(45000)
112
+        api.treeRead([txHash], "not the owner")
113
+        .then(_ => done(new Error('Expected error but succeeded')))
114
+        .catch(_ => done())
92 115
     })
93 116
 
94 117
     it('treeWrite XL', async function(){
95
-        //this.skip()
96 118
         this.timeout(450000)
97 119
         txHash = await api.treeWrite(htmlTxt, receiveWallet.address, sendWallet.secret)
98 120
         expect(txHash).to.exist
@@ -100,7 +122,6 @@ describe('XRPIO', () => {
100 122
     })
101 123
 
102 124
     it('treeRead XL', async function(){
103
-        //this.skip()  
104 125
         this.timeout(450000)
105 126
         const data = await api.treeRead([txHash])
106 127
         expect(data).to.exist

Loading…
Cancel
Save