Below, you can see the relevant parts of the [React component](https://reactjs.org/docs/react-component.html)
This modal is displayed using the `authenticate` function exported by the `src/stacks.js` module, which organizes all Stacks resources needed across the app:
that triggers this modal in [`src/components/Signin.jsx`](https://github.com/blockstack/stacks-todos/blob/master/src/components/Signin.jsx):
```js
```js
// src/components/Signin.jsx
// src/stacks.js
import { useConnect } from '@stacks/auth';
import { AppConfig, UserSession, showBlockstackConnect } from '@stacks/auth';
const appConfig = new AppConfig(['store_write', 'publish_data']);
// src/components/App.jsx
export const userSession = new UserSession({ appConfig });
export const storage = new Storage({ userSession });
export function authenticate(sendToSignIn) {
showBlockstackConnect({
appDetails: {
name: 'Todos',
icon: window.location.origin + '/logo.svg',
},
redirectTo: '/',
finished: () => {
window.location.reload();
},
sendToSignIn: sendToSignIn,
userSession: userSession,
});
}
appDetails: {
export function getUserData() {
name: 'Stacks App',
return userSession.loadUserData();
icon: window.location.origin + '/favicon.ico'
}
}
export function getPerson() {
return new Person(getUserData().profile);
}
```
```
This component loads the [`UserSession`](https://blockstack.github.io/stacks.js/classes/usersession.html)
The `authenticate` function implements the `showBlockstackConnect` function imported from the `@stacks/auth` library.
module from `@stacks/auth`
```js
import { UserSession } from '@stacks/auth';
import { appConfig } from '../assets/constants';
// ...
`showBlockstackConnect` triggers the display of a modal that initiates the authentication process for users, one in which they'll authenticate with a _Secret Key_ that's used to encrypt their private data.
const userSession = new UserSession({ appConfig });
The `showBlockstackConnect` function accepts a number of properties within a parameter object such as:
```
This module handles user session operations and is initiated using the
- The app's `name` and `icon`: provided as strings comprising the `appDetails` object property.
- The `redirectTo` string: used to provide a URL to which the user should be redirected upon successful authentication. The `finished` callback serves a similar purpose by handling successful authentication within a context of a popup window.
which contains an array of [scopes](/authentication/overview#scopes) that indicate just what permissions
- The `sendToSignIn` boolean: used to indicate whether the user should proceed through the "registration" flow (in which they'll be given a newly generated _Secret Key_) or whether they should proceed through the "sign in" flow (in which they'll be prompted to enter an existing _Secret Key_).
to grant during authentication:
- The `userSession` object: used to pass the [scopes](/authentication/overview#scopes) needed by the app.
```js
Note how the `userSession` object is created at the beginning of this module by leveraging an `AppConfig` object that's first initiated with all relevant scopes.
// src/assets/constants.js
export const appConfig = new AppConfig(['store_write', 'publish_data']);
The [`UserSession`](https://blockstack.github.io/stacks.js/classes/usersession.html) and [`AppConfig`](https://blockstack.github.io/stacks.js/classes/appconfig.html) classes are themselves imported from the `@stacks/auth` library.
```
The `appDetails` and `userSession` objects are joined by the callback function
In the separate `src/components/App.jsx` component, we see how
`componentDidMount` loads the user's data into the app's state, whether upon redirect post-authentication with `userSession.handlePendingSignIn()` or upon detection of an existing session with `userSession.isUserSignedIn()`:
in configuring Stacks authentication with the `authOptions` object:
The data for all todos are saved as JSON to the Gaia hub linked to your Secret Key using the
The data for all todos are saved as JSON to the Gaia hub linked to your Secret Key using the [`putFile`](http://blockstack.github.io/stacks.js/classes/storage.html#putfile) method of the `storage` object in the `src/data-store.js` module:
[`putFile`](http://blockstack.github.io/stacks.js/classes/storage.html#putfile) method of the `userSession` object in the
Note how the `storage` object imported here is originally instantiated in the `stacks` module using `new Storage({ userSession });`, where `userSession` is the same object as used with authentication. It's provided here to ensure that all storage calls are made with the user's Gaia hub.
By default, the `putFile` and `getFile` methods automatically encrypt data when saved and decrypt it when retrieved,
By default, the `putFile` and `getFile` methods automatically encrypt data when saved and decrypt it when retrieved,
using the user's Secret Key. This ensures that only the user has the ability to view this data.
using the user's _Secret Key_. This ensures that only the user has the ability to view this data.
When deleting a todo, the same `putFile` method is used to save a new JSON array of todos that excludes the deleted todo.
When deleting a todo, the same `putFile` method is used to save a new JSON array of todos that excludes the deleted todo.
@ -254,7 +232,7 @@ When deleting a todo, the same `putFile` method is used to save a new JSON array
Select "Make public" to make your todos accessible to the public for sharing via URL.
Select "Make public" to make your todos accessible to the public for sharing via URL.
This will call `saveTasks` with the `isPublic` parameter set to `true`, which is used to disable encryption when using `putFile`.
This will call `saveTasks` with the `isPublic` parameter set to `true`, which is used to disable encryption when using `putFile`.
@ -264,38 +242,36 @@ The app will now show all of your todos to anyone who visits the URL displayed w
Select "Sign out" to deauthenticate the app with your Stacks account.
Select "Sign out" to deauthenticate the app with your Stacks account.
This triggers an event, which
This calls the [`signUserOut`](https://blockstack.github.io/stacks.js/classes/usersession.html#signuserout) method
[under the hood](https://github.com/blockstack/stacks-todos/blob/master/src/components/Header.jsx#L47)
of the `userSession` object within `src/components/Header.jsx`.
calls the [`signUserOut` method](https://blockstack.github.io/stacks.js/classes/usersession.html#signuserout)
of the `UserSession` object.
Now, visit the URL that was provided to you when you made your tasks public. This url is of the format `/todos/:username`, so if your username is `jane_doe.id.blockstack`, the URL would be [`localhost:3000/todos/jane_doe.id.blockstack`](http://localhost:3000/todos/jane_doe.id.blockstack).
Now visit the URL that was provided to you when you made your tasks public. This URL has the format `/todos/:username`, so if your username were `janedoe.id.blockstack`, the URL would be `localhost:3000/todos/jane_doe.id.blockstack`.
When you visit this page, the `TodoList.jsx` component detects that there is a username in the URL.
When you visit this page, the `TodoList.jsx` component detects that there is a username in the URL.
When there is a username, it calls `fetchTasks`, this time providing the `username` argument. This `username`
When there is a username, it calls `fetchTasks`, this time providing the `username` argument. This `username`
option is then passed to `getFile`, which will lookup where that user's tasks are stored.
option is then passed to `getFile`, which will lookup where that user's tasks are stored.
## Sign back in
## Sign back in
At this point, you will be logged out from the app but not you'll still have an active session with the Stacks
At this point, you will be logged out from the app but not you'll still have an active session with the Stacks
app itself on [app.blockstack.org](https://app.blockstack.org). Navigate to app.blockstack.org and select "Sign out" there if you want to deauthenticate the Stacks app as well.
app itself on [app.blockstack.org](https://app.blockstack.org). Navigate to app.blockstack.org and select "Sign out" there if you want to deauthenticate the Stacks app as well.
Once signed out, select "Sign in" to sign back in with your _Secret Key_.
Once signed out, select "Sign In" to sign back in with your _Secret Key_.
If you've previously deauthenticated the Stacks app, you'll see a prompt to enter your _Secret Key_:
If you've previously deauthenticated the Stacks app, you'll see a prompt to enter your _Secret Key_:
![An example of a sign in screen](/images/todos-sign-in.svg)
!["Sign in" screen](/images/todos/sign-in.png)
The above screen will be ommitted if you have an active session with the Stacks app already.
The above screen will be ommitted if you have an active session with the Stacks app already.
Then you'll be presented with the option to select an existing username associated with your _Secret Key_ or
Then you'll be presented with the option to select an existing username associated with your _Secret Key_ or
create a new one if you wish to authenticate the app with a different identity and data set:
create a new one if you wish to authenticate the app with a different identity and data set:
![An example of the choose an account screen](/images/todos-choose-account.svg)