diff --git a/_browser/todo-list.md b/_browser/todo-list.md index e6bc7d83..05c73589 100644 --- a/_browser/todo-list.md +++ b/_browser/todo-list.md @@ -59,7 +59,7 @@ If you don’t find `npm` in your system, [install it](https://www.npmjs.com/get Finally, make sure you have [created at least one Blockstack ID]({{site.baseurl}}/browser/ids-introduction.html#create-an-initial-blockstack-id). You’ll use this ID to interact with the application. -## Install the application code and retrieve the dependencies +## Task 1: Install the code and retrieve the dependencies You can clone the source code with `git` or [download and unzip the code from the @@ -96,7 +96,7 @@ The Todo application has a basic Vue.js structure. There are several configurati | `components/Dashboard.vue` | Application data storage and user sign out. | -## Sign into the application +## Task 2: Sign into the application The example application runs in a node server on your local host. In the this section, you start the application and interact with it. @@ -109,17 +109,31 @@ The example application runs in a node server on your local host. In the this se This path will be different for you, but double-check the last part to ensure that you're in the directory into which you cloned and in which you ran `npm install`. -2. Start the application. +2. Start the application in your local environment. + ```bash + $ npm run serve ``` - $ npm run start - ``` + You should see output similar to the following: + + ```bash + 98% after emitting CopyPlugin s + DONE Compiled successfully in 5854ms 7:34:28 PM + + App running at: + - Local: http://localhost:8080/ + - Network: http://192.168.0.12:8080/ + Note that the development build is not optimized. + To create a production build, run npm run build. + ``` +2. Open your local browser to the `http://localhost:8080` URL. + You should see a simple application: ![](images/todo-sign-in.png) - 2. Choose **Sign In with Blockstack**. + 3. Choose **Sign In with Blockstack**. If you have already signed into Blockstack the application prompts you to select the ID to use. If you aren’t signed in, Blockstack prompts you to: @@ -129,13 +143,19 @@ The example application runs in a node server on your local host. In the this se ![](images/todo-app.png) -## Understand the sign in process +## Task 3: Larn about the sign in process {% include sign_in.md %} + +## Task 4: Decode the authRequest + To decode the token and see what information it holds: 1. Copy the `authRequest` string from the URL. + + + 2. Navigate to [jwt.io](https://jwt.io/). 3. Paste the full token there. @@ -143,28 +163,29 @@ To decode the token and see what information it holds: ```json { - "jti": "3i96e3ad-0626-4e32-a316-b243154212e2", - "iat": 1533136622, - "exp": 1533140228, - "iss": "did:btc-addr:1Nh8oQTunbEQWjrL666HBx2qMc81puLmMt", + "jti": "f65f02db-9f42-4523-bfa9-8034d8edf459", + "iat": 1555641911, + "exp": 1555645511, + "iss": "did:btc-addr:1ANL7TNdT7TTcjVnrvauP7Mq3tjcb8TsUX", "public_keys": [ - "0362173da080c6e1dec0653fa9a3eff5f5660546e387ce6c24u04a90c2fe1fdu73" + "02f08d5541bf611ded745cc15db08f4447bfa55a55a2dd555648a1de9759aea5f9" ], "domain_name": "http://localhost:8080", "manifest_uri": "http://localhost:8080/manifest.json", - "redirect_uri": "http://localhost:8080/", - "version": "1.2.0", + "redirect_uri": "http://localhost:8080", + "version": "1.3.1", "do_not_include_profile": true, "supports_hub_url": true, "scopes": [ - "store_write" + "store_write", + "publish_data" ] } ``` The `iss` property is a decentralized identifier or `did`. This identifies the user and the user name to the application. The specific `did` is a `btc-addr`. -## Under the covers in the sign in code +## Task 5: Under the covers in the sign in code Now, go to the underlying `blockstack-todo` code you cloned or downloaded. Sign in and sign out is handled in each of these files: @@ -175,26 +196,32 @@ in and sign out is handled in each of these files: | `Landing.vue ` | Generates the `authRequest`. | | `Dashboard.vue` | Handles sign out. | -The `src/components/Landing.vue` code calls a [`redirectToSignIn()`](https://blockstack.github.io/blockstack.js#redirectToSignIn) function which generates the `authRequest` and redirects the user to the Blockstack authenticator: +The `src/components/Landing.vue` code configures an `AppConfig` object and then uses this to create a `UserSession`. Then, the application calls a [`redirectToSignIn()`](https://blockstack.github.io/blockstack.js#redirectToSignIn) function which generates the `authRequest` and redirects the user to the Blockstack authenticator: ```js -signIn () { - const blockstack = this.blockstack - blockstack.UserSession.redirectToSignIn() -} + signIn () { + const appConfig = new this.blockstack.AppConfig(['store_write', 'publish_data']) + const UserSession = new this.blockstack.UserSession({ appConfig: appConfig }) + UserSession.redirectToSignIn() + } ``` Once the user authenticates, the application handles the `authResponse` in the `src/App.vue` file. : ```js -if (blockstack.isUserSignedIn()) { - this.user = blockstack.UserSession.loadUserData().profile -} else if (blockstack.UserSession.isSignInPending()) { - blockstack.UserSession.handlePendingSignIn() - .then((userData) => { - window.location = window.location.origin - }) -} + mounted () { + const UserSession = this.UserSession + if (UserSession.isUserSignedIn()) { + this.userData = UserSession.loadUserData() + this.user = new this.blockstack.Person(this.userData.profile) + this.user.username = this.userData.username + } else if (UserSession.isSignInPending()) { + UserSession.handlePendingSignIn() + .then((userData) => { + window.location = window.location.origin + }) + } + }, ``` If [`blockstack.isUserSignedIn()`](https://blockstack.github.io/blockstack.js/#isusersignedin) is true, the user was previously signed in so Blockstack pulls the data from the browser and uses it in our application. If the check on [`blockstack.UserSession.isSignInPending()`](https://blockstack.github.io/blockstack.js/#issigninpending) is true, a previous `authResponse` was sent to the application but hasn't been processed yet. The `handlePendingSignIn()` function processes any pending sign in. @@ -202,28 +229,27 @@ If [`blockstack.isUserSignedIn()`](https://blockstack.github.io/blockstack.js/#i Signout is handled in `src/components/Dashboard.vue`. ```js -signOut () { - this.blockstack.signUserOut(window.location.href) -} + signOut () { + this.UserSession.signUserOut(window.location.href) + } ``` The method allows the application creator to decide where to redirect the user upon Sign Out: -## Working with the application +## Task 6: Work with the application -Now, trying adding a few itmes to the todo list. For example, try making a list of applications you want to see built on top of Blockstack: +Now, trying adding a few items to the todo list. For example, try making a list of applications you want to see built on top of Blockstack: ![](images/make-a-list.png) Each list is immediately stored in the Gaia Hub linked to your Blockstack ID. -For more information about the Gaia hub, see the [hub -repository](https://github.com/blockstack/gaia). You can fetch the `todos.json` +For more information about the Gaia hub, [see the overview in this documentation]({{ site.baseurl }}/storage/overview.html#). You can fetch the `todos.json` file you just added by opening the Javascript console and running the following command: ```Javascript -blockstack.UserSession.getFile("todos.json", { decrypt: true }).then((file) => {console.log(file)}) +blockstack.getFile("todos.json", { decrypt: true }).then((file) => {console.log(file)}) ``` You should see a JSON with the todos you just added: @@ -270,7 +296,7 @@ using the Javascript console, the results reflect your change. Look for `"comple Now that you have seen the application in action, dig into how it works. -## Implementing storage +## Task 7: Implement storage Go to the underlying `blockstack-todo` code you cloned or downloaded. The application interactions with your Gaia Hub originate in the @@ -278,15 +304,17 @@ application interactions with your Gaia Hub originate in the Todos are processed: ```js -todos: { - handler: function (todos) { - const blockstack = this.blockstack - - // encryption is now enabled by default - return blockstack.UserSession.putFile(STORAGE_FILE, JSON.stringify(todos)) +watch: { + todos: { + handler: function (todos) { + const UserSession = this.UserSession + + // encryption is now enabled by default + return UserSession.putFile(STORAGE_FILE, JSON.stringify(todos)) + }, + deep: true + } }, - deep: true -} ``` The `todos` JSON object is passed in and the @@ -297,16 +325,16 @@ The code needs to read the Todo items from the storage with the [`blockstack.Use ```js fetchData () { - const blockstack = this.blockstack - blockstack.UserSession.getFile(STORAGE_FILE) // decryption is enabled by default - .then((todosText) => { - var todos = JSON.parse(todosText || '[]') - todos.forEach(function (todo, index) { - todo.id = index - }) - this.uidCount = todos.length - this.todos = todos - }) + const UserSession = this.UserSession + UserSession.getFile(STORAGE_FILE) // decryption is enabled by default + .then((todosText) => { + var todos = JSON.parse(todosText || '[]') + todos.forEach(function (todo, index) { + todo.id = index + }) + this.uidCount = todos.length + this.todos = todos + }) }, ``` @@ -314,6 +342,7 @@ The `todos` data is retrieved from the promise. ## Summary +{:.no_toc} You now have everything you need to construct complex applications complete with authentication and storage on the Decentralized Internet. Why not try coding [a sample application that accesses multiple profiles](blockstack_storage.html). diff --git a/_develop/images/copy-authRequest.png b/_develop/images/copy-authRequest.png new file mode 100644 index 00000000..0dcc4170 Binary files /dev/null and b/_develop/images/copy-authRequest.png differ