From afd648c47fbba7fcc99b0d2dadf78b70773a3abf Mon Sep 17 00:00:00 2001 From: Mary Anthony Date: Thu, 18 Apr 2019 19:15:31 -0700 Subject: [PATCH] Search and replace auth to add UserSessions Signed-off-by: Mary Anthony --- _browser/hello-blockstack.md | 6 +-- _browser/todo-list.md | 20 +++++----- _develop/add_auth.md | 6 ++- _develop/overview_auth.md | 42 +++++++++----------- _develop/profiles.md | 77 +++++++++++++++++++----------------- _develop/storage.md | 19 +++++---- _includes/sign_in.md | 4 +- _storage/hello-hub-choice.md | 2 +- overview_auth.md | 4 +- 9 files changed, 92 insertions(+), 88 deletions(-) diff --git a/_browser/hello-blockstack.md b/_browser/hello-blockstack.md index 19db85be..e5f62270 100644 --- a/_browser/hello-blockstack.md +++ b/_browser/hello-blockstack.md @@ -259,10 +259,10 @@ The application handles these situations as followed: ```js if (blockstack.isUserSignedIn()) { - var profile = blockstack.loadUserData().profile + var profile = blockstack.UserSession.loadUserData().profile showProfile(profile) -} else if (blockstack.isSignInPending()) { - blockstack.handlePendingSignIn().then(function(userData) { +} else if (blockstack.UserSession.isSignInPending()) { + blockstack.UserSession.handlePendingSignIn().then(function(userData) { window.location = window.location.origin }) } diff --git a/_browser/todo-list.md b/_browser/todo-list.md index 63ab6f9b..e6bc7d83 100644 --- a/_browser/todo-list.md +++ b/_browser/todo-list.md @@ -180,7 +180,7 @@ The `src/components/Landing.vue` code calls a [`redirectToSignIn()`](https://blo ```js signIn () { const blockstack = this.blockstack - blockstack.redirectToSignIn() + blockstack.UserSession.redirectToSignIn() } ``` @@ -188,16 +188,16 @@ Once the user authenticates, the application handles the `authResponse` in the ` ```js if (blockstack.isUserSignedIn()) { - this.user = blockstack.loadUserData().profile -} else if (blockstack.isSignInPending()) { - blockstack.handlePendingSignIn() + this.user = blockstack.UserSession.loadUserData().profile +} else if (blockstack.UserSession.isSignInPending()) { + blockstack.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.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. Signout is handled in `src/components/Dashboard.vue`. @@ -223,7 +223,7 @@ file you just added by opening the Javascript console and running the following command: ```Javascript -blockstack.getFile("todos.json", { decrypt: true }).then((file) => {console.log(file)}) +blockstack.UserSession.getFile("todos.json", { decrypt: true }).then((file) => {console.log(file)}) ``` You should see a JSON with the todos you just added: @@ -283,22 +283,22 @@ todos: { const blockstack = this.blockstack // encryption is now enabled by default - return blockstack.putFile(STORAGE_FILE, JSON.stringify(todos)) + return blockstack.UserSession.putFile(STORAGE_FILE, JSON.stringify(todos)) }, deep: true } ``` The `todos` JSON object is passed in and the -[`blockstack.putFile()`](https://blockstack.github.io/blockstack.js/#putfile) +[`blockstack.UserSession.putFile()`](https://blockstack.github.io/blockstack.js/#putfile) method to store it in a Gaia Hub. -The code needs to read the Todo items from the storage with the [`blockstack.getFile()`](https://blockstack.github.io/blockstack.js/#getfile) method which returns a promise: +The code needs to read the Todo items from the storage with the [`blockstack.UserSession.getFile()`](https://blockstack.github.io/blockstack.js/#getfile) method which returns a promise: ```js fetchData () { const blockstack = this.blockstack - blockstack.getFile(STORAGE_FILE) // decryption is enabled by default + blockstack.UserSession.getFile(STORAGE_FILE) // decryption is enabled by default .then((todosText) => { var todos = JSON.parse(todosText || '[]') todos.forEach(function (todo, index) { diff --git a/_develop/add_auth.md b/_develop/add_auth.md index 283d4191..4006165c 100644 --- a/_develop/add_auth.md +++ b/_develop/add_auth.md @@ -51,8 +51,8 @@ To check for the presence of this token, your app should call `UserSession.isSig ```js import * as blockstack from 'blockstack' -if (blockstack.isSignInPending()) { - blockstack.handlePendingSignIn() +if (blockstack.UserSession.isSignInPending()) { + blockstack.UserSession.handlePendingSignIn() .then(userData => { const profile = userData.profile }) @@ -60,6 +60,8 @@ if (blockstack.isSignInPending()) { ``` +By default, these method use the `store_write` scope which allows the DApp to read the user profile and read/write user data for the DApp. To specify a different scope, use a AppConfig object. + ### Custom flows Alternatively, you can generate your own transit private key and/or diff --git a/_develop/overview_auth.md b/_develop/overview_auth.md index 20da5cea..d2b92a9d 100644 --- a/_develop/overview_auth.md +++ b/_develop/overview_auth.md @@ -2,7 +2,9 @@ layout: learn permalink: /:collection/:path.html --- + # Understand Blockstack Auth + {:.no_toc} Blockstack Auth provides single sign on and authentication without third parties or remote servers. On this page, you'll get an overview of authentication from an developer and user perspective. The following topics are covered: @@ -10,7 +12,6 @@ Blockstack Auth provides single sign on and authentication without third parties * TOC {:toc} - ## User experience flow Blockstack Auth is a bearer token-based authentication system. From an application user's perspective, Blockstack authentication is similar to legacy third-party authentication techniques that they're familiar with. Applications present users with a **Sign in with Blockstack** button. @@ -18,23 +19,22 @@ Blockstack Auth is a bearer token-based authentication system. From an applicati ![](images/signwithblockstack.png) Assume a user, Alice, clicks the **Sign in with Blockstack** button on an app. She is -redirected to her copy of the Blockstack Browser. If the user has -signed into the DApp previously. The actual Blockstack sign-in dialog depends on -whether the user already has an existing session in the Blockstack Browser. +redirected to her copy of the Blockstack Browser. The Blockstack sign-in dialog a user sees depends on +whether the user already has an existing Blockstack Browser session for their current device. -Alice can choose to authenticate as one of her Blockstack IDs by selecting the -ID and clicking the **Approve** button. The Blockstack Browser shows Alice an approval dialog with information about your app including: +Signing in with an identity is the means by which the user grants the DApp access. Access depends on the scope requested by the DApp. The default `store_write` scope allows the DApp to read the user profile and read/write user data for the DApp. Data is encrypted at a unique URL on a Gaia storage hub. + +Alice can choose to authenticate and sign into the DApp with one of her Blockstack IDs by selecting the +ID. The Blockstack Browser shows Alice an approval dialog with information about the access the DApp requests: * The origin your app was served from * Your app's name * Your app's logo * The types of permissions and data your app is requesting -Signing in with an identity is the means by which the user grants the DApp access. Access depends on the scope requested by the DApp. The default `store_write` scope allows the DApp to read the user profile and read/write user data for the DApp. Data is encrypted at a unique URL on a Gaia storage hub. - -When she clicks approve, Alice is redirected back to the DApp where she is logged in. +When she chooses an ID (or creates a new one), Alice is redirected back to the DApp where she is logged in. ## DApp authentication flow @@ -42,8 +42,7 @@ When she clicks approve, Alice is redirected back to the DApp where she is logge ## Scopes -Scopes define the information and permissions an app requests from the -user during authentication. This determines the set of permissions a user reads and accepts by choose an ID to sign in with. +Scopes define the permissions requested from, and that a user accepts, through the sign-in dialog. DApps may request any of the following scopes: | Scope | Definition| @@ -52,16 +51,12 @@ DApps may request any of the following scopes: | `publish_data` | Publish data so that other users of the app can discover and interact with the user. | | `email` | Requests the user's email if available. | -If no `scopes` array is provided to the `redirectToSignIn` or `makeAuthRequest` +The permissions scope should be specified through the AppConfig object. If no `scopes` array is provided to the `redirectToSignIn` or `makeAuthRequest` functions, the default is to request `['store_write']`. - ## blockstack: custom protocol handler -The `blockstack:` custom protocol handler is how Blockstack apps send their -authentication requests to the Blockstack Browser. When the Blockstack Browser -is installed on a user's computer, it registers itself as the handler for the -`blockstack:` customer protocol. +The `blockstack:` custom protocol handler is how Blockstack apps send their authentication requests to the Blockstack Browser. Users can have a Blockstack Browser installed locally on their device or they can use the web version of the Blockstack Browser. If the Blockstack Browser is installed on a user's computer, it registers itself as the handler for the `blockstack:` customer protocol. When an application calls [`redirectToSignIn`](http://blockstack.github.io/blockstack.js/index.html#redirecttosignin) @@ -69,8 +64,7 @@ or [`redirectToSignInWithAuthRequest`](http://blockstack.github.io/blockstack.js/index.html#redirecttosigninwithauthrequest), blockstack.js checks if a `blockstack:` protocol handler is installed and, if so, redirects the user to `blockstack:`. This passes the -authentication request token from the app to the Blockstack Browser, which will -in turn validate the request and display an authentication dialog. +authentication request token from the app to the local Blockstack Browser. If the local Blockstack Browser is not installed, the call is directed to the web version of the Blockstack Browser. ## Manifest file @@ -90,8 +84,8 @@ Blockstack apps have a manifest file. This file is based on the [W3C web app man ``` The Blockstack Browser retrieves the manifest file from the app during the -authentication process and displays some of the information in it such as the -app name and icon to the user. The location of the app manifest file is specific +authentication process and displays the information in it such as the +app `name` and to the user during sign in. The location of the app manifest file is specific in the authentication request token and **must** be on the same origin as the app requesting authentication. @@ -107,9 +101,9 @@ How you implement CORS depends in part on which platform/service you use to serv Blockstack Auth makes extensive use of public key cryptography. Blockstack uses ECDSA with the `secp256k1` curve. The following sections describe the three public-private key pairs used in the authentication process: -* how they're generated, -* where they're used -* to whom the private key is disclosed. +* how they're generated +* where they're used +* to whom the private key is disclosed ### Transit private key diff --git a/_develop/profiles.md b/_develop/profiles.md index 91ca47f7..f45a6319 100644 --- a/_develop/profiles.md +++ b/_develop/profiles.md @@ -6,18 +6,42 @@ permalink: /:collection/:path.html {:.no_toc} -Blockstack Auth provides single sign on and authentication without third parties or remote servers. On this page, you'll get an overview of authentication from an developer and user perspective. The following topics are covered: + + +You can use the blockstack.js library to create and register an ID on the Stacks blockchain. This section describes the `Profile` object and contains the following topics: * TOC {:toc} -You can use the blockstack.js library to create and register an ID on the Stacks blockchain. Follow these steps to create and register a profile for a Blockchain ID: +## About profiels + +Profile data is stored using Gaia on the user's selected storage provider. An example of a `profile.json` file URL using Blockstack provided storage: + +``` +https://gaia.blockstack.org/hub/1EeZtGNdFrVB2AgLFsZbyBCF7UTZcEWhHk/profile.json +``` + + +Follow these steps to create and register a profile for a Blockstack ID: 1. Create a JSON profile object 2. Split up the profile into tokens, sign the tokens, and put them in a token file 3. Create a zone file that points to the web location of the profile token file +Accounts can have one or more proofs. Proofs are stored under the `account` key in the user's profile data + +```js +"account": [ + { + "@type": "Account", + "service": "twitter", + "identifier": "naval", + "proofType": "http", + "proofUrl": "https://twitter.com/naval/status/12345678901234567890" + } +] +``` ## Create a profile @@ -60,20 +84,12 @@ try { const recoveredProfile = Person.fromToken(tokenFile, publicKey) ``` -### Validate profile schema +## Validate profile schema ```js const validationResults = Person.validateSchema(recoveredProfile) ``` -## Where profile data is stored - -Profile data is stored using Gaia on the user's selected storage provider. - -An example of a profile.json file URL using Blockstack provided storage: -`https://gaia.blockstack.org/hub/1EeZtGNdFrVB2AgLFsZbyBCF7UTZcEWhHk/profile.json` - - ## Validate a proof ```es6 @@ -86,15 +102,23 @@ validateProofs(profile, domainName).then((proofs) => { ``` ## How proofs are validated + The `validateProofs` function checks each of the proofs listed in the -profile by fetching the proof URL and verifying the proof message. +profile by fetching the proof URL and verifying the proof message. Currently supported proof validation services: + +- Facebook +- Twitter +- Instagram +- LinkedIn +- Hacker News +- GitHub The proof message must be of the form: + ``` Verifying my Blockstack ID is secured with the address 1EeZtGNdFrVB2AgLFsZbyBCF7UTZcEWhHk ``` - The proof message also must appear in the required location on the proof page specific to each type of social media account. @@ -103,7 +127,8 @@ the account identifier/username claimed in the user profile. The `validateProofs` function will check this in the body of the proof or in the proof URL depending on the service. -### Adding additional social account validation services +## Adding additional social account validation services + The `Service` class can be extended to provide proof validation service to additional social account types. You will need to override the `getProofStatement(searchText: string)` method which parses the proof @@ -125,26 +150,4 @@ static getProofStatement(searchText: string) { return '' } } -``` - -## Currently supported proof validation services -- Facebook -- Twitter -- Instagram -- LinkedIn -- Hacker News -- GitHub - -## Profile proof schema -Proofs are stored under the `account` key in the user's profile data -```js -"account": [ - { - "@type": "Account", - "service": "twitter", - "identifier": "naval", - "proofType": "http", - "proofUrl": "https://twitter.com/naval/status/12345678901234567890" - } -] -``` +``` \ No newline at end of file diff --git a/_develop/storage.md b/_develop/storage.md index ec584369..5d65e300 100644 --- a/_develop/storage.md +++ b/_develop/storage.md @@ -12,7 +12,7 @@ The Blockstack Platform stores application data in the Gaia Storage System. Tran {:toc} -{% include note.html content="
  • Blockstack Gaia Storage APIs and on-disk format will change in upcoming pre-releases breaking backward compatibility. File encryption is currently opt-in on a file by file basis.
  • Certain storage features such as and collections are not implemented in the current version. These features will be rolled out in future updates.
" %} +{% include note.html content="
  • Blockstack Gaia Storage APIs and on-disk format will change in upcoming pre-releases breaking backward compatibility. File encryption is currently opt-in on a file by file basis.
  • Certain storage features such as collections are not implemented in the current version. These features will be rolled out in future updates.
" %} ## Creating a file @@ -23,7 +23,7 @@ You use the { // /hello.txt exists now, and has the contents "hello world!". }) @@ -38,7 +38,7 @@ You use the { // message.txt exists now, and has the contents "hello world!". }) @@ -53,7 +53,7 @@ You use the { // get the contents of the file /hello.txt assert(fileContents === "hello world!") @@ -69,7 +69,7 @@ You use the decrypt: true } - blockstack.getFile("/message.txt", options) + blockstack.UserSession.getFile("/message.txt", options) .then((fileContents) => { // get & decrypt the contents of the file /message.txt assert(fileContents === "Secret hello!") @@ -86,7 +86,7 @@ the `publish_data` scope during authentication. app: 'http://BlockstackApp.com' // origin of the app this file is stored for } - blockstack.getFile("/message.txt", options) + blockstack.UserSession.getFile("/message.txt", options) .then((fileContents) => { // get the contents of the file /message.txt assert(fileContents === "hello world!") @@ -95,7 +95,7 @@ the `publish_data` scope during authentication. ## Delete a file -You use the UserSession.deleteFile +You use the UserSession.deleteFile from the application's data store. ```JavaScript @@ -104,3 +104,8 @@ You use the