diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml deleted file mode 100644 index 7ea0e5f..0000000 --- a/.github/workflows/node.js.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: CI - -on: - push: - branches: [master] - pull_request: - branches: [master] - -jobs: - test: - strategy: - matrix: - node-version: [16.x, 18.x, 20.x] - os: [ubuntu-latest] - - runs-on: ${{ matrix.os }} - timeout-minutes: 2 - - steps: - - name: Checkout the repo - uses: actions/checkout@v2 - - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: npm install - - run: npm test diff --git a/.woodpecker.yaml b/.woodpecker.yaml new file mode 100644 index 0000000..d254f8d --- /dev/null +++ b/.woodpecker.yaml @@ -0,0 +1,13 @@ +matrix: + NODE_VERSION: + - 18 + - 20 + +steps: + test: + when: + event: [push] + image: node:${NODE_VERSION} + commands: + - npm install + - npm test \ No newline at end of file diff --git a/README.md b/README.md index edad547..7a3a5ec 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ -# ppppp-promise +# pzp-promise -**Work in progress** +PZP promises are tokens that authorize others to gain something -Not to be confused with JavaScript Promises. PPPPP Promises are tokens that can be redeemed by other peers, which authorize the execution of some code on the peer that issued the promise. +Not to be confused with JavaScript Promises. PZP promises are tokens that can be redeemed by other peers, which authorize the execution of some code on the peer that issued the promise. + +## Installation + +``` +npm install pzp-promise +``` diff --git a/lib/index.js b/lib/index.js index b84481a..45f4cd1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,9 +6,9 @@ const bs58 = require('bs58') const b4a = require('b4a') /** - * @typedef {ReturnType} PPPPPDB - * @typedef {ReturnType} PPPPPSet - * @typedef {import('ppppp-db/msg-v4').AccountAdd} AccountAdd + * @typedef {ReturnType} PZPDB + * @typedef {ReturnType} PZPSet + * @typedef {import('pzp-db/msg-v4').AccountAdd} AccountAdd * @typedef {Buffer | Uint8Array} B4A * @typedef {{global: {path: string}}} ExpectedConfig * @typedef {{global: {path?: string}}} Config @@ -33,7 +33,7 @@ function assertValidConfig(config) { } /** - * @param {{ db: PPPPPDB; set: PPPPPSet }} peer + * @param {{ db: PZPDB; set: PZPSet }} peer * @param {Config} config */ function initPromise(peer, config) { @@ -143,23 +143,28 @@ function initPromise(peer, config) { peer.set.load(myAccountID, (err) => { // prettier-ignore - if (err) return cb(new Error(`Failed to load ppppp-set with account "${myAccountID}" when executing follow promise`, { cause: err })) - if (peer.set.has('follows', theirAccountID)) { - promises.delete(token) - cb(null, false) - return - } else { - peer.set.add('follows', theirAccountID, (err, _) => { - // prettier-ignore - if (err) return cb(new Error(`Failed to follow account "${theirAccountID}" in ppppp-set from account "${myAccountID}" when executing follow promise`, { cause: err })) + if (err) return cb(new Error(`Failed to load pzp-set with account "${myAccountID}" when executing follow promise`, { cause: err })) + + peer.set.has('follows', theirAccountID, null, (err, peerHas) => { + if (err) return cb(err) + + if (peerHas) { promises.delete(token) - save((err, _) => { + cb(null, false) + return + } else { + peer.set.add('follows', theirAccountID, (err, _) => { // prettier-ignore - if (err) return cb(new Error('Failed to save promise file when executing follow promise', { cause: err })) - cb(null, true) + if (err) return cb(new Error(`Failed to follow account "${theirAccountID}" in pzp-set from account "${myAccountID}" when executing follow promise`, { cause: err })) + promises.delete(token) + save((err, _) => { + // prettier-ignore + if (err) return cb(new Error('Failed to save promise file when executing follow promise', { cause: err })) + cb(null, true) + }) }) - }) - } + } + }) }) } @@ -237,21 +242,26 @@ function initPromise(peer, config) { curve: /**@type {const}*/ ('ed25519'), public: addition.key.bytes, } - if (peer.db.account.has({ account, keypair })) { - cb(null, false) - return - } + peer.db.account.has({ account, keypair }, (err, accountHas) => { + if (err) return cb(err) - peer.db.account.add( - { account, keypair, consent: addition.consent }, - (err, rec) => { - if (err) return cb(err) - promises.delete(token) - save(() => { - cb(null, true) - }) + if (accountHas) { + cb(null, false) + return } - ) + + if (!addition.consent) return cb(Error('Consent disappeared')) + peer.db.account.add( + { account, keypair, consent: addition.consent }, + (err, rec) => { + if (err) return cb(err) + promises.delete(token) + save(() => { + cb(null, true) + }) + } + ) + }) } /** diff --git a/package.json b/package.json index 7e6c814..1ae9c33 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "ppppp-promise", + "name": "pzp-promise", "version": "0.0.1", - "description": "PPPPP promises are tokens that authorize others to gain something", - "homepage": "https://github.com/staltz/ppppp-promise", + "description": "PZP promises are tokens that authorize others to gain something", + "homepage": "https://codeberg.org/pzp/pzp-promise", "repository": { "type": "git", - "url": "git://github.com/staltz/ppppp-promise.git" + "url": "git@codeberg.org:pzp/pzp-promise.git" }, "author": "Andre 'Staltz' Medeiros ", "license": "MIT", @@ -32,10 +32,10 @@ "@types/node": "^20.2.5", "c8": "^7.11.0", "husky": "^4.3.0", - "ppppp-caps": "github:staltz/ppppp-caps", - "ppppp-db": "github:staltz/ppppp-db", - "ppppp-keypair": "github:staltz/ppppp-keypair", - "ppppp-set": "github:staltz/ppppp-set", + "pzp-caps": "^1.0.0", + "pzp-db": "^1.0.1", + "pzp-keypair": "^1.0.0", + "pzp-set": "^1.0.0", "prettier": "^2.6.2", "pretty-quick": "^3.1.3", "rimraf": "^5.0.1", diff --git a/test/index.test.js b/test/index.test.js index 5b5b447..ed4952b 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -5,21 +5,21 @@ const os = require('node:os') const fs = require('node:fs') const p = require('node:util').promisify const rimraf = require('rimraf') -const Keypair = require('ppppp-keypair') -const caps = require('ppppp-caps') +const Keypair = require('pzp-keypair') +const caps = require('pzp-caps') async function setup() { setup.counter ??= 0 setup.counter += 1 - const path = Path.join(os.tmpdir(), 'ppppp-promise-' + setup.counter) + const path = Path.join(os.tmpdir(), 'pzp-promise-' + setup.counter) rimraf.sync(path) const keypair = Keypair.generate('ed25519', 'alice') const peer = require('secret-stack/bare')() .use(require('secret-stack/plugins/net')) .use(require('secret-handshake-ext/secret-stack')) - .use(require('ppppp-db')) - .use(require('ppppp-set')) + .use(require('pzp-db')) + .use(require('pzp-set')) .use(require('../lib')) .call(null, { shse: { caps }, @@ -71,12 +71,12 @@ test('follow()', async (t) => { const contentsBefore = fs.readFileSync(file, 'utf-8') assert.strictEqual(contentsBefore, JSON.stringify([[token, promise]])) - assert.equal(peer.set.has('follows', 'FRIEND_ID'), false, 'not following') + assert.equal(await p(peer.set.has)('follows', 'FRIEND_ID', null), false, 'not following') const result1 = await p(peer.promise.follow)(token, 'FRIEND_ID') assert.strictEqual(result1, true) - assert.equal(peer.set.has('follows', 'FRIEND_ID'), true, 'following') + assert.equal(await p(peer.set.has)('follows', 'FRIEND_ID', null), true, 'following') const contentsAfter = fs.readFileSync(file, 'utf-8') assert.strictEqual(contentsAfter, '[]') @@ -102,7 +102,11 @@ test('accountAdd()', async (t) => { const contentsBefore = fs.readFileSync(file, 'utf-8') assert.strictEqual(contentsBefore, JSON.stringify([[token, promise]])) - const dbBefore = [...peer.db.msgs()].map(({ data }) => data) + const msgs = [] + for await (msg of peer.db.msgs()) { + msgs.push(msg) + } + const dbBefore = msgs.map(({ data }) => data) assert.equal(dbBefore.length, 1) assert.equal(dbBefore[0].action, 'add') assert.equal(dbBefore[0].key.algorithm, 'ed25519') @@ -122,7 +126,11 @@ test('accountAdd()', async (t) => { }) assert.strictEqual(result1, true) - const dbAfter = [...peer.db.msgs()].map(({ data }) => data) + const msgs2 = [] + for await (msg of peer.db.msgs()) { + msgs2.push(msg) + } + const dbAfter = msgs2.map(({ data }) => data) assert.equal(dbAfter.length, 2) assert.equal(dbAfter[0].action, 'add') assert.equal(dbAfter[0].key.algorithm, 'ed25519')