validate who+type in feed tangles

This commit is contained in:
Andre Staltz 2023-04-17 15:57:11 +03:00
parent 5883e1df21
commit 0917361305
3 changed files with 98 additions and 1 deletions

View File

@ -90,6 +90,22 @@ function validateTangle(msg, tangle, tangleId) {
// prettier-ignore
return new Error('invalid message: prev must be an array, on feed: ' + msg.metadata.who);
}
if (typeof depth !== 'number') {
// prettier-ignore
return new Error('invalid message: depth must be a number, on feed: ' + msg.metadata.who);
}
if (tangle.isFeed()) {
const { type, who } = tangle.getFeed()
if (type !== msg.metadata.type) {
// prettier-ignore
return new Error(`invalid message: type "${msg.metadata.type}" does not match feed type "${type}"`)
}
if (who !== msg.metadata.who) {
// prettier-ignore
return new Error(`invalid message: who "${msg.metadata.who}" does not match feed who "${who}"`)
}
}
let minDiff = Infinity
for (const p of prev) {
if (typeof p !== 'string') {
// prettier-ignore
@ -106,10 +122,16 @@ function validateTangle(msg, tangle, tangleId) {
}
const prevDepth = tangle.getDepth(p)
if (prevDepth >= depth) {
const diff = depth - prevDepth
if (diff <= 0) {
// prettier-ignore
return new Error('invalid message: depth of prev ' + p + ' is not lower, on feed: ' + msg.metadata.who);
}
if (diff < minDiff) minDiff = diff
}
if (minDiff !== 1) {
// prettier-ignore
return new Error('invalid message: depth must be the largest prev depth plus one');
}
}

View File

@ -2,6 +2,10 @@
* @typedef {import("./plugin").Rec} Rec
*/
/**
* @typedef {import("./feed-v1").Msg} Msg
*/
function lipmaa(n) {
let m = 1
let po3 = 3
@ -45,6 +49,11 @@ class Tangle {
*/
#rootHash
/**
* @type {Msg}
*/
#rootMsg
/**
* @type {Set<string>}
*/
@ -89,6 +98,7 @@ class Tangle {
this.#tips.add(msgHash)
this.#perDepth.set(0, [msgHash])
this.#depth.set(msgHash, 0)
this.#rootMsg = msg
} else if (tangles[this.#rootHash]) {
this.#tips.add(msgHash)
const prev = tangles[this.#rootHash].prev
@ -162,6 +172,18 @@ class Tangle {
return this.#depth.get(msgHash) ?? -1
}
isFeed() {
if (this.#rootMsg.content) return false
const metadata = this.#rootMsg.metadata
return metadata.size === 0 && metadata.proof === ''
}
getFeed() {
if (!this.isFeed()) return null
const { type, who } = this.#rootMsg.metadata
return { type, who }
}
#shortestPathToRoot(msgHash) {
const path = []
let current = msgHash

View File

@ -176,3 +176,56 @@ tape('invalid msg with unknown prev', (t) => {
t.end()
})
})
tape('invalid feed msg with a different who', (t) => {
const keysA = generateKeypair('alice')
const keysB = generateKeypair('bob')
const rootMsg = FeedV1.createRoot(keysA, 'post')
const rootHash = FeedV1.getMsgHash(rootMsg)
const feedTangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
const msg = FeedV1.create({
keys: keysB,
content: { text: 'Hello world!' },
type: 'post',
tangles: {
[rootHash]: feedTangle,
},
when: 1652030002000,
})
const msgHash = FeedV1.getMsgHash(msg)
FeedV1.validate(msg, feedTangle, msgHash, rootHash, (err) => {
t.match(err.message, /who ".*" does not match feed who/, 'invalid feed msg')
t.end()
})
})
tape('invalid feed msg with a different type', (t) => {
const keysA = generateKeypair('alice')
const rootMsg = FeedV1.createRoot(keysA, 'post')
const rootHash = FeedV1.getMsgHash(rootMsg)
const feedTangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
const msg = FeedV1.create({
keys: keysA,
content: { text: 'Hello world!' },
type: 'comment',
tangles: {
[rootHash]: feedTangle,
},
when: 1652030002000,
})
const msgHash = FeedV1.getMsgHash(msg)
FeedV1.validate(msg, feedTangle, msgHash, rootHash, (err) => {
t.match(
err.message,
/type "comment" does not match feed type "post"/,
'invalid feed msg'
)
t.end()
})
})