This PR introduces basic auth implementation between the app and the
server as part of the architectural example.
This PR is a big bigger than the previous ones so I hope this
explanation helps:
### Server implementation
The server introduces a new endpoint `/login` to perform login requests,
which accepts login requests defined in the `LoginRequest` data class,
with an email and password.
The login process "simulates" checking on the email and password and
responds with a "token" and user ID, defined by the `LoginResponse` data
class. This is a simple hard-coded check and in any way a guide on how
to implement authentication, just a way to demonstrate an architectural
example.
The server also implements a middleware in
`server/lib/middleware/auth.dart`. This checks that the requests between
the app and the server carry a valid authorization token in the headers,
responding with an unauthorized error otherwise.
### App implementation
The app introduces the following new parts:
- `AuthTokenRepository`: In charge of storing the auth token.
- `AuthLoginComponent`: In charge of performing login.
- `AuthLogoutComponent`: In charge of performing logout.
- `LoginScreen` with `LoginViewModel`: Displays the login screen.
- `LogoutButton` with `LogoutViewModel`: Displays a logout button.
The `AuthTokenRepository` acts as the source of truth to decide if the
user is logged in or not. If the repository contains a token, it means
the user is logged in, otherwise if the token is null, it means that the
user is logged out. This repository is also a `ChangeNotifier`, which
allows listening to change in it.
The `GoRouter` has been modified so it listens to changes in the
`AuthTokenRepository` using the `refreshListenable` property. It also
implements a `redirect`, so if the token is set to `null` in the
repository, the router will redirect users automatically to the login
screen. This follows the example found in
https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/redirection.dart
On app start, `GoRouter` checks the `AuthTokenRepository`, if a token
exists the user stays in `/`, if not, the user is redirected to
`/login`.
The `ApiClient` has also been modified, so it reads the stored token
from the repository when performing network calls, and adds it to the
auth headers.
The two new components implement basic login and logout functionality.
The `AuthLoginComponent` will send the request using the `ApiClient`,
and then store the token from the response. The `AuthLogoutComponent`
clears the stored token from the repository, and as well clears any
existing itinerary configuration, effectively cleaning the app state.
Performing logout redirects the user to the login screen, as explained.
The `LoginScreen` uses the `AuthLoginComponent` internally, it displays
two text fields and a login button, plus the application logo on top. A
successful login redirects the user to `/`.
The `LogoutButton` replaces the home button at the `/`, and on tap it
will perform logout using the `AuthLogoutComponent`.
**Development target app**
The development target app works slightly different compared to the
staging build. In this case, the `AuthTokenRepository` always contains a
fake token, so the app believes it is always logged in.
Auth is only used in the staging build when the server is involved.
## Screenshots
<details>
<summary>Screenshots</summary>
The logout button in the top right corner:
![Screenshot from 2024-08-14
15-28-54](https://github.com/user-attachments/assets/1c5a37dc-9fa1-4950-917e-0c7272896780)
The login screen:
![Screenshot from 2024-08-14
15-28-12](https://github.com/user-attachments/assets/3c26ccc2-8e3b-42d2-a230-d31048af6960)
</details>
## Pre-launch Checklist
- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-devrel
channel on [Discord].
<!-- Links -->
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md
[CLA]: https://cla.developers.google.com/
[Discord]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md
[Contributors Guide]:
https://github.com/flutter/samples/blob/main/CONTRIBUTING.md