Giter Site home page Giter Site logo

graphite-docs / graphite Goto Github PK

View Code? Open in Web Editor NEW
582.0 21.0 88.0 85.64 MB

Encrypted, secure, user-owned productivity suite

Home Page: https://graphitedocs.com

License: GNU General Public License v3.0

HTML 0.98% JavaScript 94.19% CSS 4.83%
decentralized-applications blockchain privacy security writing

graphite's Introduction

Graphite

Graphite is a secure, private, and encrypted alternative to Google's G-Suite. Using Blockstack's developer tools and protocol, Graphite gives people control over their identity. People get all the convenience of cloud computing with none of the privacy tradeoffs.

Check it out at http://app.graphitedocs.com

Graphite is open source and available for contributions. It is also available to simple run locally. One of the exciting things about this app is you can run it (alongside Blockstack) without ever going to the Graphite URL.

Quick Start

Install

Graphite is open source and welcomes new issues, feature requests, and contributions.

Steps to install:

  1. Clone the repo.
  2. Run npm install
  3. Run npm run start
  4. Run cp .env.sample .env

Note: Local development will result in CORS errors on authentication. Use a CORS browser extension to get around this. Future version will eliminate this need and when pushed to a hosted site, the CORS error is resolved.

Using Locally with Graphite Pro

It is possible to run Graphite locally and access Graphite Pro features. There are two options:

  1. Update the code in the src/index.js. Set the axios.defaults.baseURL to process.env.REACT_APP_API_URL_SOCKET (https://socket.graphitedocs.com)
  2. Clone and run the graphite-server. This server handles websockets and Graphire Pro requires. It is available at https://github.com/graphite-docs/graphite-server.

Technical Architecture

There is a lot that goes into making Graphite work well while hiding the complexities of encryption behind the scenes. But at the same time, it's important to understand how that complexity works so that people can audit and adopt similar approaches elsewhere.

Identity

When creating a user account, people are directed to the Blockstack Browser. While the name is a bit of a misnomer, the Blockstack Browser is an authenticator. The best way to think of it is like the little window that pops up when you sign into applications using Google or Facebook. The difference here is that the Blockstack Browser is simply verifying or generating application-specific encryption keys for you to use within Graphite.

Basic flow for a new user:

  • Click Sign Up
  • Directed to Blockstack Browser
  • Choose username
  • Name is registered
  • Master keychain created
  • Application-specific encryption keys generated
  • Storage hub selected and specified in profile
  • Authentication response included in a redirect to Graphite

What's actually happening above?

If a user has never used an application built on Blockstack's protocol, they'll need to select a user name. Let's explore that first.

Username selection and registration

Initially, a username is created for free as a sponsored name under the id.blockstack name within the .blockstack namespace. The best way to think of names are like website domains, and the best way to think of namespaces are like top-level domains (.com, .org, etc). Because all name registrations require a transaction on the bitcoin blockchain (this is how these names become wholly owned by the people who register them and not by apps like Graphite), a payment is required. However, by issuing sponsored names under and existing name, these name registrations can be batched together. This allows hundreds of names to be registered at once, thus bringing down the cost significantly.

Example: justin.id.blockstack is a sponsored name under the id.blockstack name within the blockstack namespace. Although the owner of id.blockstack controls the availability of name registrations through that name, once a name is created, it is entirely owned and controlled by the person using it.

People have the opportunity to create additional names, and those names do not have to be sponsored names. It's important to note that as of this time, any names created outside the sponsored id.blockstack name will require payment from the user to issue the name transaction on the blockchain.

In a soon-to-be-released version of Graphite's authentication system, users will simply be able to select a username and enter a password. The process described above will happen behind the scenes and without the user ever having to leave Graphite's web app.

Master keychain creation
For brand new users, a keychain is created. This keychain is a combination of things. It helps generate their publicly available profile file, but it also includes sensitive information such as master private key, master payment key, and a seed phrase.

Currently, each user must record the seed phrase and keep it somewhere safe. Loss of the seed phrase equates to loss of data.

This keychain is created client-side and encrypted.

Application-specific encryption keys generated
Because Blockstack's protocol is designed to be used with a single username across multiple applications, the user is presented with application-specific encryption keys. These keys are used only within the app the person is logging into. In the case of Graphite, Graphite-specific keys are used for encryption and decryption. If someone were to try to use those keys in another app, they would not work.

These keys, of course, are unique per person and are derived by a combination of the verification of Graphite's application origin (https://app.graphitedocs.com) and the person's master seed phrase.

Because of this derivation process, a user never has to memorize or store their Graphite-specific encryption keys. As long as they have their seed phrase somewhere safe, they will always be able to encrypt and decrypt data behind the scenes with the same simplicity as using unencrypted Google Products.

Storage

Storage hub selected and specified in profile
While not all applications buuilding with Blockstack's protocol offer this, Graphite offers people the opportunity to provide a user-selected storage hub URL. Should a user not want to deal with the technical requirements of configuring and deploying a storage hub, they can simply use Blockstack's sponsored storage hub for free. All data is encrypted before being sent to Blockstack's sponsored hub, so people can freely work and communicate without fear of snooping or data breaches.

If a person would like to run their own storage hub, they can follow the instructions here: Gaia Storage.

Notes about storage and Graphite Pro plans:
Paying users of Graphite's enterprise offering, Graphite Pro, will have pointer information stored in a Graphite managed database. This database contains no personal information and simply allows teams to work together by signalling where a file is currently located (i.e. which users on the account has the most recent updates in their storage hub).

Collaboration

To get a sense for how sharing of documents and files works in Graphite at a base level, consider the diagram below.

Essentially, every file or document that is shared is copied then encrypted with the recipient's public key. This is true of real-time collaboration as well, but with the added convenience of back and forth updates possible in real time.

Graphite uses a websockets server to manage real-time collaboration. The server uses a secure wss connections (the equivalent of tls connections for web browsers). No data is stored on the server or sent anywhere other than to the other collaborators. This is all verifiable by reviewing the open source code for Graphite's server here.

Graphite Pro

Paying customer under Graphite's enterprise plan, Graphite Pro, have added benefits such as team management, roles and permissions, and team sharing. To enable these features, Graphite takes a security-first approach while still recognizing the need for convenience.

When a team is created, encryption keys for that team are also created. This happens client-side. When a team member is added to the team an email invite is sent which includes a token that allows the team member to receive and store and encrypted copy of the team-specific encryption keys in their storage hub.

Any files, forms, or documents shared amongst a team are encrypted with team-specific keys. Because Graphite Pro also makes use of a server and a database for pointer files, additional security is put in place to verify the authenticity of an API call to request information about a file's storage location. Should a teammate be removed from the team, the database knows about this, the client knows about this, and the encryption keys for the team are rotated.

To get an even better sense of how this all works, please review the blog post that outlines Graphite Pro.

Motivation

This project stemmed from the increasing control companies place on user data. At any given moment, Google can remove access to every single one of the documents you write and store with them. That's unacceptable.

Additionally, government censorship, which has always been around, seems to be growing more prevalent.

Graphite sets out to change that, and this was only possible because of the work done by Blockstack.

Contributing

If you'd like to contribute to this project, there are a few ways to do so:

Report bugs

You can create a new issue any time, but please make sure your bug reports are clean and clear. Here's a good guide:

https://testlio.com/blog/the-ideal-bug-report/

Please make sure you search any existing issues for the bug you would like to report before opening a new issue.

Suggest Features

A public roadmap will soon be up at http://graphitedocs.com, but feature requests are always welcome. To suggest a feature, please open a new issue in this format:

Feature: [Your feature title] Description of the feature requests

Be as detailed as possible in feature requests and be sure to search existing issues to make sure you are not making a duplicate feature request.

Bug Fixes

If you'd like to contribute by fixing any existing bugs, please create a pull request. Here's a basic guide for doing so:

https://help.github.com/articles/creating-a-pull-request/

License

GPLv3. See the License file.

graphite's People

Contributors

arisgk avatar ccasadiego avatar daniel-wang avatar daveloyall avatar epmills avatar ethanryan avatar joshuaaguilar20 avatar polluterofminds avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graphite's Issues

BUG - Export: links duplicated

Bug description

This is not blocking, just impacting performance. I noticed it while testing #16. The two downloads links will get rendered as many times as render() is getting invoked (over a dozen times), which pollutes the DOM tree.

Steps to reproduce

  • Go to "export all data"

Fix description

Move links generation in a separate function that will be invoked once & as soon as state is available.

Sheet with no name now inaccessible

Somehow I managed to save a sheet I was working on with an empty file name. The sheet is still listed in the file listing, but there is no way to click into it.

screenshot_20180606-194610_brave

Cannot add contact at https://app.graphitedocs.com/contacts

obraz
After clicking on desired result in contacts search, code throws GET error https://core.blockstack.org/v1/names/[object%20Object] not found.

Looking at your code problem may be here:

<a className="contact-add" onClick={() => this.props.handleAddContact(manualResults)}>
<-- instead of this.props.handleAddContact(manualResults) should be: this.props.handleAddContact(manualResults.name)

OS: Windows 10 x64
Browser: Tested on Chrome 71.0.3551.3 and Firefox 63.0b4

Authentication infinite loop

I installed Graphite and managed to run successfully. Now, I have issues with login.
I setup blockstack in Ubuntu 18.04 using the official install instructions.

Step 1: Download the official blockstack binary:
wget https://github.com/blockstack/blockstack-browser/releases/download/v0.25.0/Blockstack-for-Linux-v0.25.0.sh

Step 2: Run the installer

$ chmod a+x ./Blockstack-for-Linux-v0.25.0.sh
$ ./Blockstack-for-Linux-v0.25.0.sh pull
$ ./Blockstack-for-Linux-v0.25.0.sh start

Step 3: Setup blockstack CoreAPI:

I followed the instructions to setup an account.

{Note: The docker container and the on-screen instructions to enter CoreAPI password exposes the password as plain-text. I don't why it should be doing that, since the whole premise is to create a secure mechanism of collaboration?!}

Once the blockstack docker is running, I launched Firefox and launched the local instance of Graphite, running at localhost:8080.
It takes me to the login page, but I am stuck in an infinite loop. The app never successfully authenticates via blockstack.

Any thoughts on how to fix this?

Markdown support like Paper

It would be cool if graphite supported markdown like Dropbox Paper does - it works if you type it and doesn't affect you at all if you don't know it.

Add tooltips to menu-options in editors.

The purpose of some of the option of the menus in the editors is not clear. Adding tooltips when hovering over a certain button would greatly improve user-friendliness.

image

Design - Main App Landing Page

The current landing page after sign-in is helpful for navigation but it is plain and generally useless outside of the initial login. I'd love for this to be a page that people come back to even after log in.

Thoughts for the design:

-Make it data-rich
---Number of Documents
---Number of Sheets
---Total Word Count
---Number of Contacts
---Most common file-type for vault
---Number of Vault files

I think this page is a great place for quick navigation while also serving as a beautiful dashboard. The above are just some random dashboard ideas, but I'm open to others.

ERROR in ./src/index.js Module build failed: SyntaxError: Unexpected token (11:2) -- webpack: Failed to compile, error.

I tried compiling Graphite-Docs from source in Ubuntu 18.04, with nodejs legacy version 8 and npm package manager. I followed the install instructions from GitHub repo:

$ git clone https://github.com/Graphite-Docs/graphite
$ cd graphite
$ git checkout
$ sudo npm install
$ sudo npm run start

When I run 'npm run start' I am getting this error message: webpack failed to compile.

Any ideas on how to fix this?

--- Full console log ---

[email protected] start /home/rahulremanan/graphite
NODE_ENV=development webpack-dev-server

Project is running at http://localhost:8081/
webpack output is served from /
404s will fallback to /index.html
Hash: 68f421c2fbb264cb29dc
Version: webpack 2.7.0
Time: 10226ms
Asset Size Chunks Chunk Names
index_bundle.js 142 kB 0 [emitted] main
index.html 3.76 kB [emitted]
manifest.json 282 bytes [emitted]
icon-192x192.png 44.8 kB [emitted]
chunk {0} index_bundle.js (main) 318 kB [entry] [rendered]
[2] ./src/index.js 644 bytes {0} [built] [failed] [1 error]
[3] (webpack)-dev-server/client?http://localhost:8081 7.95 kB {0} [built]
[6] .//events/events.js 8.33 kB {0} [built]
[7] ./
/html-entities/index.js 231 bytes {0} [built]
[10] .//loglevel/lib/loglevel.js 7.86 kB {0} [built]
[11] ./
/punycode/punycode.js 14.7 kB {0} [built]
[15] .//sockjs-client/dist/sockjs.js 181 kB {0} [built]
[16] ./
/strip-ansi/index.js 161 bytes {0} [built]
[17] .//url/url.js 23.3 kB {0} [built]
[18] ./
/url/util.js 314 bytes {0} [built]
[19] (webpack)-dev-server/client/overlay.js 3.73 kB {0} [built]
[20] (webpack)-dev-server/client/socket.js 1.05 kB {0} [built]
[22] (webpack)/hot nonrecursive ^./log$ 160 bytes {0} [built]
[23] (webpack)/hot/emitter.js 77 bytes {0} [built]
[24] multi (webpack)-dev-server/client?http://localhost:8081 ./src/index.js 40 bytes {0} [built]
+ 10 hidden modules

ERROR in ./src/index.js
Module build failed: SyntaxError: Unexpected token (11:2)

9 |
10 | ReactDOM.render(

11 | ,
| ^
12 | document.getElementById('root')
13 | );
14 |

@ multi (webpack)-dev-server/client?http://localhost:8081 ./src/index.js
Child html-webpack-plugin for "index.html":
chunk {0} index.html 545 kB [entry] [rendered]
[0] .//lodash/lodash.js 540 kB {0} [built]
[1] ./
/html-webpack-plugin/lib/loader.js!./src/index.html 4.14 kB {0} [built]
[2] (webpack)/buildin/global.js 509 bytes {0} [built]
[3] (webpack)/buildin/module.js 517 bytes {0} [built]
webpack: Failed to compile.

Secure Public Drop

You provide a link, users can drop any file type, 5mb or less, and it will be encrypted with your pubKey, accessible only by you.

Feature: Calendar

I would like to see calendar functionality wherein you can add an event to a day with a title, description, start and end-time and the option to invite other blockstack users to this event.

Document Not Saved

Not sure how to repeat this but spent an hour on a document and it was not saved. The next time I went there it was blank.

Using Safari on Mac.

Separate issue, safari often show's a blank page after a certain amount of time, just all white.

Install issue: Bower Deprecated (Raspbian - fully updated)

i'm surprised to not see this in the issues list already.

would liked to have used the community brains trust to resolve.

virgin os, fully patched up, raspberry pi3 on debian

gets:
root@base:/home/pi/graphite# npm install
(node:6434) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.
npm WARN deprecated [email protected]: Handsontable for React is now available as @handsontable/react.
npm ERR! Error: Method Not Allowed
npm ERR! at errorResponse (/usr/share/npm/lib/cache/add-named.js:260:10)
npm ERR! at /usr/share/npm/lib/cache/add-named.js:203:12
npm ERR! at saved (/usr/share/npm/node_modules/npm-registry-client/lib/get.js:167:7)
npm ERR! at FSReqWrap.oncomplete (fs.js:135:15)
npm ERR! If you need help, you may report this entire log,
npm ERR! including the npm and node versions, at:
npm ERR! http://github.com/npm/npm/issues

npm ERR! System Linux 4.14.69-v7+
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! cwd /home/pi/graphite
npm ERR! node -v v8.11.1
npm ERR! npm -v 1.4.21
npm ERR! code E405
npm WARN deprecated [email protected]: We don't recommend using Bower for new projects. Please consider Yarn and Webpack or Parcel. You can read how to migrate legacy project here: https://bower.io/blog/2017/how-to-migrate-away-from-bower/
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/pi/graphite/npm-debug.log
npm ERR! not ok code 0

Design: Onboarding Indicators

Currently, when a user first starts using Graphite, there are not many calls to actions. The Dashboard will be updated and will need some sort of call to action, but the focus here is on each of the component pages:

  1. Docs
  2. Sheets
  3. Contacts
  4. Vault

What should the user do? Add a doc? Add a contact? On first visit, there should be some design mechanism to help the user learn what to do next.

BUG: Shared Sheets Cannot Be Added To Collection

Steps to reproduce:

  1. Have someone share a sheet with you.
  2. Go to your shared sheets from that user.
  3. Open the sheet.
  4. Click Add to Sheets

Expected outcome is that file becomes part of your Sheets Collection. Actual outcome is that the Sheet is not added.

not able to save document, JS errors

OS: Ubuntu 17.10
Browser: Version 64.0.3282.186 (Official Build) (64-bit)

I installed blockstack and managed to log in, but not documents are saved...it says "saving" constantly.

Looking at the Chrome console I see the following JS errors:

Uncaught Error: Private key must be less than the curve order
at new ECPair (index_bundle.js:1)
at t.getPublicKeyFromPrivate (index_bundle.js:1)
at t.value (index_bundle.js:1)
at index_bundle.js:1
at o (index_bundle.js:1)
at index_bundle.js:1
at e.notifyAll (index_bundle.js:1)
at r.close (index_bundle.js:1)
at r.closeAll (index_bundle.js:1)
at r.perform (index_bundle.js:1)
at a (index_bundle.js:1)
at r.perform (index_bundle.js:1)
at Object.batchedUpdates (index_bundle.js:1)
at Object.batchedUpdates (index_bundle.js:1)
at Object._renderNewRootComponent (index_bundle.js:1)
at Object._renderSubtreeIntoContainer (index_bundle.js:1)
documents:1

graphite

not sure if the above is related to the issue that no documents are saved.

TypeError: Cannot read property 'toUpperCase' of undefined

Title: TypeError: Cannot read property 'toUpperCase' of undefined
Environment: Linux Mint 19, NPM 3.5.2, Chromium Version 68.0.3440.75,
Steps to reproduce: Add a PDF or image file to the Vault, Click to add a tag to the file, and type in a three letter tag in all CAPS. ie... ABC
Expected Result: It should have added the tag to the file
Actual Result: This has caused a major issue and now I can't even get into my Vault anymore. When I try to click on my Graphite Vault I am getting the following error:
×
TypeError: Cannot read property 'toUpperCase' of undefined
(anonymous function)
src/components/vault/VaultCollection.js:725
722 | {
723 | uniqueType.map(type => {
724 | return (

725 |

  • <a onClick={() => this.setState({ selectedType: type, typeList: "hide", applyFilter: true})}>{type.split('/')[1].toUpperCase()}

  • 726 | )
    727 | })
    728 | }
    View compiled
    VaultCollection.render
    src/components/vault/VaultCollection.js:723
    720 | {/* Type list */}
    721 |

      722 | {
      723 | uniqueType.map(type => {
      724 | return (
      725 |
    • <a onClick={() => this.setState({ selectedType: type, typeList: "hide", applyFilter: true})}>{type.split('/')[1].toUpperCase()}

    • 726 | )
      View compiled
      ▶ 17 stack frames were collapsed.
      (anonymous function)
      src/components/vault/VaultCollection.js:144
      141 | .then((fileContents) => {
      142 | if(fileContents){
      143 | this.setState({ files: JSON.parse(fileContents || '{}') });
      144 | this.setState({filteredValue: this.state.files});
      145 | }else {
      146 | this.setState({ files: [] });
      147 | this.setState({filteredValue: []});
      View compiled
      This screen is visible only in development. It will not appear if the app crashes in production.
      Open your browser’s developer console to further inspect this error.

    Visual Proof (screenshots, videos, text):
    typeerror

    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.