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
 {
1
 {
2
   "name": "xrpio",
2
   "name": "xrpio",
3
-  "version": "0.2.0",
3
+  "version": "0.2.1",
4
   "repository": {
4
   "repository": {
5
     "type": "git",
5
     "type": "git",
6
     "url": "https://gitea.nitowa.xyz/npm-packages/xrpio.git"
6
     "url": "https://gitea.nitowa.xyz/npm-packages/xrpio.git"

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

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
 import * as zlib from 'zlib'
4
 import * as zlib from 'zlib'
5
 import * as util from 'util'
5
 import * as util from 'util'
6
 import { NON_ZERO_TX_HASH } from '../util/protocol.constants'
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
 const compressB64 = async (data: string) => (await util.promisify(zlib.deflate)(Buffer.from(data, 'utf-8'))).toString('base64')
9
 const compressB64 = async (data: string) => (await util.promisify(zlib.deflate)(Buffer.from(data, 'utf-8'))).toString('base64')
10
 const decompressB64 = async (data: string) => (await util.promisify(zlib.inflate)(Buffer.from(data, 'base64'))).toString('utf-8')
10
 const decompressB64 = async (data: string) => (await util.promisify(zlib.inflate)(Buffer.from(data, 'base64'))).toString('utf-8')
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
     if (!NON_ZERO_TX_HASH.test(hash)) {
129
     if (!NON_ZERO_TX_HASH.test(hash)) {
131
       throw ERR_BAD_TX_HASH(hash)
130
       throw ERR_BAD_TX_HASH(hash)
132
     }
131
     }
133
-
134
     const tx = await this.getTransaction(hash)
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
     const memo = tx.result.Memos[0].Memo
138
     const memo = tx.result.Memos[0].Memo
136
     const memoParsed = {
139
     const memoParsed = {
137
       data: hexDecode(memo.MemoData),
140
       data: hexDecode(memo.MemoData),
156
     return await this.treeWrite(JSON.stringify(hashes), to, secret, 'N')
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
     const bad_hash = hashes.find(hash => !NON_ZERO_TX_HASH.test(hash))
163
     const bad_hash = hashes.find(hash => !NON_ZERO_TX_HASH.test(hash))
161
     if (bad_hash)
164
     if (bad_hash)
162
       throw ERR_BAD_TX_HASH(bad_hash)
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
     const payload: string = await decompressB64(memos.map(memo => memo.data).join(''))
168
     const payload: string = await decompressB64(memos.map(memo => memo.data).join(''))
166
 
169
 
167
     if (memos.some(memo => memo.format === 'N')) {
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
     return payload
174
     return payload

+ 32
- 11
test/primitives.ts View File

36
     })
36
     })
37
 
37
 
38
     it('getAccountSequence', async function(){
38
     it('getAccountSequence', async function(){
39
-        //this.skip()
40
         this.timeout(10000)
39
         this.timeout(10000)
41
         const seq = await api.getAccountSequence(sendWallet.address)
40
         const seq = await api.getAccountSequence(sendWallet.address)
42
         expect(seq).to.exist
41
         expect(seq).to.exist
44
     })
43
     })
45
 
44
 
46
     it('estimateFee', async function () {
45
     it('estimateFee', async function () {
47
-        this.timeout(2000)
46
+        this.timeout(10000)
48
         const cost = await api.estimateFee(longText)
47
         const cost = await api.estimateFee(longText)
49
         expect(cost).to.be.a('number')
48
         expect(cost).to.be.a('number')
50
         expect(cost).to.be.lessThan(50)
49
         expect(cost).to.be.lessThan(50)
53
 
52
 
54
     let txHash
53
     let txHash
55
     it('writeRaw', async function(){
54
     it('writeRaw', async function(){
56
-        //this.skip()
57
         this.timeout(15000)
55
         this.timeout(15000)
58
         txHash = await api.writeRaw({data: TEST_DATA}, receiveWallet.address, sendWallet.secret);
56
         txHash = await api.writeRaw({data: TEST_DATA}, receiveWallet.address, sendWallet.secret);
59
         expect(txHash).to.exist
57
         expect(txHash).to.exist
61
     })
59
     })
62
 
60
 
63
     it('readRaw', async function () {
61
     it('readRaw', async function () {
64
-        //this.skip()
65
         this.timeout(15000)
62
         this.timeout(15000)
66
         const memo = await api.readRaw(txHash)
63
         const memo = await api.readRaw(txHash)
67
         expect(memo).to.exist
64
         expect(memo).to.exist
68
         expect(memo.data).to.be.equal(TEST_DATA)
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
     it('readRaw bad hash', function (done){
82
     it('readRaw bad hash', function (done){
72
         this.timeout(150000)
83
         this.timeout(150000)
73
         api.readRaw("123")
84
         api.readRaw("123")
76
     })
87
     })
77
 
88
 
78
     it('treeWrite', async function(){
89
     it('treeWrite', async function(){
79
-//        this.skip()
80
         this.timeout(45000)
90
         this.timeout(45000)
81
         txHash = await api.treeWrite(longText, receiveWallet.address, sendWallet.secret)
91
         txHash = await api.treeWrite(longText, receiveWallet.address, sendWallet.secret)
82
         expect(txHash).to.exist
92
         expect(txHash).to.exist
84
     })
94
     })
85
 
95
 
86
     it('treeRead', async function(){
96
     it('treeRead', async function(){
87
-//        this.skip()
88
         this.timeout(45000)
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
     it('treeWrite XL', async function(){
117
     it('treeWrite XL', async function(){
95
-        //this.skip()
96
         this.timeout(450000)
118
         this.timeout(450000)
97
         txHash = await api.treeWrite(htmlTxt, receiveWallet.address, sendWallet.secret)
119
         txHash = await api.treeWrite(htmlTxt, receiveWallet.address, sendWallet.secret)
98
         expect(txHash).to.exist
120
         expect(txHash).to.exist
100
     })
122
     })
101
 
123
 
102
     it('treeRead XL', async function(){
124
     it('treeRead XL', async function(){
103
-        //this.skip()  
104
         this.timeout(450000)
125
         this.timeout(450000)
105
         const data = await api.treeRead([txHash])
126
         const data = await api.treeRead([txHash])
106
         expect(data).to.exist
127
         expect(data).to.exist

Loading…
Cancel
Save