Code Monkey home page Code Monkey logo

ara-filesystem's Introduction

ara-filesystem

Build Status

The Ara Filesystem, standalone and secure filesystems backed by Ara identities.

Stability

[Stability][stability-index]: 2 - Stable. Stable. Compatibility with the npm ecosystem is a high priority.

Although the API is stable, this project is still in alpha development and is not yet ready to be used in a production environment.

Dependencies

Installation

$ npm install ara-filesystem --save

Usage

Important: Each CLI command that makes changes to the AFS requires the password of the owner identity (the one created with aid create). Do not forget this password, as it's the only way to update the AFS.

Create an AFS

Run the create command with a valid owner identity.

$ afs create did:ara:df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9

Store the mnemonic phrase in a safe place as it is the only recovery mechanism for your AFS.

Note: The did:ara: prefix is optional for all commands.

Add a file to an AFS

Adding files and/or directories can be done with the add command.

$ afs add <did> <pathspec...>

Example:

$ afs add df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9 my_video.mp4

Remove a file from an AFS

$ afs remove <did> <pathspec...>

Example:

$ afs remove df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9 my_video.mp4

.afsignore

A .afsignore file can be used to specify any files or directories to ignore when adding to an AFS. Only a .afsignore file located at the directory where the afs command is run will be honored.

Each line in afsignore specifies a pattern, similar to .npmignore and .gitignore files:

  • Blank lines or lines starting with # are ignored.
  • Standard glob patterns work.
  • You can end patterns with a forward slash / to specify a directory.
  • You can negate a pattern by starting it with an exclamation point !.

By default, .afs/ and .afsignore are ignored.

An example .afsignore file (taken from the .gitignore link above):

# ignore all .a files
*.a

# but do track lib.a, even though you're ignoring .a files above
!lib.a

# only ignore the TODO file in the current directory, not subdir/TODO
/TODO

# ignore all files in any directory named build
build/

# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt

# ignore all .pdf files in the doc/ directory and any of its subdirectories
doc/**/*.pdf

Deploy an AFS proxy

Before you can commit to an AFS, a proxy contract representing that AFS must be deployed to the network.

$ afs deploy df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9

Commit file(s) to an AFS

Every change in the AFS saved to a local file on disc, much like staged commits. Changes must be commited before they are discoverable and published to the Ara network.

$ afs commit df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9

Price an AFS

Set the price of an AFS by passing in an AFS identity and price in ara tokens. For example, this sets the price of the AFS to 10 ara tokens:

$ afs set-price df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9 10

To verify set price:

$ afs get-price df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9

API

All transaction callbacks (onhash, onreceipt, onconfirmation, onerror, and onmined) are optional. For more information, see ara-util and ara-contracts.

async create(opts)

If owner is given, this function will create a new AFS with the owning identity owner. If did is given, it attempts to get a reference to a previously created AFS.

  • opts
    • did - The DID of an existing AFS
    • owner - DID of the owner of the AFS to be created
    • password - The password of the owner of this AFS; this is only required for writing to the AFS.
    • afsPassword - The password of the AFS; this is only required for writing to the AFS.
    • storage - Optional storage function to use for the AFS
    • keyringOpts - Optional keyring options

Returns the AFS object.

To create a new AFS:

const aid = require('ara-identity')
const { create } = require('ara-filesystem')

const identity = await aid.create({ context, password })
await writeIdentity(identity)
const { publicKey: owner } = identity


const { afs } = await create({ owner, password, afsPassword })

To obtain a reference to an existing AFS:

const did = did:ara:df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9
const { afs } = await create({ did })

Note: Either did or owner is required, but not both.

async destroy(opts)

Destroys the local copy of an AFS and unlists it from the blockchain (if owner), effectively removing it from the Ara network.

  • opts
    • did - The DID of the AFS to be destroyed
    • password - The password of the owner of this AFS
    • afsPassword - The password of the AFS
    • mnemonic - The mnemonic for this AFS
    • keyringOpts - Optional keyring options

If an estimate, returns the cost (in ETH), otherwise returns the transaction receipt.

const { create, destroy } = require('ara-filesystem')
const { afs, mnemonic } = await create({ owner, password, afsPassword })
const { did } = afs
await destroy({
  did,
  mnemonic,
  password,
  afsPassword
})

async add(opts)

Adds one or more files to an existing AFS.

  • opts
    • did - The DID of the AFS to add files to
    • password - The password of the AFS
    • force - Force add the path(s)
    • paths - The path(s) of the files to add
    • keyringOpts - Optional keyring options

Returns the AFS object.

const { create, add } = require('ara-filesystem')
let { afs } = await create({ owner, password })
const { did } = afs
const paths = ['./index.js', './add.js', './picture.png']
afs = await add({
  did,
  paths,
  password
})

async remove(opts)

Removes one or more files from an AFS.

  • opts
    • did - The DID of the AFS where the files are located
    • password - The password of the AFS
    • paths - The path(s) of the files to remove
    • keyringOpts - Optional keyring options

Returns the AFS object.

const { remove } = require('ara-filesystem')
const afs = await remove({
  did,
  paths,
  password
})

async deploy(opts)

Deploys an AFS proxy to the network. Returns the Ethereum address of the deploy contract (if not an estimation).

  • opts
    • did - DID of the AFS to deploy
    • password - Owner's password for this AFS
    • afsPassword - The password of the AFS
    • estimate - Optional flag to check cost of deploy
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

If an estimate, returns the cost (in ETH), otherwise returns the Ethereum address where the contract was deployed.

const { deploy } = require('ara-filesystem')
const address = await deploy({
  afsPassword,
  password,
  did
})

// estimate deploy
const cost = await deploy({
  estimate: true,
  afsPassword,
  password,
  did
})

async commit(opts)

Commits any changes to an AFS to the blockchain. Calling deploy is required before any commits can occur.

  • opts
    • did - The DID of the AFS to commit
    • password - The password of the owner of this AFS
    • afsPassword - The password of the AFS
    • estimate - Optional flag to check cost of commit
    • estimateDid - Optional DID of a proxy which points to an estimate version of an AFS Standard (used for estimating cost without deploy first)
    • price - Optional price in Ara tokens to set this AFS
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • writeCallbacks - Optional callbacks for the Write transaction
      • onhash
      • onreceipt
      • onconfirmation
      • onerror
      • onmined
    • priceCallbacks - Optional callbacks for the Price transaction
      • onhash
      • onreceipt
      • onconfirmation
      • onerror
      • onmined

If an estimate, returns the cost (in ETH), otherwise returns the transaction receipt.

const { commit } = require('ara-filesystem')
const result = await commit({
  afsPassword,
  password,
  price,
  did
})

// estimate commit cost
const cost = await commit({
  estimate: true,
  afsPassword,
  password,
  price,
  did
})

async setPrice(opts)

Sets the price in Ara tokens of an AFS.

  • opts
    • did - The DID of the AFS to set the price of
    • password - The password of the owner of this AFS
    • afsPassword - The password of the AFS
    • price - The price (in Ara) to purchase this AFS
    • estimate - Optional flag to check cost of setPrice
    • estimateDid - Optional DID of a proxy which points to an estimate version of an AFS Standard (used for estimating cost without deploy first)
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

If an estimate, returns the cost (in ETH), otherwise returns the transaction receipt.

const { setPrice } = require('ara-filesystem')
const price = 10
await setPrice({
  afsPassword,
  password,
  price,
  did
})

// estimate set price cost
const cost = await setPrice({
  estimate: true,
  afsPassword
  password,
  price,
  did
})

async getPrice(opts)

Gets the price in Ara tokens of an AFS.

  • opts
    • did - The DID of the AFS to get the price of

If an estimate, returns the cost (in ETH) as a string.

const { getPrice } = require('ara-filesystem')
const price = await getPrice({ did })

async unarchive(opts)

Stability: 2 Stable

Unarchives (unzips) an AFS to a specified location.

  • opts
    • did - The DID of the AFS to unarchive
    • path - Optional path to the AFS
    • keyringOpts - Optional keyring options
const { unarchive } = require('ara-filesystem')
await unarchive({
  did,
  path
})

async isUpdateAvailable(opts)

Compares local AFS version to what has been published. Returns true if the published AFS version is greater than the local, otherwise false.

  • opts
    • did - The DID of the AFS to check
    • keyringOpts - Optional keyring options

Returns a boolean.

const { isUpdateAvailable } = require('ara-filesystem')
const available = await isUpdateAvailable({ did: 'df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9' })

async metadata.writeFile(opts)

Writes a metadata JSON file to the metadata partition of an AFS.

  • opts
    • did - The DID of the AFS to write to
    • password - The password of the owner of this AFS
    • afsPassword - The password of the AFS
    • filepath - The path of the metadata JSON file to copy
    • keyringOpts - Optional keyring options

Returns the updated metadata object.

const { metadata } = require('ara-filesystem')

const result = await metadata.writeFile({
  did,
  password,
  filepath,
  afsPassword
})

async metadata.writeKey(opts)

Writes a metadata key/value pair to the metadata partition of an AFS.

  • opts
    • did - The DID of the AFS to write to
    • password - The password of the owner of this AFS
    • afsPassword - The password of the AFS
    • key - The key to write
    • value - The value to write
    • keyringOpts - Optional keyring options

Returns the updated metadata object.

const { metadata } = require('ara-filesystem')

const key = 'foo'
const value = 'bar'
const result = await metadata.writeKey({
  did,
  key,
  value,
  password,
  afsPassword
})

async metadata.writeKeys(opts)

Writes multiple key/value pairs to the metadata parition of an AFS.

  • opts
    • did - The DID of the AFS to write to
    • password - The password of the owner of this AFS
    • afsPassword - The password of the AFS
    • keys - Object containing the key/value pairs to write
    • keyringOpts - Optional keyring options

Returns the updated metadata object.

const { metadata } = require('ara-filesystem')

const keys = { foo: 'bar', hello: 'world' }
await metadata.writeKeys({
  did,
  keys,
  password,
  afsPassword
})

async metadata.readKey(opts)

Reads a metadata key from the metadata partition of an AFS.

  • opts
    • did - The DID of the AFS to read from
    • key - The key to write

Returns the value of the metadata key.

const { metadata } = require('ara-filesystem')

const result = await metadata.readKey({
  did,
  key
})

async metadata.delKey(opts)

Deletes a metadata key/value pair from the metadata partition of an AFS.

  • opts
    • did - The DID of the AFS to delete from
    • password - The password of the owner of this AFS
    • afsPassword - The password of the AFS
    • key - The key to write
    • keyringOpts - Optional keyring options

Returns the updated metadata object.

const { metadata } = require('ara-filesystem')

await metadata.delKey({
  did,
  key,
  password,
  afsPassword
})

async metadata.clear(opts)

Empties all metadata contents of an AFS.

  • opts
    • did - The DID of the AFS whose metadata is to be emptied
    • password - The password of the owner of this AFS
    • afsPassword - The password of the AFS
const { metadata } = require('ara-filesystem')
await metadata.clear({ did, password, afsPassword })

async metadata.readFile(opts)

Reads all metadata from an AFS.

  • opts
    • did - The DID of the AFS to read from

Returns the updated metadata object.

const { metadata } = require('ara-filesystem')
const contents = await metadata.readFile({ did })

ownership.estimateRequestGasCost(opts)

Gets the estimated gas cost of requesting ownership of an AFS.

Note: This function takes the same arguments as ownership.request(opts)

Returns the cost (in ETH) as a string.

const { ownership } = require('ara-filesystem')
const cost = await ownership.estimateRequestGasCost(opts) // 0.015 ETH

ownership.estimateRevokeGasCost(opts)

Gets the estimated gas cost of revoking a previous ownership request.

Note: This function takes the same arguments as ownership.revokeRequest(opts)

Returns the cost (in ETH) as a string.

const { ownership } = require('ara-filesystem')
const cost = await ownership.estimateRevokeGasCost(opts) // 0.015 ETH

ownership.estimateApproveGasCost(opts)

Gets the estimated gas cost of approving an ownership request.

Note: This function takes the same arguments as ownership.approveTransfer(opts)

Returns the cost (in ETH) as a string.

const { ownership } = require('ara-filesystem')
const cost = await ownership.estimateApproveGasCost(opts) // 0.015 ETH

ownership.request(opts)

Requests the transfer of ownership of an AFS to requesterDid. Must be approved by the current owner. This transaction will revert if a request is already active.

  • opts
    • requesterDid - DID of the requester
    • contentDid - DID of the AFS to request ownership for
    • password - password of the requester
    • estimate - Optional flag to check cost of request
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns the transaction receipt as an object.

const { ownership } = require('ara-filesystem')
const requesterDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'pass'
const contentDid = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'
const receipt = await ownership.request({ requesterDid, password, contentDid })

ownership.revokeRequest(opts)

Revokes a previous request for AFS ownership transfer. This transaction will revert if there isn't an active request.

  • opts
    • requesterDid - DID of the requester
    • contentDid - DID of the AFS to revoke ownership reequest for
    • password - password of the requester
    • estimate - Optional flag to check cost of revokeRequest
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns the transaction receipt as an object.

const { ownership } = require('ara-filesystem')
const requesterDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'pass'
const contentDid = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'
const receipt = await ownership.revokeRequest({ requesterDid, password, contentDid })

ownership.approveTransfer(opts)

Approves a pending transfer request, this officially transfers ownership for the given AFS. If not an estimate, this function will return an object containing a random password to be delivered to the identity claiming ownership, along with the transaction receipt.

  • opts
    • contentDid - DID of the content to change ownership for
    • password - Password of the staged owner
    • afsPassword - The password of the AFS
    • newOwnerDid - DID of the owner to transfer ownership to
    • mnemonic - mnemonic associated with the AFS
    • estimate - Optional flag to check cost of approveTransfer
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns object:

  • receipt - transaction receipt
  • password - randomly generated password
const { ownership } = require('ara-filesystem')
const contentDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'pass'
const afsPassword = 'password'
const newOwnerDid = 'did:ara:7dc039cfb220029c371d0f4aabf4a956ed0062d66c447df7b4595d7e11187271'
const mnemonic = 'cargo diary bracket crumble stable chief grief grab frost seven wet repeat'
const result = await ownership.approveTransfer({ contentDid, password, afsPassword, newOwnerDid, mnemonic })

ownership.claim(opts)

Fully claims ownership of an AFS after it has been transferred by the previous owner.

  • opts
    • currentPassword - random password generated from the previous owner
    • newPassword - new password for this AFS identity
    • contentDid - DID of the content to claim ownership for
    • mnemonic - mnemonic associated with the AFS to claim
    • keyringOpts - Optional keyring options
const { ownership } = require('ara-filesystem')
const contentDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const currentPassword = 'generatedPassword'
const newPassword = 'secureNewPassword'
const mnemonic = 'cargo diary bracket crumble stable chief grief grab frost seven wet repeat'

await ownership.claim({
  currentPassword,
  newPassword,
  contentDid,
  mnemonic
})

Contributing

Releases follow Semantic Versioning

See Also

License

LGPL-3.0

ara-filesystem's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ara-filesystem's Issues

afs.create crashes on multidrive

Expected Behavior

afs.create should gracefully throw if a did does not exist, or no longer exists, even if multidrive has a reference on disk to where it thinks it should be.

Actual Behavior

Sometimes, still investigating when, afs.create will crash without properly throwing an error that can be caught. The leading thought is that if a local afs folder is deleted, and potentially if there's no proxy, but there still exists a ref to it in the nodes folder.

Note: this isn't a huge issue, it's just a pain when testing and switching networks often.

Steps to Reproduce the Problem

Specifications

  • Version:
  • Platform:
  • Subsystem:

Read-only copies have different public keys on different computers

Expected Behavior

Creating read-only programmatic instance of AFS on different computers should have the same public key.

Actual Behavior

Creating read-only programmatic instance of AFS on different computers have different public keys.

Steps to Reproduce the Problem

  1. Create an AFS on computer A
  2. Create a programmatic ref to AFS on computer A and print out afs.key
  3. Create a programmatic ref to AFS on computer B and print out afs.key
  4. The two keys are different

Specifications

  • Version: 3ff9099
  • Platform:
  • Subsystem:

Claim Ownership Remotely

Expected Behavior

If the owner's keystore is not local, it should fetch is remotely and be able to replicate it locally prior to needing to decrypt and re-encrypt.

Actual Behavior

Right now claiming ownership requires the keystore to be local to the machine that needs to do the decryption.

Should not be able to set a price of 0

Expected Behavior

An error should be thrown when trying to call setPrice with a value of 0.

Actual Behavior

The transaction will complete and cost gas, even if you are trying to set a price of 0.

handle if readonly and no proxy

Expected Behavior

Correctly catch issue if user creates AFS that is readonly but there is no current proxy.

Actual Behavior

Error is not caught / is not thrown correctly, and causes crash. In storage.js, the create function can potentially pass a null value to _decode on read, which does not handle nulls.

Steps to Reproduce the Problem

  1. Create a readonly afs with a valid proxy

Specifications

  • Version:
  • Platform:
  • Subsystem:

Calling `create({ did, password })` to replicate an AFS, writes a `staged.json` file

Expected Behavior

call create({ did, password }) will clone/replicate/download home and metadata dirs of an AFS

Actual Behavior

call create({ did, password }) will write a staged.json file in the local afs directory

Steps to Reproduce the Problem

  1. Create an afs; add a file; commit the file (no staged.json in directory)
  2. call create({ did, password })
    portion of log from calling create({ did, password }):
  ara-filesystem:storage metadata/signatures staged write at offset 0 size 32 +0ms
  ara-filesystem:storage writing (and therefore appendingg ~~~~~. ) +0ms
  ara-filesystem:commit      APPENDING ~~~  +0ms
  ara-filesystem:commit could not make dir at /Users/vipyne/.ara/afs/d58cb5c6921d3dd7e2bd462acc9d64b56f3ba713a115986755b4660dbf006e98/staged.json +1ms
  ara-filesystem:commit                                                          BUT COULD YOU THO +0ms
  ara-filesystem:commit  { Error: EEXIST: file already exists, mkdir '/Users/vipyne/.ara/afs/d58cb5c6921d3dd7e2bd462acc9d64b56f3ba713a115986755b4660dbf006e98'
    at Object.fs.mkdirSync (fs.js:905:18)
    at _makeStagedFile (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/commit.js:216:8)
    at generateStagedPath (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/commit.js:138:5)
    at append (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/commit.js:106:16)
    at RandomAccess.write [as _write] (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/storage.js:61:7)
    at Request._run (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/random-access-storage/index.js:199:40)
    at Request._unqueue (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/random-access-storage/index.js:155:50)
    at Request.callback (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/random-access-storage/index.js:160:8)
    at nextTickCallback (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/random-access-storage/index.js:249:7)
    at process._tickCallback (internal/process/next_tick.js:152:19)
  errno: -17,
  code: 'EEXIST',
  syscall: 'mkdir',
  path: '/Users/vipyne/.ara/afs/d58cb5c6921d3dd7e2bd462acc9d64b56f3ba713a115986755b4660dbf006e98' } +0ms
  ara-filesystem:storage metadata/tree staged write at offset 0 size 32 +3ms
  ara-filesystem:storage writing (and therefore appendingg ~~~~~. ) +0ms
  ara-filesystem:commit      APPENDING ~~~  +2ms
  ara-filesystem:storage metadata/signatures read at offset 160 size 64 +8ms
  ara-filesystem:storage metadata/tree read at offset 72 size 40 +25ms
  ara-filesystem:storage metadata/tree read at offset 192 size 40 +1ms
  ara-filesystem:storage metadata/tree read at offset 32 size 40 +40ms

I think the issue is here:
https://github.com/AraBlocks/ara-filesystem/blob/master/commit.js#L199-L205

Specifications

  • Version: 1.0.0
  • Platform: macos
  • Subsystem: 10.12.6

Ability to add files/directories from non-cwd

Expected Behavior

Ability to add files/directories to an AFS from non-cwd.

Actual Behavior

Only able to add from cwd.

Proposed Solution

Below is an example using mirror-folder that allows the adding of files/directories to an afs from the non-cwd.

const { join, basename } = require('path')
const mirror = require('mirror-folder')

async function add(opts){
  if (null === opts.did || 'string' !== typeof opts.did || !opts.did) {
    throw new TypeError('ara-filesystem.add: Expecting non-empty did.')
  }

  if (null === opts.password || 'string' !== typeof opts.password || !opts.password) {
    throw new TypeError('ara-filesystem.add: Password required to continue')
  }

  if (null === opts.paths || (!(opts.paths instanceof Array)
    && 'string' !== typeof opts.paths) || 0 === opts.paths.length) {
    throw new TypeError('ara-filesystem.add: Expecting one or more filepaths to add')
  }

  const {
    did, paths, password, force
  } = opts

  let afs
  try {
    ({ afs } = await create({ did, password }))
  } catch (err) {
    throw err
  }

  for (let i = 0; i < paths.length; i++){
    await mirrorPath(paths[i])
  }

  debug('full copy complete')
  debug(await afs.readdir(afs.HOME))

  return afs

  async function mirrorPath(path){
    debug(`copy start: ${path}`)

    let name = afs.HOME
    if (await pify(isFile)(path)) {
      name = join(afs.HOME, basename(path))
    }

    const error = await pify(mirror)({ name: path }, {
      name,
      fs: afs
    }, { keepExisting: true })
  
    if (error){
      debug(`copy error: ${path}: ${error}`)
    } else {
      debug(`copy complete: ${path}`)
    }
  }
}

Password not hidden on windows

Expected Behavior

When prompted for password on CLI, command line should hide password.

Actual Behavior

When prompted for password on CLI, command line doesn't hide the password until the password is submitted.

Steps to Reproduce the Problem

  1. Create an AFS
  2. When it asks for password, notice that the password that is typed is not hidden.

Specifications

  • Version: master commit 0cb75fc
  • Platform: Windows
  • Subsystem: Using mingw64 for command line (i.e. git bash)

Commits should send as a batch write request

Expected Behavior

When a user commits updates to an AFS, they should be sent as a single transaction.

Actual Behavior

Each individual change to the metadata/tree and metadata/signatures file each requires their own write, and thus, their own individual transactions.

Remove inconsistent usage of semi-colons in create.js

Expected Behavior

Code contains no semi-colons

Actual Behavior

Code contains two semi-colons when using aid.create.

The reasoning behind it is seemingly not by mistake. The issue was that if you removed those semi-colons, scoping issues would began happening when using ({ x } = y) statements. My assumption is that surrounding a statement in parenthesis creates a child scope which might cause issue if node is inferring when statements are complete. With the semi-colon, it was obvious to node but without, things get more hazy (My assumptions for future readers :))

Steps to Reproduce the Problem

  1. Remove semi-colons
  2. Behold the variables that become undefined despite being defined
  3. Become annoyed
  4. Realize scoping is hilarious

Specifications

  • Version: 0.1.0
  • Platform: Only tested on Ubuntu 18.04 but I would presume all
  • Subsystem: create.js

AFS Create fails if you are on a fresh install

Expected Behavior

AFS Create will successfully create all of the required folders

Actual Behavior

AFS Create throws uncaught error due to using a non-synchronous function and not passing a callback

Steps to Reproduce the Problem

  1. Delete afs archive path
  2. Try ara-filesystem create <did>

Use rc files rather than constants

Expected Behavior

Changing the rc file or passing corresponding options will change the behavior of ara-filesystem accordingly (change what keyring file is used, have a default DID, pass a resolver network name)

Actual Behavior

Inconsistent behavior. In some cases, options are correctly used but fallback on hard-coded values. In some cases, passed options will be ignored and only use the hard-coded values

Steps to Reproduce the Problem

  1. Pass keyringOpts into ara create (or a few other functions)
  2. In ara create, keyringOpts will effect the archive but not the resolve
  3. In afs provided aid functions, the passed options will not be used

Specifications

  • Version: 0.1.0
  • Platform: All
  • Subsystem: CLI, create, aid, destroy, commit

afs add command does not accept filepaths outside of CWD

Expected Behavior

$ afs add fa161f865d8a9... ~/Desktop/jSGeSHD.gif 
 ara: info:  id: fa161f865d8a9620069455a758b21676bbb87a93ea374983a5e0efb43a1c4020
 ara: info:  paths:  [ '/Users/vipyne/Desktop/jSGeSHD.gif' ]
afs: info: Reading [------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 1.23 mbps 100% 0.0s
afs: info: Writing [------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 1.23 mbps 100% 0.0s

Actual Behavior

$ afs add fa161f865d8a9... ~/Desktop/jSGeSHD.gif 
 ara: info:  id: fa161f865d8a9620069455a758b21676bbb87a93ea374983a5e0efb43a1c4020
 ara: info:  paths:  [ '/Users/vipyne/Desktop/jSGeSHD.gif' ]
/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/hyperdrive/index.js:669
    if (name !== '/' && (err || !list.length)) return cb(err || new Error(name + ' could not be found'))
                                                      ^

TypeError: cb is not a function
    at /Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/hyperdrive/index.js:669:55
    at onnodes (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/append-tree/index.js:116:33)
    at onget (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/append-tree/index.js:358:21)

Steps to Reproduce the Problem

  1. afs add a file not located in current working directory

Specifications

  • Version: 1.0.0 / ck-ownership-contract
  • Platform: macos
  • Subsystem: osX 10.12.6

`ara-filesystem add` is broken on Linux

Expected Behavior

File is added.

Actual Behavior

Command hangs because the file doesn't exist.

Steps to Reproduce the Problem

  1. Be on the latest commit
  2. Try afs add <did> <file>
  3. Wait forever

Specifications

  • Version: ???
  • Platform: Linux
  • Subsystem: Ubuntu
maddie@lscomputer:~$ afs add 7b65940677c88cd072616f323156c89b3ad28cd416852c19fbaf1e5602607fde ~/doggo.mp4 -D                                                                                                 
 ara: info:  id: 7b65940677c88cd072616f323156c89b3ad28cd416852c19fbaf1e5602607fde                                                                                                                            
 ara: info:  paths:  [ '/home/maddie/doggo.mp4' ]                                                                                                                                                            
? Please provide the passphrase for your identity. This is needed to complete this action.                                                                                                                   
Passphrase: [hidden]                                                                                                                                                                                         
(node:5289) DeprecationWarning: ara-crypto: crypto.decrypt() is deprecated. Please use 'ara-secret-storage' instead.                                                                                         
  ara-filesystem:storage metadata/signatures staged write at offset 0 size 32 +0ms                                                                                                                           
  ara-filesystem:storage metadata/tree staged write at offset 0 size 32 +2ms                                                                                                                                 
(node:5289) DeprecationWarning: ara-crypto: crypto.encrypt() is deprecated. Please use 'ara-secret-storage' instead.                                                                                         
  ara-filesystem:add copy start: /home/maddie/doggo.mp4 +0ms                                                                                                                                                 
  ara-filesystem:add adding path /home/doggo.mp4 +1ms                                                                                                                                                        

afs add fails when "/" in directory on windows

Expected Behavior

$ afs add b88592e85e99b790f22b21227aa6a1eecb2a2a738dd54c38e599978d538323ec /d/Littlstar/Test/web.mp4

Should successfully add file at path.

Actual Behavior

$ afs add b88592e85e99b790f22b21227aa6a1eecb2a2a738dd54c38e599978d538323ec /d/Littlstar/Test/web.mp4

results in:

Path: metadata\tree
Path: metadata\signatures
Path: content\tree
Path: content\signatures
D:\Development\EnvironmentA\ara-filesystem\node_modules\hyperdrive\index.js:668
    if (name !== '/' && (err || !list.length)) return cb(err || new Error(name + ' could not be found'))
                                                      ^

TypeError: cb is not a function
    at D:\Development\EnvironmentA\ara-filesystem\node_modules\hyperdrive\index.js:668:55
    at onnodes (D:\Development\EnvironmentA\ara-filesystem\node_modules\append-tree\index.js:116:33)
    at onget (D:\Development\EnvironmentA\ara-filesystem\node_modules\append-tree\index.js:358:21)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

Steps to Reproduce the Problem

  1. Create AFS
  2. Add File to AFS that is not contained in current directory (note: add command works if file is in same directory, i.e.
$ afs add b88592e85e99b790f22b21227aa6a1eecb2a2a738dd54c38e599978d538323ec web.mp4

Specifications

  • Version: master commit c1c36e9
  • Platform: Windows

Passphrase request verbiage on Create

Expected Behavior

When creating an AFS, the CLI needs the actual passphrase for your identity (rather than asking you to create a new one), so it should say "Please provide the passphrase for your identity."

Actual Behavior

When creating an AFS, the CLI responds with the statement "Please provide a passphrase for your identity."

Steps to Reproduce the Problem

  1. create an AFS via CLI

Specifications

  • Version: branch master at commit: 12e0f6e

storage.js resolveBufferIndex fails to split path on windows

Expected Behavior

resolveBufferIndex should split using the '' character on windows systems

Actual Behavior

resolveBufferIndex splits using the '/' character on all platforms.

Steps to Reproduce the Problem

  1. Create an AFS on windows
  2. Get error:

Error: Path is not properly formatted
at resolveBufferIndex (D:\Development\EnvironmentA\ara-filesystem\storage.js:103:11)

Specifications

  • Version: master on c1c36e9
  • Platform: Windows

Migrate to use ara-secret-storage encrypt, decrypt methods

Expected Behavior

Encrypt/decrypt within AFS should not throw deprecation warnings, and should use ara-secret-storage for these operations.

Actual Behavior

Encrypt/decrypt throws deprecation warnings as ara-crypto encrypt/decrypt functions are still being used.

Use same CLI layout to display mnemonic as ara-identity

Expected Behavior

To remain consistent across the various Ara modules, AFS mnemonics should be displayed similarly to ara-identity when creating a new identity via the command line.

Actual Behavior

AFS displays AFS identity mnemonics differently.

Steps to Reproduce the Problem

  1. Create an AFS via the CLI.

Id and key of AFS should be the same

Expected Behavior

id and key of afs should be equivalent

Actual Behavior

id and key of afs are different

Steps to Reproduce the Problem

  1. Create AFS
  2. Compare identifier and key of AFS

Specifications

Use SafeMath

Instead of using arithmetic operations directly, it is recommended to use something like the SafeMath library from OpenZeppelin. This will make the function revert if there is an overflow or an underflow.

At the beginning of the contract you can do using SafeMath for uint256, and then you can do things like: return largest_key.add(buffer_mappings[identity][file].buffers[largest_key].length);.

intermittent `RangeError [ERR_INDEX_OUT_OF_RANGE]` when reading an AFS

Expected Behavior

An AFS file accessed by it's Ara ID is read back from storage

Actual Behavior

  ara:network:node:cdn received request for content AID 04aff33f4c4a3f45847aa9674e0ce8d96e6ea768c91f1c21b779ca8a7eccd1d8 from undefined +35s
  ara:network:node:cdn afs list ::  [ 'jSGeSHD.gif' ] +2ms
  ara:network:node:cdn streaming content +0ms
  ara:network:node:cdn received request for content AID 6b24991c55e0d21add967067321e1fddd48742320dadd84cac770da9147c194a from undefined +2s
  ara-filesystem:storage metadata/signatures staged write at offset 0 size 32 +37s
  ara-filesystem:storage metadata/tree staged write at offset 0 size 32 +1ms
  ara-filesystem:storage metadata/signatures read at offset 352 size 64 +8ms
  ara-filesystem:storage metadata/tree read at offset 152 size 40 +29ms
  ara-filesystem:storage metadata/tree read at offset 392 size 40 +1ms
  ara-filesystem:storage metadata/tree read at offset 32 size 40 +40ms
  ara-filesystem:storage content/signatures staged write at offset 0 size 32 +20ms
  ara-filesystem:storage content/tree staged write at offset 0 size 32 +1ms
  ara-filesystem:storage content/signatures read at offset 4832 size 64 +3ms
  ara-filesystem:storage content/tree read at offset 2552 size 40 +17ms
  ara-filesystem:storage content/tree read at offset 5432 size 40 +1ms
  ara-filesystem:storage content/tree read at offset 5912 size 40 +1ms
  ara-filesystem:storage metadata/tree read at offset 352 size 40 +42ms
  ara-filesystem:storage metadata/tree read at offset 432 size 40 +14ms
  ara-filesystem:storage metadata/tree read at offset 112 size 40 +15ms
  ara:network:node:cdn afs list ::  [ 'states-of-a-programmer.png', 'jSGeSHD.gif' ] +382ms
  ara:network:node:cdn streaming content +1ms
  ara-filesystem:storage content/tree read at offset 152 size 40 +24ms
  ara-filesystem:storage content/tree read at offset 392 size 40 +2ms
  ara-filesystem:storage content/tree read at offset 512 size 40 +27ms
  ara:network:node RangeError [ERR_INDEX_OUT_OF_RANGE]: Index out of range
  ara:network:node     at checkOffset (buffer.js:1020:11)
  ara:network:node     at Buffer.readUInt32BE (buffer.js:1096:5)
  ara:network:node     at Object.exports.decode (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/uint64be/index.js:24:17)
  ara:network:node     at Request._callback (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/hypercore/lib/storage.js:160:25)
  ara:network:node     at Request.callback (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/node_modules/random-access-storage/index.js:161:8)
  ara:network:node     at RandomAccess.read [as _read] (/Users/vipyne/Documents/littlstar/ara/ara-filesystem/storage.js:55:11)
  ara:network:node     at <anonymous>
  ara:network:node     at process._tickCallback (internal/process/next_tick.js:160:7) +53s

Steps to Reproduce the Problem

  1. create, add, and commit an AFS
  2. access the AFS via content / ARA id via ara-network-node-cdn
  3. Sometimes this error happens. Sometimes not. Possible suspect: blockchain/truffle caching incorrect storage address.

Specifications

  • develop ara-filesystem branch

  • local blockchain running via Truffle

  • Version: 1.0.0

  • Platform: Mac OS

  • Subsystem: 10.12.6

publicKeys does not follow the standard publicKey structure in `create()` of `ara-identity`

Ref : https://github.com/AraBlocks/ara-filesystem/blob/master/create.js#L274

Expected Behavior

metadata publicKey is being sent to create() of ara-identity as,

const publicKey = {
    "id" : "metdata",
    "value" : "ec84465527bea0f8c54ce6c42c0d7549a7163336655a8bcaf731f07eb2997c73"
}

Actual Behavior

metadata publicKey should be sent as,

const publicKey = {
    "id" : "metadata",
    "publicKeyHex": "ec84465527bea0f8c54ce6c42c0d7549a7163336655a8bcaf731f07eb2997c73",
    "publicKeyBase58": "GvGCfZpuJapzxoo3rgyaYR39XReFxaWpZZUvoaq1o8qg",
    "publicKeyBase64": "OyERlUnvqD4xUzmxCwNdUmnFjM2ZVqLyvcx8H6ymXxz"
}

AFS not closing programtically after `add`

Expected Behavior

When afs.add is called subsequently toafs.create, in the same node process, it should close the AFS.

Actual Behavior

Seems that unless the node process ends, the AFS remains open after adding. This is causing a problem for the content-manager, in where the publish function creates, adds, commits, and then broadcasts in a single step. It breaks when someone tries to download from the swarm broadcast.

Fix

Adding afs.close() to the onfinish function of add.js will fix this.

Add AFS ls command

Expected Behavior

Add an afs ls <did> <path> command which prints out the current contents of the afs in the cli where did is the did of the afs and the optional path parameter allows to ls for different sub-directories of the specified afs.

Add CLI easter egg

Desired Behavior

$ afs -h
usage: afs: [-hDV] [--help] [--version]
            [--debug] <command> [<args>]

Below are some useful afs commands:

  afs create     Create a new AFS
  afs add        Adds file(s) and/or directories to an AFS
  afs remove     Removes file(s) and/or directores from an AFS
  afs commit     Publishes an AFS to the network
  afs history    Prints AFS history
  afs price      Sets, gets the price (in ARA) of an AFS
  afs destroy    Removes an AFS from the network
  afs unarchive  Unarchive an AFS to a directory
  afs metadata   CRUD operation interface for an AFS' metadata
  afs ownership  Ownership management of an AFS
  afs deploy     Deploy an AFS proxy to the network
  afs hr

Options:
  --help, -h     Show this message
  --version, -V  Show AFS CLI version
  --verbose, -v  Show verbose output
  --debug, -D    Enable debug output (Sets 'DEBUG=ara-filesystem:*')
  --secret, -s   Shared secret for the keyring                          [string]
  --network, -n  Network name of the key for the DID resolver in the keyring
                                                                        [string]
  --keyring, -k  Path to the keyring                                    [string]

Steps to find easter egg:

$ afs hr
prompt:
(user types in up, up, down, down, left, right, left, right)

[ print out of hood rat ascii art ]

Metadata updates should require password

Expected Behavior

A user should be prompted to input their identity's password before being allowed to change metadata for a particular AFS.

Actual Behavior

A user can change any metadata of any AFS as long as they have the DID for that AFS.

Metadata batch write function

Currently, writeKey only takes a single key and value, so you have to call it every time you want to add a new key, which means a new call to _readMetadataFile and _writeMetadataFile for every key pair. Since we'd be using this function programmatically in the DApp, and adding a handful of keys for every publish, a batchWriteKey would be nice to have.

Happy to write it ourselves! API seems straightforward.

Use yargs .help rather than custom help catch

Expected Behavior

-h / --help will always work without passing any options and exits successfully

Actual Behavior

If a command uses positionals, the command exits with code 1

Steps to Reproduce the Problem

Run any command with required options or positionals
Run echo $?

Check current price before setting new price

Expected Behavior

The price of the AFS is checked before making a transaction to update it if it's already set the price that's being requested.

Actual Behavior

The transaction will be sent regardless, overwriting the existing price.

Version CLI flag does not print out version

Expected Behavior

-V prints out the current version of afs that is being used on the CLI.

Actual Behavior

Passing -V as a flag should

Fix is to use yargs' version() function on parent and children processes.

No force option for commit or set price

Expected Behavior

I should be able to commit via the CLI using a force flag (-f, --force) to skip any confirmations prompts, specifically committing or setting a price.

Actual Behavior

Gas cost prompts always appear regardless of a force flag.

archiverNetwork and resolverNetwork not passed in cli create

Expected Behavior

archiverNetwork and resolverNetwork should be passed from afs create cli

Actual Behavior

It isn't because it only destructures network

Steps to Reproduce the Problem

  1. Try passing archiverNetwork and/or resolverNetwork
  2. It defaults to your rc values

Specifications

  • Version:
  • Platform:
  • Subsystem:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.