docs/flagship.md
Rama master · réplica de lectura del repositorio original.
# Flagship App
## Introduction
The flagship application is a mobile application that can be used to run all
the Cozy webapps inside it. It also has a bunch of exclusive features like the
client-side connectors. But, to be able to work, it needs a very powerful
access to the Cozy instance. Technically, it means that the flagship app is an
OAuth client with a scope that covers everything. And we want to ensure that
only the flagship can have this power. So, we require the application to be
certified. It can be certified via the Google and Apple stores, and when it's
not available, the user has the possibility to manually certify the flagship
app (lineage OS users for example).
Let's see the workflow when a user opens the flagship app for the first time.
The app will load, and it will open a page of the cloudery for the onboarding.
The user can type their email address, the cloudery sends an email, the user
opens a link in this email, and then, we have two cases: the user already have
a Cozy instance, or they want to create a new one. In both cases, the flagship
will register its-self as an OAuth client on the Cozy and will type their
passphrase before going to the home of the Cozy inside the flagship app. It is
just that for a new Cozy, there are a few additional steps like accepting the
terms of services.
**Note:** the flagship app can be used with self-hosted stack. The user will
have to type their Cozy address instead of using their email address, but
everything else should work, including the certification via the Google and
Apple stores (there are some config parameters, but they have a default value
that make this possible).
## Create the OAuth client & certification
When the flagship app knows the Cozy instance of the user, it will register
itself as an OAuth client, and will try to attest that it is really the
flagship app via the Google and Apple APIs. It is done by calling these 3
routes from the stack:
1. `POST /auth/register`
2. `POST /auth/clients/:client-id/challenge`
3. `POST /auth/clients/:client-id/attestation`
Between 2 and 3, the app will ask the mobile OS to certify that this is really
the flagship app. It is done via the [Play Integrity
API](https://developer.android.com/google/play/integrity) (or [SafetyNet
attestation API](https://developer.android.com/training/safetynet/attestation))
on Android, and the [AppAttest
API](https://developer.apple.com/documentation/devicecheck) on iOS.
## New Cozy instance
On a new Cozy instance, the user will choose a passphrase that will be
registered on the Cozy by sending its PBKDF2 hash to
`POST /settings/passphrase/flagship`.
## Existing Cozy instance
On an existing Cozy instance, the app will fetch some parameters with
`GET /public/prelogin`, then the user can type their passphrase, and the PBKDF2
hash will be sent to `POST /auth/login/flagship` to give the app access to the
whole Cozy.
## Magic link variant
When magic link is enabled on a Cozy, the flagship app can use
`POST /auth/magic_link/flagship` with a code sent by email to the user to get
access to the Cozy.
## OIDC variant
When a user uses an OIDC provider, or FranceConnect, the flagship app will get
a delegated code from the cloudery and will use it via the `POST /oidc/access_token`
endpoint to get access to the Cozy.
## SSO logout integration
When the flagship app authenticates via OpenID Connect, the session ID (`sid`)
is obtained from the delegated code. The cloudery sends the `id_token` when
requesting the delegated code from the stack, and the stack extracts and stores
the `sid` claim with the code. When the flagship app exchanges the delegated
code at `POST /oidc/access_token`, the session ID is automatically retrieved
and stored in the OAuth client. When the user signs out of the flagship app and
the client is removed, the stack calls the identity provider's
`end_session_endpoint` (when one is declared in the provider configuration) so
the upstream SSO session is closed as well. This keeps the Cozy session and the
external provider in sync during logout.
## Manual certification
When the certification from the Google and Apple stores has failed, the app
will have to do a few more steps to have access to the Cozy:
1. Opening an in-app browser on the authorize page of the stack
`GET /auth/authorize?scope=*`
(note: PKCE is mandatory for the flagship app)
2. The stack sends a mail with a 6 digits code in that case. The email explains
that this code can be used to certify the flagship app.
3. The user can type this code on the authorize page and submit it. It makes
a `POST /auth/clients/:client-id/flagship`.
4. If successful, it redirects back to the same page
(`GET /auth/authorize?scope=*`), but this time, the user has button to
accept using the flagship app.
5. The user accepts, it sends a request to `POST /auth/authorize`, and the
flagship app can finish the OAuth danse and have a full access on the Cozy.
## Special routes
Some routes of the stack are dedicated to the flagship app, like:
- creating a session code with `POST /auth/session_code`
- getting a konnector token with `POST /auth/tokens/konnectors/:slug`
- getting the parameters to open a webapp with `GET /apps/:slug/open`
And some routes accept a `session_code` to open a session in a webview or
inAppBrowser, like:
- serving the `index.html` of a webapp
- starting the OAuth danse of a konnector (`/accounts/:slug/start`)
- starting the reconnect BI flow (`/accounts/:slug/reconnect`).
## Notifications
When a notification is sent via the push channel, the stack will first try to
send it to the dedicated mobile app. If there are no dedicated apps with a push
token, the stack will then try to send the notification to the flagship apps.
If it fails again, the stack then fallbacks on email.
If the notification is sent to the flagship app, the title is modified to
preprend the application name. By default, the notification `slug` is used but,
if present, the name is taken from the `appName` field of the additional
parameters (`data`). It allows the user to have more context when reading the
notification on their mobile. The `data.appName` field can also be used to
completely remove the application name from the notification title if set to an
empty string.