diff --git a/README.md b/README.md index bfc95018..1aea54de 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,15 @@ the [releases tab](https://github.com/ethersphere/swarm-cli/releases). - [Uploading a File](#uploading-a-file) - [Creating an Identity](#creating-an-identity) - [Uploading to a Feed](#uploading-to-a-feed) - - [Upload file with ACT](#upload-file-with-act) - - [Download file with ACT](#download-file-with-act) - - [Create grantees list](#create-grantees-list) - - [Get grantees list](#get-grantees-list) - - [Patch grantees list](#patch-grantees-list) + - [Access control trie (ACT)](#access-control-trie-(act)) + - [Initialize ACT](#initialize-act) + - [Grant access to a certain grantee](#grant-access-to-a-certain-grantee) + - [Revoke access from a certain grantee](#revoke-access-from-a-certain-grantee) + - [Show list of grantee lists](#show-list-of-grantee-lists) + - [Show grantees in a certain grantee list](#show-grantees-in-a-certain-grantee-list) + - [Get the list of events for a certain grantee list](#get-the-list-of-events-for-a-certain-grantee-list) + - [Upload a file with ACT](#upload-a-file-with-act) + - [Download a file with ACT](#download-a-file-with-act) - [Description](#description) - [Installation](#installation) - [From npm](#from-npm) @@ -149,11 +153,6 @@ swarm-cli access history --list-name swarm-cli upload --share-with ``` -##### [DEPRECATED] -```sh -swarm-cli upload --act --stamp -``` - ### Download a file with ACT `token` constructed from the owner's public key and the history address @@ -162,57 +161,6 @@ swarm-cli upload --act --stamp swarm-cli download --access ``` -##### [DEPRECATED] -```sh -swarm-cli download --act --act-history-address --act-publisher -``` - -### Create a grantees list [DEPRECATED] - -```sh -swarm-cli grantee create grantees.json --stamp -``` - -`grantees.json`: - -```json -{ "grantees": [ - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" -] -} -``` - -### Get a grantees list [DEPRECATED] - -```sh -swarm-cli grantee get -``` - -### Patch a grantees list [DEPRECATED] - -```sh -swarm-cli grantee patch grantees-patch.json \ - --reference \ - --history \ - --stamp -``` - -`grantees-patch.json`: - -```json -{ - "add": [ - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e7" - ], - "revoke": [ - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" - ] -} -``` - # Description > Manage your Bee node and interact with the Swarm network via the CLI @@ -269,7 +217,6 @@ stamp Buy, list and show postage stamps pss Send, receive, or subscribe to PSS messages manifest Operate on manifests utility Utility commands for managing wallets -grantee Create, Get, Patch grantee list history Get upload history access Share access to your uploaded files/folders diff --git a/src/command/download.ts b/src/command/download.ts index fb817d25..774ce23b 100644 --- a/src/command/download.ts +++ b/src/command/download.ts @@ -32,14 +32,7 @@ export class Download extends RootCommand implements LeafCommand { let response: Bytes let nameOverride: string | undefined - if (this.manifestDownload.act) { - const responseAct = await this.bee.downloadFile(this.address.hash, this.manifestDownload.destination, { - actPublisher: this.manifestDownload.actPublisher, - actHistoryAddress: this.manifestDownload.actHistoryAddress, - actTimestamp: this.manifestDownload.actTimestamp, - }) - response = responseAct.data - } else if (this.manifestDownload.access) { + if (this.manifestDownload.access) { const [publisher, historyAddress] = this.manifestDownload.access.split(':') const responseAct = await this.bee.downloadFile(this.address.hash, this.manifestDownload.destination, { actPublisher: publisher, diff --git a/src/command/grantee/create.ts b/src/command/grantee/create.ts deleted file mode 100644 index bc4dccc8..00000000 --- a/src/command/grantee/create.ts +++ /dev/null @@ -1,40 +0,0 @@ -import fs from 'fs' -import { Argument, LeafCommand, Option } from 'furious-commander' -import { stampProperties } from '../../utils/option' -import { createKeyValue } from '../../utils/text' -import { GranteeCommand } from './grantee-command' - -export class Create extends GranteeCommand implements LeafCommand { - public readonly name = 'create' - public readonly description = 'Create grantee list' - private actReqHeaders: Record = {} - - @Argument({ - key: 'path', - description: 'Path to the file with grantee list', - required: true, - autocompletePath: true, - conflicts: 'stdin', - }) - public path!: string - - @Option({ key: 'stdin', type: 'boolean', description: 'Take data from standard input', conflicts: 'path' }) - public stdin!: boolean - - @Option(stampProperties) - public stamp!: string - - public async run(): Promise { - super.init() - this.actReqHeaders = { - 'Swarm-Act': 'true', - } - const granteesFile = fs.readFileSync(this.path, 'utf8') - const createGrantees = JSON.parse(granteesFile) - const grantees = createGrantees.grantees - - const response = await this.bee.createGrantees(this.stamp, grantees) - this.console.log(createKeyValue('Grantee reference', response.ref.toHex())) - this.console.log(createKeyValue('Grantee history reference', response.historyref.toHex())) - } -} diff --git a/src/command/grantee/get.ts b/src/command/grantee/get.ts deleted file mode 100644 index 44dd8105..00000000 --- a/src/command/grantee/get.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Argument, LeafCommand } from 'furious-commander' -import { createKeyValue } from '../../utils/text' -import { GranteeCommand } from './grantee-command' - -export class Get extends GranteeCommand implements LeafCommand { - public readonly name = 'get' - public readonly description = 'Get grantee list' - - @Argument({ - key: 'reference', - description: 'Grantee list reference', - required: true, - conflicts: 'stdin', - }) - public reference!: string - - public async run(): Promise { - super.init() - const response = await this.bee.getGrantees(this.reference) - this.console.log( - createKeyValue('Grantee public keys', response.grantees.map(grantee => grantee.toCompressedHex()).join('\n')), - ) - } -} diff --git a/src/command/grantee/grantee-command.ts b/src/command/grantee/grantee-command.ts deleted file mode 100644 index f3ab65b6..00000000 --- a/src/command/grantee/grantee-command.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { deprecationWarningText } from '../../utils/text' -import { RootCommand } from '../root-command' - -export class GranteeCommand extends RootCommand { - protected init(): void { - super.init() - this.console.log( - deprecationWarningText( - '`grantee` commands are deprecated and will be removed in the future. Please use `access` commands instead.', - ), - ) - } -} diff --git a/src/command/grantee/index.ts b/src/command/grantee/index.ts deleted file mode 100644 index 336e8a2a..00000000 --- a/src/command/grantee/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GroupCommand } from 'furious-commander' -import { Create } from './create' -import { Get } from './get' -import { Patch } from './patch' - -export class Grantee implements GroupCommand { - public readonly name = 'grantee' - - public readonly description = 'Create, Get, Patch grantee list' - - public subCommandClasses = [Create, Get, Patch] -} diff --git a/src/command/grantee/patch.ts b/src/command/grantee/patch.ts deleted file mode 100644 index 7376ebc2..00000000 --- a/src/command/grantee/patch.ts +++ /dev/null @@ -1,58 +0,0 @@ -import fs from 'fs' -import { Argument, LeafCommand, Option } from 'furious-commander' -import { stampProperties } from '../../utils/option' -import { createKeyValue } from '../../utils/text' -import { GranteeCommand } from './grantee-command' - -export class Patch extends GranteeCommand implements LeafCommand { - public readonly name = 'patch' - public readonly description = 'Patch grantee list' - private actReqHeaders: Record = {} - - @Argument({ - key: 'path', - description: 'Path to the JSON file with grantee patch (add, revoke)', - required: true, - autocompletePath: true, - conflicts: 'stdin', - }) - public path!: string - - @Option({ key: 'stdin', type: 'boolean', description: 'Take data from standard input', conflicts: 'path' }) - public stdin!: boolean - - @Option(stampProperties) - public stamp!: string - - @Option({ - key: 'reference', - type: 'string', - description: 'Encrypted grantee list reference with 128 characters length', - length: 128, - required: true, - }) - public eref!: string - - @Option({ - key: 'history', - type: 'string', - description: 'Swarm address reference to the ACT history entry', - length: 64, - required: true, - }) - public history!: string - - public async run(): Promise { - super.init() - this.actReqHeaders = { - 'Swarm-Act': 'true', - 'Swarm-Act-Timestamp': Date.now().toString(), - } - const patchContent = fs.readFileSync(this.path, 'utf8') - const patch = JSON.parse(patchContent) - - const response = await this.bee.patchGrantees(this.stamp, this.eref, this.history, patch, this.actReqHeaders) - this.console.log(createKeyValue('Grantee reference', response.ref.toHex())) - this.console.log(createKeyValue('Grantee history reference', response.historyref.toHex())) - } -} diff --git a/src/command/manifest/download.ts b/src/command/manifest/download.ts index b1311cbd..c7b76fde 100644 --- a/src/command/manifest/download.ts +++ b/src/command/manifest/download.ts @@ -6,7 +6,6 @@ import { join, parse } from 'path' import { exit } from 'process' import { directoryExists } from '../../utils' import { BzzAddress, makeBzzAddress } from '../../utils/bzz-address' -import { deprecationWarningText } from '../../utils/text' import { RootCommand } from '../root-command' export class Download extends RootCommand implements LeafCommand { @@ -24,34 +23,12 @@ export class Download extends RootCommand implements LeafCommand { @Option({ key: 'stdout', type: 'boolean', description: 'Print to stdout (single files only)' }) public stdout!: boolean - @Option({ key: 'access', type: 'string', description: 'Download using grantee list', conflicts: 'act' }) + @Option({ key: 'access', type: 'string', description: 'Download using grantee list' }) public access!: string - @Option({ key: 'act', type: 'boolean', description: 'Download with ACT', default: false }) - public act!: boolean - - @Option({ key: 'act-timestamp', type: 'string', description: 'ACT history timestamp', default: '1' }) - public actTimestamp!: string - - // required if act is true - @Option({ key: 'act-history-address', type: 'string', description: 'ACT history address', required: { when: 'act' } }) - public actHistoryAddress!: string - - // required if act is true - @Option({ key: 'act-publisher', type: 'string', description: 'ACT publisher', required: { when: 'act' } }) - public actPublisher!: string - public async run(): Promise { super.init() - if (this.act) { - this.console.log( - deprecationWarningText( - '--act option is deprecated and will be removed in future versions. Please use --access option with publisher:historyAddress format instead.', - ), - ) - } - // can be already set from other command if (!this.address) { this.address = await makeBzzAddress(this.bee, this.bzzUrl) diff --git a/src/command/upload.ts b/src/command/upload.ts index 09c61a90..b63d0500 100644 --- a/src/command/upload.ts +++ b/src/command/upload.ts @@ -17,7 +17,7 @@ import { getMime } from '../utils/mime' import { stampProperties } from '../utils/option' import { printQRCodeWithLabel } from '../utils/qr' import { createSpinner } from '../utils/spinner' -import { createKeyValue, deprecationWarningText, warningSymbol, warningText } from '../utils/text' +import { createKeyValue, warningSymbol, warningText } from '../utils/text' import { publicUrl } from '../utils/url' import { RootCommand } from './root-command' import { VerbosityLevel } from './root-command/command-log' @@ -51,15 +51,6 @@ export class Upload extends RootCommand implements LeafCommand { @Option({ key: 'deferred', type: 'boolean', description: 'Do not wait for network sync', default: true }) public deferred!: boolean - @Option({ - key: 'act', - type: 'boolean', - description: 'Upload with ACT', - default: false, - required: { when: 'act-history-address' }, - }) - public act!: boolean - @Option({ key: 'share-with', type: 'string', @@ -68,9 +59,6 @@ export class Upload extends RootCommand implements LeafCommand { }) public shareWith!: string - @Option({ key: 'act-history-address', type: 'string', description: 'ACT history address' }) - public optHistoryAddress!: string - @Option({ key: 'sync', type: 'boolean', @@ -149,14 +137,6 @@ export class Upload extends RootCommand implements LeafCommand { public async run(usedFromOtherCommand = false): Promise { super.init() - if (this.act || this.optHistoryAddress) { - this.console.log( - deprecationWarningText( - '--act and --act-history-address options are deprecated and will be removed in future versions. Please use --share-with option instead.', - ), - ) - } - if (await this.hasUnsupportedGatewayOptions()) { exit(1) } @@ -236,7 +216,7 @@ export class Upload extends RootCommand implements LeafCommand { printQRCodeWithLabel(publicUrl(url), 'QR for URL', this.console) } - if (this.shareWith) { + if (this.usingACT()) { this.addNewAccessHistoryEvent() await this.printShareInstructions() } @@ -486,7 +466,7 @@ export class Upload extends RootCommand implements LeafCommand { if (this.usingACT()) { this.console.error('You are trying to upload to the gateway which does not support ACT.') - this.console.error('Please try again without the --act option.') + this.console.error('Please try again without the --share-with option.') return true } @@ -587,7 +567,7 @@ export class Upload extends RootCommand implements LeafCommand { } private usingACT(): boolean { - return this.act || Boolean(this.shareWith) + return Boolean(this.shareWith) } private addNewAccessHistoryEvent() { @@ -624,14 +604,6 @@ export class Upload extends RootCommand implements LeafCommand { private prepareACTUploadOptions(uploadOptions: FileUploadOptions): FileUploadOptions { const options = { ...uploadOptions } - if (this.act) { - options.act = this.act - - if (this.optHistoryAddress) { - options.actHistoryAddress = this.optHistoryAddress - } - } - if (this.shareWith) { const accessHistory = new AccessHistory(this.commandConfig, this.console) const lastHistoryEvent = accessHistory.getLatestEvent(this.shareWith) diff --git a/src/config.ts b/src/config.ts index a1c4d1a9..05099e01 100644 --- a/src/config.ts +++ b/src/config.ts @@ -5,7 +5,6 @@ import { Addresses } from './command/addresses' import { Cheque } from './command/cheque' import { Download } from './command/download' import { Feed } from './command/feed' -import { Grantee } from './command/grantee' import { Hash } from './command/hash' import { History } from './command/history' import { Identity } from './command/identity' @@ -125,7 +124,6 @@ export const rootCommandClasses = [ Stake, Wallet, Utility, - Grantee, Quickstart, History, Access, diff --git a/test/command/download.spec.ts b/test/command/download.spec.ts index b063a54e..931eb181 100644 --- a/test/command/download.spec.ts +++ b/test/command/download.spec.ts @@ -21,28 +21,6 @@ describeCommand('Test Download command', ({ consoleMessages, getLastMessage }) = expect(consoleMessages[0]).toContain('Hello Swarm!') }) - it('should download with act and print to stdout', async () => { - const addressesInvocation = await invokeTestCli(['addresses']) - const addressesCommand = addressesInvocation.runnable as Addresses - const uploadInvocation = await invokeTestCli(['upload', 'test/message.txt', '--act', ...getStampOption()]) - const uploadCommand = uploadInvocation.runnable as Upload - const ref = uploadCommand.result.getOrThrow().toHex() - const history = uploadCommand.historyAddress.getOrThrow().toHex() - const publicKey = addressesCommand.nodeAddresses.publicKey.toHex() - consoleMessages.length = 0 - await invokeTestCli([ - 'download', - ref, - '--act', - '--act-history-address', - history, - '--act-publisher', - publicKey, - '--stdout', - ]) - expect(consoleMessages[0]).toContain('Hello Swarm!') - }) - describe('when --access option is used', () => { afterEach(() => { const historyFilePath = `${__dirname}/../testconfig/access-history.json` diff --git a/test/command/grantee.spec.ts b/test/command/grantee.spec.ts deleted file mode 100644 index b7efb251..00000000 --- a/test/command/grantee.spec.ts +++ /dev/null @@ -1,89 +0,0 @@ -import * as fs from 'fs' -import * as path from 'path' -import { describeCommand, invokeTestCli } from '../utility' -import { getStampOption } from '../utility/stamp' - -const stripAnsi = (str: string) => - str.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '') - -function extractReferences(consoleMessages: string[]): [string, string] { - const nonAnsiConsoleMessages = consoleMessages.map(stripAnsi) - const referenceMatch = nonAnsiConsoleMessages - .find(m => m.includes('Grantee reference:')) - ?.match(/Grantee reference: (\w{128})/) - const historyMatch = nonAnsiConsoleMessages - .find(m => m.includes('Grantee history reference:')) - ?.match(/Grantee history reference: (\w{64})/) - - return [referenceMatch ? referenceMatch[1] : '', historyMatch ? historyMatch[1] : ''] -} - -function extractPublicKeys(consoleMessages: string[]): string[] { - const publicKeysStringPrefix = 'Grantee public keys: ' - const publicKeysString = consoleMessages.map(stripAnsi).find(msg => msg.startsWith(publicKeysStringPrefix)) - - return publicKeysString ? publicKeysString.replace(publicKeysStringPrefix, '').split('\n') : [] -} - -describeCommand('Test Grantee command', ({ consoleMessages }) => { - let grantees = { grantees: [] } - beforeAll(() => { - grantees = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../../test/grantees.json'), 'utf-8')) - }) - - beforeEach(() => { - consoleMessages.length = 0 - }) - - it('should create', async () => { - await invokeTestCli(['grantee', 'create', 'test/grantees.json', ...getStampOption()]) - const [reference, history] = extractReferences(consoleMessages) - expect(reference).not.toBeNull() - expect(history).not.toBeNull() - }) - - it('should get', async () => { - await invokeTestCli(['grantee', 'create', 'test/grantees.json', ...getStampOption()]) - const [reference] = extractReferences(consoleMessages) - consoleMessages.length = 0 - - await invokeTestCli(['grantee', 'get', reference]) - const publicKeys = extractPublicKeys(consoleMessages) - - expect(publicKeys.length).toBe(grantees.grantees.length) - - publicKeys.forEach((key, index) => { - expect(key).toBe(grantees.grantees[index]) - }) - }) - - it('should patch', async () => { - await invokeTestCli(['grantee', 'create', 'test/grantees.json', ...getStampOption()]) - const [reference, history] = extractReferences(consoleMessages) - consoleMessages.length = 0 - - await new Promise(resolve => setTimeout(resolve, 1000)) - await invokeTestCli([ - 'grantee', - 'patch', - 'test/grantees-patch.json', - '--reference', - reference, - '--history', - history, - ...getStampOption(), - ]) - await new Promise(resolve => setTimeout(resolve, 1000)) - const [referenceAfterPatch, historyAfterPatch] = extractReferences(consoleMessages) - - expect(referenceAfterPatch).not.toBeNull() - expect(historyAfterPatch).not.toBeNull() - consoleMessages.length = 0 - - await new Promise(resolve => setTimeout(resolve, 1000)) - await invokeTestCli(['grantee', 'get', referenceAfterPatch]) - const publicKeys = extractPublicKeys(consoleMessages) - // Original count: 3. Added one, revoked (deleted) two, remaining two grantees. - expect(publicKeys.length).toBe(2) - }) -}) diff --git a/test/command/upload.spec.ts b/test/command/upload.spec.ts index b9fbfe38..51802b7f 100644 --- a/test/command/upload.spec.ts +++ b/test/command/upload.spec.ts @@ -62,52 +62,6 @@ describeCommand( expect(uploadCommand.result.getOrThrow().toHex()).toHaveLength(128) }) - describe('when --act flag provided', () => { - it('should upload file with act', async () => { - const commandBuilder = await invokeTestCli(['upload', 'README.md', '--act', ...getStampOption()]) - const [ref, his] = actUpload(commandBuilder) - expect(ref).toHaveLength(64) - expect(his).toHaveLength(64) - }) - - it('should upload file with act and history', async () => { - const commandBuilder1 = await invokeTestCli(['upload', 'README.md', '--act', ...getStampOption()]) - const [ref1, his1] = actUpload(commandBuilder1) - expect(ref1).toHaveLength(64) - expect(his1).toHaveLength(64) - - // Upload same file with the same history address - const commandBuilder2 = await invokeTestCli([ - 'upload', - 'README.md', - '--act', - '--act-history-address', - his1, - ...getStampOption(), - ]) - const [ref2, his2] = actUpload(commandBuilder2) - expect(ref2).toHaveLength(64) - expect(his2).toHaveLength(64) - expect(ref1).toBe(ref2) // Same reference - expect(his1).toBe(his2) // Same history address - - // Upload another file with the same history address - const commandBuilder3 = await invokeTestCli([ - 'upload', - 'test/message.txt', - '--act', - '--act-history-address', - his1, - ...getStampOption(), - ]) - const [ref3, his3] = actUpload(commandBuilder3) - expect(ref3).toHaveLength(64) - expect(his3).toHaveLength(64) - expect(ref1).not.toBe(ref3) // Not same reference - expect(his1).toBe(his3) // Same history address - }) - }) - describe('when --share-with flag provided', () => { afterEach(() => { const historyFilePath = `${__dirname}/../testconfig/upload-access-history.json` diff --git a/test/grantees-patch.json b/test/grantees-patch.json deleted file mode 100644 index f73c8802..00000000 --- a/test/grantees-patch.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "add": [ - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e7" - ], - "revoke": [ - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" - ] -} \ No newline at end of file diff --git a/test/grantees.json b/test/grantees.json deleted file mode 100644 index 64c192d3..00000000 --- a/test/grantees.json +++ /dev/null @@ -1,6 +0,0 @@ -{ "grantees": [ - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" -] -} \ No newline at end of file