# Consent

Flexpa Consent enables secure patient authorization for [Records](https://www.flexpa.com/docs/records) retrieval using [SMART on FHIR](http://hl7.org/fhir/smart-app-launch/) with OAuth 2.0 PKCE.

Consent can be used in web and mobile apps.

### How it works

1. Your app redirects users to Flexpa's authorization endpoint  
2. Users connect their healthcare records from our [3-in-1 network](https://www.flexpa.com/docs/network)  
3. Flexpa redirects back to your app with an authorization code  
4. You exchange the authorization code for an access token and start making [Records](https://www.flexpa.com/docs/records) requests

### What you need

- A pair of [API Keys](https://www.flexpa.com/docs/guides/quickstart#api-keys) from the [Flexpa Portal](https://portal.flexpa.com/)  
- A **redirect URI** registered in the [Flexpa Portal](https://portal.flexpa.com/). This is where users will be redirected after authorization.  
- Optional: The [@flexpa/node-sdk](https://www.flexpa.com/docs/records/node-sdk) package installed in your project

### Getting Started

The SMART on FHIR authorization flow involves these main steps:

1. [Generate PKCE](https://www.flexpa.com/docs/consent#generate-pkce) - Create a code verifier and challenge  
2. [Build authorization URL](https://www.flexpa.com/docs/consent#build-authorization-url) - Construct the URL with your parameters  
3. [Redirect](https://www.flexpa.com/docs/consent#redirect) - Send the user to Flexpa for authorization  
4. [Handle callback](https://www.flexpa.com/docs/consent#handle-callback) - Process the authorization code on redirect  
5. [Exchange](https://www.flexpa.com/docs/consent#exchange) - Exchange the code for access tokens  
6. [Fetch records](https://www.flexpa.com/docs/consent#fetch-records) - Use the access token to retrieve patient data

```bash
npm install @flexpa/node-sdk
```

### Generate PKCE

PKCE (Proof Key for Code Exchange, pronounced "pixie") is an extension to OAuth 2.0 ( [RFC 7636](https://www.rfc-editor.org/rfc/rfc7636)) that prevents authorization code interception attacks. It ensures the application that starts the authorization flow is the same one that finishes it.

You'll generate two values:

- **Code Verifier**: A cryptographically random string (43-128 characters) that you keep secret and store until the callback  
- **Code Challenge**: A SHA-256 hash of the verifier, base64url-encoded, sent with the authorization request

For web apps, store the verifier in `sessionStorage`—it survives redirects within the same tab and is automatically cleared when the tab closes.

#### Generate PKCE Commands

```bash
# Generate code verifier (43-128 character base64url string)
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=' | tr '/+' '_-')

# Generate code challenge: BASE64URL(SHA256(verifier))
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | \
  openssl sha256 -binary | base64 | tr -d '=' | tr '/+' '_-')

echo "Code Verifier: $CODE_VERIFIER"
echo "Code Challenge: $CODE_CHALLENGE"
```

### Build authorization URL

Construct the authorization URL with your OAuth parameters.

#### Parameters

- `client_id` (string, Required): Your publishable key from the [Flexpa Portal](https://portal.flexpa.com/).
- `redirect_uri` (string, Required): The URL where users will be redirected after authorization. Must be registered in the [Flexpa Portal](https://portal.flexpa.com/).
- `response_type` (string, Required): Must be `code` for the authorization code flow.
- `code_challenge` (string, Required): The PKCE code challenge generated from the code verifier (43 base64url characters).
- `code_challenge_method` (string, Required): Must be `S256` (SHA-256).
- `scope` (string, Required): Space-separated OAuth scopes. Must include `launch/patient`. Add `offline_access` for refresh tokens.

#### Build URL Example

```bash
https://api.flexpa.com/oauth/authorize
  ?client_id=pk_test_...
  &redirect_uri=https://example.com/callback
  &response_type=code
  &code_challenge=$CODE_CHALLENGE
  &code_challenge_method=S256
  &scope=launch/patient
  &flexpa_external_id=usr_1234
```

### Scopes

OAuth scopes control what data your application can access and for how long.

#### Supported scopes

- `launch/patient` (string, Required): Required scope indicating patient context will be provided.
- `offline_access` (string): Optional scope that enables refresh tokens.

### Redirect

Once you have the authorization URL, redirect the user to begin the consent flow. Users will:

1. Connect their health records  
2. Consent to share their data with your application  
3. Be redirected back to your `redirect_uri` with an authorization code

### Handle callback

After authorization, Flexpa redirects back to your `redirect_uri` with query parameters.

#### Success parameters

- `code` (string): The authorization code to exchange for an access token.
- `state` (string): The state parameter provided (if any).

#### Error parameters

- `error` (string): One of the error codes, `access_denied` or `server_error`.
- `error_description` (string): Human-readable error description providing additional detail.
- `error_uri` (string): Link to error code documentation.

### Exchange

Exchange the authorization code for an access token using the token endpoint. This request:

- Validates the authorization code with Flexpa
- Verifies the PKCE code verifier
- Returns access and refresh tokens

### Fetch records

Use your access token to fetch patient data from the [FHIR API](https://www.flexpa.com/docs/records#fhir-api).

```bash
curl 'https://api.flexpa.com/fhir/Patient/$everything' \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

## OAuth API

### Authorization

The authorization endpoint initiates the OAuth 2.0 PKCE flow. See [Build authorization URL](https://www.flexpa.com/docs/consent#build-authorization-url) for implementation details.

### Token

The token endpoint supports three grant types:

1. `authorization_code`: For exchanging an authorization code for access tokens (OAuth PKCE flow)
2. `refresh_token`: For refreshing Patient Access Tokens with `MULTIPLE` usage
3. `client_credentials`: For obtaining [Application Access Tokens](https://www.flexpa.com/docs/records#application-access-token)

### Revoke

Revokes a consent and expunges the patient's data from Flexpa's cache. This invalidates both the `access_token` and `refresh_token`.

```bash
curl -X POST https://api.flexpa.com/oauth/revoke \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{"secret_key": "sk_test..."}'
```

### REST API

Retrieve information about a consent record and its associated patient authorizations, including sync status and SMART scope information.

```bash
ACCESS_TOKEN=your-access-token

curl https://api.flexpa.com/rest/consent \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

### Migration from v1

If you are migrating from the legacy FlexpaLink SDK, see the [v1 documentation](https://www.flexpa.com/docs/consent/v1) for the previous implementation details and migration guide.

### Troubleshooting

**Invalid code_challenge**: The code_challenge must be a base64url-encoded SHA256 hash (43 characters, no padding).

**Invalid redirect_uri**: The redirect_uri must exactly match a URI registered in the [Flexpa Portal](https://portal.flexpa.com/) including protocol, domain, and path.

**Token exchange fails**: Common causes include expired authorization code or mismatched `redirect_uri`.
