From f909801409c490138db86154cde1ef13687f2057 Mon Sep 17 00:00:00 2001 From: Newman Chow Date: Mon, 26 Feb 2024 14:21:16 +0800 Subject: [PATCH] Specify settings action #3813 --- docs/specs/oidc.md | 63 +++++++++++++++++++++++++++++++++++++++++++++- docs/specs/sdk.md | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/docs/specs/oidc.md b/docs/specs/oidc.md index abae8e04aa8..a7883aab3df 100644 --- a/docs/specs/oidc.md +++ b/docs/specs/oidc.md @@ -17,6 +17,7 @@ + [acr_values](#acr_values) + [code_challenge_method](#code_challenge_method) + [nonce](#nonce) + + [x_settings_action](#x_settings_action) * [Token Request](#token-request) + [grant_type](#grant_type) + [id_token_hint](#id_token_hint-1) @@ -38,7 +39,7 @@ + [subject_types_supported](#subject_types_supported) + [id_token_signing_alg_values_supported](#id_token_signing_alg_values_supported) + [claims_supported](#claims_supported) - + [code_challenge_methods_supported](#code_challenge_methods_supported) + + [ds_supported](#code_challenge_methods_supported) * [ID Token](#id-token) + [`amr`](#amr) + [`auth_time`](#auth_time) @@ -62,6 +63,7 @@ + [Consent Screen](#consent-screen) + [Authorized Apps page](#authorized-apps-page) + [App Session Token](#app-session-token) + + [Settings Action](#settings-action) * [How to construct authentication request to achieve different scenarios](#how-to-construct-authentication-request-to-achieve-different-scenarios) + [The user has NOT signed in yet in my mobile app. I want to authenticate any user.](#the-user-has-not-signed-in-yet-in-my-mobile-app-i-want-to-authenticate-any-user) + [The user has NOT signed in yet in my mobile app. I want to authenticate any user. Possibly reuse any previous signed in sessions.](#the-user-has-not-signed-in-yet-in-my-mobile-app-i-want-to-authenticate-any-user-possibly-reuse-any-previous-signed-in-sessions) @@ -219,6 +221,12 @@ Only `S256` is supported. `plain` is not supported. To mitigate replay attacks, provide a `nonce` in the authentication request. Authgear will include the `nonce` Claim in the ID Token, and the client must verify that the `nonce` claim value is equal to the value of the `nonce` parameter sent in the authentication request. The `nonce` is recommended but it is optional. The `nonce` value is a case sensitive string. Reference: [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.1). +### x_settings_action + +When it is specified, the user will be redirected to the corresponding auth ui pages of the settings action. After completing the action, the user will be redirected back to the app through redirect URI. + +Supported values: `change_password`. + ## Token Request ### grant_type @@ -631,6 +639,59 @@ When the app session token is consumed: instead of IdP sessions. Therefore, the lifetime of session cookie is bound to refresh token instead of IdP session. +### Settings Action + +For first-party clients, user may want to perform specific account settings action (e.g. verify email) in the app. + +Settings action will be started via authorization endpoint. Authentication is needed for performing settings action. Both IdP session or App session are accepted. If the login hint (app session token) is provided in the authorization endpoint, the app session cookie will be set when redirecting to the settings action ui. If the login hint is not provided, user will be redirected to the settings action ui directly and the IdP session will be used. + +The redirect URI of the settings action should be the different per settings action. The redirect URI's origin should be registered in the client settings `x_settings_redirect_uri_origins`. + +The following flow charts show how the settings actions work. + +```mermaid +flowchart LR + subgraph /oauth2/authorize + authz[authz endpoint] + end + subgraph settings[e.g. /settings/change_email] + settings_action[settings action endpoints] + end + subgraph app[e.g. com.app://host/after-change-password] + app_callback[app callback] + end + + SDK --app session token--> /oauth2/authorize + /oauth2/authorize --app session token--> settings + settings --authorization code--> app +``` + +```mermaid +flowchart LR + subgraph /oauth2/token + token[token endpoint] + end + app --authorization code--> /oauth2/token +``` + +#### Authentication request of settings actions + +``` +GET /oauth2/authorize?client_id=client_id&prompt=none&response_type=code + &login_hint=https%3A%2F%2Fauthgear.com%2Flogin_hint%3Ftype%3Dapp_session_token%26app_session_token%3D + &id_token_hint= + &code_challenge= + &code_challenge_method=S256 + &x_settings_action= + &redirect_uri= HTTP/1.1 +Host: accounts.example.com + +--- +HTTP/1.1 302 Found +Set-Cookie: +Location: +``` + ## How to construct authentication request to achieve different scenarios ### The user has NOT signed in yet in my mobile app. I want to authenticate any user. diff --git a/docs/specs/sdk.md b/docs/specs/sdk.md index e654951d231..467db55729b 100644 --- a/docs/specs/sdk.md +++ b/docs/specs/sdk.md @@ -271,3 +271,50 @@ await authgear.authorize({ ... }); const enabled = await authgear.isBiometricEnabled(); assert(enabled === false); ``` + +## Perform settings action + +Allow the user performs specific settings action from the app. e.g. change password. The action is only resolved when the user has completed the action. + +```typescript +// In mobile sdk +interface ChangePasswordOptions { + redirectURI: string; + uiLocales?: string[]; + colorScheme?: ColorScheme; +} + +function changePassword(options: ChangePasswordOptions): Promise; + +// In web sdk +interface ChangePasswordOptions { + redirectURI: string; + openInSameTab?: boolean; + uiLocales?: string[]; + colorScheme?: ColorScheme; +} + +function startChangingPassword(options: ChangePasswordOptions): Promise; + +function finishChangingPassword(): Promise; +``` + +Remarks: In web SDK, redirect URI of different settings actions need to be different. If `openInSameTab` is false (default), the settings tab will be closed after the action is completed. Otherwise user will be redirected to the redirect URI. + +### Intended usage + +```typescript +const userInfo = authgear.fetchUserInfo(); + +try { + await authgear.startChangingPassword({ + redirectURI: "com.app://host/after-changing-password", + }) +} catch (e) { + // The user declined. + return; +} + +// In the callback page +await authgear.finishChangingPassword(); +```