@ -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).
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.
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
You can clone the source code with `git` or [download and unzip the code from
the
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. |
| `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.
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`.
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:
You should see a simple application:
![](images/todo-sign-in.png)
![](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:
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)
![](images/todo-app.png)
## Understand the sign in process
## Task 3: Larn about the sign in process
{% include sign_in.md %}
{% include sign_in.md %}
## Task 4: Decode the authRequest
To decode the token and see what information it holds:
To decode the token and see what information it holds:
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`.
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
Now, go to the underlying `blockstack-todo` code you cloned or downloaded. Sign
in and sign out is handled in each of these files:
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`. |
| `Landing.vue ` | Generates the `authRequest`. |
| `Dashboard.vue` | Handles sign out. |
| `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
```js
signIn () {
signIn () {
const blockstack = this.blockstack
const appConfig = new this.blockstack.AppConfig(['store_write', 'publish_data'])
blockstack.UserSession.redirectToSignIn()
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. :
Once the user authenticates, the application handles the `authResponse` in the `src/App.vue` file. :
} else if (blockstack.UserSession.isSignInPending()) {
if (UserSession.isUserSignedIn()) {
blockstack.UserSession.handlePendingSignIn()
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) => {
.then((userData) => {
window.location = window.location.origin
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.
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.
@ -203,27 +230,26 @@ Signout is handled in `src/components/Dashboard.vue`.
The method allows the application creator to decide where to redirect the user upon Sign Out:
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)
![](images/make-a-list.png)
Each list is immediately stored in the Gaia Hub linked to your Blockstack ID.
Each list is immediately stored in the Gaia Hub linked to your Blockstack ID.
For more information about the Gaia hub, see the [hub
For more information about the Gaia hub, [see the overview in this documentation]({{ site.baseurl }}/storage/overview.html#). You can fetch the `todos.json`
repository](https://github.com/blockstack/gaia). You can fetch the `todos.json`
file you just added by opening the Javascript console and running the following
file you just added by opening the Javascript console and running the following
@ -297,8 +325,8 @@ The code needs to read the Todo items from the storage with the [`blockstack.Use
```js
```js
fetchData () {
fetchData () {
const blockstack = this.blockstack
const UserSession = this.UserSession
blockstack.UserSession.getFile(STORAGE_FILE) // decryption is enabled by default
UserSession.getFile(STORAGE_FILE) // decryption is enabled by default
.then((todosText) => {
.then((todosText) => {
var todos = JSON.parse(todosText || '[]')
var todos = JSON.parse(todosText || '[]')
todos.forEach(function (todo, index) {
todos.forEach(function (todo, index) {
@ -314,6 +342,7 @@ The `todos` data is retrieved from the promise.
## Summary
## 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).
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).