@lunch-money/developer-docs 2.11.2-preview.1 → 2.11.2-preview.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/STYLE_GUIDE.md +4 -0
- package/docs/branding-your-app.md +1 -1
- package/docs/getting-started.md +5 -5
- package/docs/introduction.md +1 -1
- package/docs/oauth/authorization-code.md +22 -6
- package/docs/oauth/concepts.md +60 -3
- package/docs/oauth/development.md +21 -7
- package/docs/oauth/index.md +6 -4
- package/docs/oauth/native-apps.md +26 -2
- package/docs/oauth/register-client.md +11 -1
- package/docs/oauth/review-and-approval.md +11 -3
- package/docs/oauth/sample-applications.md +263 -0
- package/docs/oauth/scopes.md +5 -5
- package/docs/oauth/security.md +32 -2
- package/docs/oauth/tokens.md +11 -3
- package/docs/oauth/troubleshooting.md +16 -2
- package/manifest.json +9 -0
- package/package.json +1 -1
- package/v1/_user.md +2 -2
- package/v2/docs/intro-to-v2.md +1 -1
- package/v2/docs/version-history.md +4 -2
- package/v2/images/oauth-authorization-flow.svg +9 -6
- package/v2/spec/AGENTS.md +6 -0
- package/v2/spec/lunch-money-api-v2.yaml +769 -1771
package/docs/STYLE_GUIDE.md
CHANGED
|
@@ -20,6 +20,10 @@ history entries.
|
|
|
20
20
|
legal company name is required.
|
|
21
21
|
- Use “Developer Portal,” “Developers page,” and “API reference” consistently.
|
|
22
22
|
Preserve different capitalization only for an exact UI label.
|
|
23
|
+
- Use “budget account” for the Lunch Money data container that holds a budget,
|
|
24
|
+
transactions, categories, and financial accounts. Use “account” only when the
|
|
25
|
+
context is unambiguous, and preserve exact UI labels such as “Create a New
|
|
26
|
+
Budget Account.”
|
|
23
27
|
- Write “v1” and “v2” in prose. Use “V2 API” only where it is an established
|
|
24
28
|
proper label, such as the rendered reference title.
|
|
25
29
|
- Distinguish authentication from authorization, personal access tokens from
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Building a tool, plugin, or integration on top of Lunch Money? Use the official **Powered by Lunch Money** badge to credit the connection clearly — without implying that your app *is* Lunch Money.
|
|
4
4
|
|
|
5
5
|
<a href="https://lunchmoney.app/assets/images/media-kit/powered-by-lunch-money-badge.png" download="powered-by-lunch-money-badge.png" target="_blank" rel="noopener noreferrer" title="Download Powered by Lunch Money badge">
|
|
6
|
-
<img src="/v2/images/powered-by-lunch-money-badge.png" alt="Powered by Lunch Money badge" />
|
|
6
|
+
<img src="/v2/images/powered-by-lunch-money-badge.png" alt="Powered by Lunch Money badge" width="320" />
|
|
7
7
|
</a>
|
|
8
8
|
|
|
9
9
|
> [!TIP]
|
package/docs/getting-started.md
CHANGED
|
@@ -8,9 +8,9 @@ Most users interact with their Lunch Money data using the official web or mobile
|
|
|
8
8
|
> Changes made via the API are permanent and cannot be undone. Always use a test budget when getting started.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
## Create a test
|
|
11
|
+
## Create a test budget account
|
|
12
12
|
|
|
13
|
-
Since changes to your data made by the API are permanent, the best way to begin interacting with the API is to <a href="https://support.lunchmoney.app/miscellaneous/unlimited-budgeting-accounts" target="_blank" rel="noopener noreferrer">create a new test
|
|
13
|
+
Since changes to your data made by the API are permanent, the best way to begin interacting with the API is to <a href="https://support.lunchmoney.app/miscellaneous/unlimited-budgeting-accounts" target="_blank" rel="noopener noreferrer">create a new test budget account</a> in your existing Lunch Money account. As you start using the API, you can interact with this test account and ensure that your real data is not modified.
|
|
14
14
|
|
|
15
15
|
:::tabs
|
|
16
16
|
|
|
@@ -29,15 +29,15 @@ Choose the option to "Set up Demo". This will add categories, accounts, tags and
|
|
|
29
29
|
|
|
30
30
|
## Getting a personal access token
|
|
31
31
|
|
|
32
|
-
Lunch Money API requests are authenticated using the Bearer Token authentication method. In plain English, this means that you will pass a personal access token associated with your
|
|
32
|
+
Lunch Money API requests are authenticated using the Bearer Token authentication method. In plain English, this means that you will pass a personal access token associated with your budget account to Lunch Money. This is so we know which account to operate on and that the request came from someone who can access that account.
|
|
33
33
|
|
|
34
|
-
This guide uses a personal access token so you can explore the API with your own
|
|
34
|
+
This guide uses a personal access token so you can explore the API with your own budget account. If you are building an application that other people will connect to Lunch Money, start with the [OAuth overview](/oauth) instead.
|
|
35
35
|
|
|
36
36
|
:::tabs
|
|
37
37
|
|
|
38
38
|
@tab 1. Go to the Developers Page
|
|
39
39
|
|
|
40
|
-
Navigate to <a href="https://my.lunchmoney.app/developers" target="_blank" rel="noopener noreferrer">the developers page in the Lunch Money web app</a>. Look at the green circle in the upper right hand corner and make sure that it is showing the test account that you just created. If you aren't sure which account is active, you can click on the green circle to bring up the "Switch Accounts" dialog. This will show you the full names of all the accounts associated with your account. Select the test
|
|
40
|
+
Navigate to <a href="https://my.lunchmoney.app/developers" target="_blank" rel="noopener noreferrer">the developers page in the Lunch Money web app</a>. Look at the green circle in the upper right hand corner and make sure that it is showing the test account that you just created. If you aren't sure which account is active, you can click on the green circle to bring up the "Switch Accounts" dialog. This will show you the full names of all the accounts associated with your account. Select the test budget account you created.
|
|
41
41
|

|
|
42
42
|
|
|
43
43
|
@tab 2. Request Access Token
|
package/docs/introduction.md
CHANGED
|
@@ -10,7 +10,7 @@ The v2 API is available at:
|
|
|
10
10
|
https://api.lunchmoney.dev/v2
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
To explore the API or work with your own
|
|
13
|
+
To explore the API or work with your own budget account, create a personal access token on the <a href="https://my.lunchmoney.app/developers" target="_blank" rel="noopener noreferrer">Developers page</a>. If you are building an application for other Lunch Money users, [use OAuth](/oauth) instead. Both kinds of access token are sent as a Bearer token with each request:
|
|
14
14
|
|
|
15
15
|
```http
|
|
16
16
|
Authorization: Bearer YOUR_ACCESS_TOKEN
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Implement the authorization-code flow
|
|
2
2
|
|
|
3
|
-
After you [register an OAuth client](/oauth/register-client), your application uses its settings—including its client ID, client secret, and registered redirect URI—to implement the authorization flow. As shown in the [OAuth overview](/oauth), your application sends the user to Lunch Money, Lunch Money returns an authorization code to your callback, and your application exchanges that code for tokens.
|
|
3
|
+
After you [register an OAuth client](/oauth/register-client), your application uses its settings—including its client ID, client secret, if configured, and a registered redirect URI—to implement the authorization flow. As shown in the [OAuth overview](/oauth), your application sends the user to Lunch Money, Lunch Money returns an authorization code to your callback, and your application exchanges that code for tokens. Step 4 explains how to identify the Lunch Money user and budget account associated with the resulting connection.
|
|
4
4
|
|
|
5
|
-
This guide walks through that process for a **Confidential web client**. Your server handles the callback and token exchange and keeps the client secret and refresh tokens secure. If you are building a standalone mobile or desktop application, read the [native application guidance](/oauth/native-apps) instead.
|
|
5
|
+
This guide walks through that process for a **Confidential web client**. Your server handles the callback and token exchange and keeps the client secret and refresh tokens secure. If you are building a standalone mobile or desktop application, read the [native application guidance](/oauth/native-apps) instead. Expo developers can also follow the [native Expo sample](/oauth/sample-applications#native-expo-sample).
|
|
6
6
|
|
|
7
7
|
## Choose an OAuth library
|
|
8
8
|
|
|
@@ -15,6 +15,8 @@ OAuth libraries handle much of the protocol work for you, including generating P
|
|
|
15
15
|
|
|
16
16
|
For Node.js and TypeScript, [`openid-client`](https://github.com/panva/openid-client) is one maintained option. Despite its name, using it does not mean that Lunch Money supports OpenID Connect identity scopes, ID tokens, or UserInfo.
|
|
17
17
|
|
|
18
|
+
The [confidential Node.js sample application](/oauth/sample-applications#understand-the-confidential-teaching-code) shows this library in a complete Lunch Money flow. Begin with its [`src/oauth` guide](https://github.com/lunch-money/lm-oauth-confidential-node-example/blob/main/src/oauth/README.md), then follow the listed reading order from protocol types and discovery through authorization, callback validation, credential storage, API access, optional refresh, and revocation.
|
|
19
|
+
|
|
18
20
|
## Configure Lunch Money with discovery
|
|
19
21
|
|
|
20
22
|
Your OAuth library needs to know where to send the user for authorization, where to exchange codes for tokens, and which protocol features Lunch Money supports. Instead of configuring each value separately, give the library the Lunch Money issuer:
|
|
@@ -40,6 +42,8 @@ On your server, generate:
|
|
|
40
42
|
|
|
41
43
|
Redirect the browser to the discovered authorization endpoint with `response_type=code`, your `client_id`, exact `redirect_uri`, `state`, `code_challenge`, and `code_challenge_method=S256`.
|
|
42
44
|
|
|
45
|
+
Lunch Money handles sign-in, budget-account selection, and consent. It may reuse an existing browser login session, and the person may be able to continue with a different Lunch Money user from the authorization screen. A user may have multiple budget accounts, but this authorization is for the one they select. Keep the authorization attempt bound to the authenticated application user who started it; do not assume which Lunch Money user will complete it.
|
|
46
|
+
|
|
43
47
|
> [!NOTE] Scopes come from the client registration
|
|
44
48
|
> You do not need to send `scope`. If your OAuth library includes it, Lunch Money ignores the requested value and uses the client's complete registered scope set. An authorization request cannot narrow or expand that set; changing scopes requires a replacement client.
|
|
45
49
|
|
|
@@ -59,9 +63,9 @@ Treat `access_denied` as a normal user decision. Do not log the callback query s
|
|
|
59
63
|
|
|
60
64
|
Send a form-encoded request to the discovered token endpoint with `grant_type=authorization_code`, the code, exact `redirect_uri`, and original `code_verifier`. A confidential client authenticates with HTTP Basic using its client ID and secret. Do this server-side.
|
|
61
65
|
|
|
62
|
-
|
|
66
|
+
Keep the returned credentials in temporary server-side state while you identify the authorization. Do not make an unidentified credential set available to the application or commit it to the normal connection store yet. If a `refresh_token` is returned, treat it as a high-value credential even during this temporary step.
|
|
63
67
|
|
|
64
|
-
## 4.
|
|
68
|
+
## 4. Identify and store the connection
|
|
65
69
|
|
|
66
70
|
Send the access token in the header:
|
|
67
71
|
|
|
@@ -71,10 +75,22 @@ Host: api.lunchmoney.dev
|
|
|
71
75
|
Authorization: Bearer YOUR_ACCESS_TOKEN
|
|
72
76
|
```
|
|
73
77
|
|
|
74
|
-
The operation must be allowed by the token's scope and by the user's access to the selected
|
|
78
|
+
The operation must be allowed by the token's scope and by the user's access to the selected budget account. See the [scope catalog](/oauth/scopes).
|
|
79
|
+
|
|
80
|
+
Call `GET /v2/me` immediately after the token exchange, before normal credential persistence. It requires `me:read`. Strictly validate the response: `id` identifies the Lunch Money user, `account_id` identifies the selected budget account, and `budget_name` is its display name. When reconnecting, use this response to establish the account identity rather than assuming the user selected the same budget. See [users, budget accounts, and access tokens](/oauth/concepts#users-budget-accounts-and-access-tokens).
|
|
81
|
+
|
|
82
|
+
Store the credential set under the authenticated application user's ID and the returned Lunch Money user `id` and `account_id`. Those three fields establish the owner and provider identity for the connection, even if your database also assigns an internal connection ID for routing. Atomically create a complete record when that combination is new, or replace the complete credential set when the same application user reauthorizes the same Lunch Money user and budget-account pair. Persist the access token, refresh token when present, scope, expiration metadata, Lunch Money user `id`, `account_id`, and `budget_name` together, then make that Lunch Money identity and connection active. Do not use `budget_name` as a key or try to derive identity by parsing the opaque access token.
|
|
83
|
+
|
|
84
|
+
If `GET /v2/me` fails validation or the complete record cannot be persisted, discard the temporary credentials and leave existing connections unchanged. A successful token exchange alone must not create an unidentified or partially saved connection.
|
|
85
|
+
|
|
86
|
+
Your application establishes ownership through its own authenticated session. When authorization starts, store the authenticated application user's internal ID in the server-side authorization attempt associated with `state`. After validating the callback and calling `GET /v2/me`, store the credentials with that application-user ID and the returned Lunch Money `id`/`account_id` pair.
|
|
87
|
+
|
|
88
|
+
For later requests, look up the selected connection using both its internal connection ID and the authenticated application user's internal ID. Then verify that its stored Lunch Money user `id` and `account_id` belong to the active identity before loading or decrypting credentials. Values supplied by the browser select only a candidate record; they do not establish ownership or provider identity.
|
|
89
|
+
|
|
90
|
+
When reauthorization completes, replace credentials only in the record matching the authenticated application user and the returned Lunch Money `id`/`account_id` pair. A different Lunch Money user authorizing the same shared `account_id` must create or update a separate owned connection. After an identity change, hide the previous Lunch Money user's connections and clear or partition displayed profile, configuration, and cached financial data. See [Associate credentials with your application user](/oauth/security#associate-credentials-with-your-application-user) for the storage and ownership rules.
|
|
75
91
|
|
|
76
92
|
## 5. Continue or recover
|
|
77
93
|
|
|
78
|
-
Use the response's `expires_in` value to
|
|
94
|
+
Use the response's `expires_in` value to track the expected lifetime of the access token. You can refresh slightly before expiry as a proactive optimization, or wait for an API request to return `401` and refresh then. In either case, coordinate refreshes for each connection, retry the failed request at most once after a successful refresh, and reauthorize after a terminal refresh failure. Read [token lifecycle and recovery](/oauth/tokens) before implementing refresh, logout, or revocation.
|
|
79
95
|
|
|
80
96
|
Next: [Develop and test your OAuth application](/oauth/development).
|
package/docs/oauth/concepts.md
CHANGED
|
@@ -4,19 +4,76 @@ These terms describe who participates in Lunch Money OAuth and what each credent
|
|
|
4
4
|
|
|
5
5
|
## Parties in the flow
|
|
6
6
|
|
|
7
|
-
- **User (resource owner):** the Lunch Money user who authorizes a third-party application to make API requests on their behalf for one
|
|
7
|
+
- **User (resource owner):** the Lunch Money user who authorizes a third-party application to make API requests on their behalf for one budget account.
|
|
8
8
|
- **Application:** the complete product or service the developer builds. It may contain many features unrelated to Lunch Money; only its Lunch Money OAuth client is managed in the Developer Portal.
|
|
9
9
|
- **Client:** the application's OAuth registration with Lunch Money: its `client_id`, type, redirect URIs, selected scopes, and—when applicable—client secret. The developer must register this client in the Developer Portal before the application can ask Lunch Money users to authorize API access.
|
|
10
|
-
- **Authorization server:** the Lunch Money-owned service that presents the Lunch Money sign-in and consent screens, records the user's decision, and issues authorization codes and tokens. The user signs in directly with Lunch Money; the third-party application never receives or sees their Lunch Money login credentials.
|
|
10
|
+
- **Authorization server:** the Lunch Money-owned service that presents the Lunch Money sign-in and consent screens, records the user's decision, and issues authorization codes and tokens. It also handles token requests, including exchanging authorization codes and refresh tokens for new tokens. The user signs in directly with Lunch Money; the third-party application never receives or sees their Lunch Money login credentials.
|
|
11
11
|
- **Lunch Money API service:** the Lunch Money-owned V2 API, which receives the application's API requests, accepts access tokens, and checks that each request is permitted by the client's scopes.
|
|
12
12
|
|
|
13
|
+
## Users, budget accounts, and access tokens
|
|
14
|
+
|
|
15
|
+
A **Lunch Money user** is the person who signs in to Lunch Money. One user can have access to multiple **budget accounts**, such as a personal budget, a household budget, and a test budget. Each budget account contains its own financial data. Here, “budget account” means that collection of data, not an individual bank or manually managed account within it.
|
|
16
|
+
|
|
17
|
+
During OAuth authorization, the user selects one budget account and approves your client's permissions. The resulting **OAuth access token is specific to that Lunch Money user and budget account pair**, for your client. It does not grant access to every budget account the user can access.
|
|
18
|
+
|
|
19
|
+
For example, Alex can access both “Household” and “API testing.” If Alex selects “API testing” during authorization, your application's access token operates on that budget account. It cannot use the same token to read or update “Household.” Scopes determine which operations the application may perform within the selected account; they do not add access to other budget accounts.
|
|
20
|
+
|
|
21
|
+
When applications store OAuth credentials, they should associate the authorization with the application user who started the flow and identify the connection by the Lunch Money user and budget account pair. Two Lunch Money users can both authorize access to the same shared budget account, so `account_id` alone is not a complete connection identity.
|
|
22
|
+
|
|
23
|
+
### Identify the authorized user and account
|
|
24
|
+
|
|
25
|
+
If your client has the `me:read` scope, call `GET /v2/me` with the access token. The response identifies both sides of the connection:
|
|
26
|
+
|
|
27
|
+
| Field | Meaning |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| `id` | The Lunch Money user's ID |
|
|
30
|
+
| `account_id` | The selected budget account's ID |
|
|
31
|
+
| `budget_name` | The selected budget account's display name |
|
|
32
|
+
|
|
33
|
+
Use `account_id` as the stable identifier for the budget account and `id` as the identifier for the Lunch Money user who completed authorization. Together they identify the Lunch Money side of the connection. For an application with its own accounts, store that pair within the authenticated application user's ownership boundary. A standalone native application without its own account system uses the `id` and `account_id` pair as its local connection identity.
|
|
34
|
+
|
|
35
|
+
Show `budget_name` so the application user can see which budget they are using, but do not use it as a key: two budget accounts can have the same name. When names collide, add a secondary label such as the account ID only where the UI needs to distinguish them. Access tokens are opaque credentials; obtain this information from the API response rather than parsing the token.
|
|
36
|
+
|
|
37
|
+
### Identify the user who completed authorization
|
|
38
|
+
|
|
39
|
+
Lunch Money may reuse an existing browser login session, and the authorization screen may let the person continue with a different Lunch Money user. Shared browser state therefore means that a login can be reused when available; it does not guarantee which user will complete authorization. A fresh or ephemeral browser request is also only an intent, not proof of identity.
|
|
40
|
+
|
|
41
|
+
After every successful code exchange, call and strictly validate `GET /v2/me`. Treat its `id` as the Lunch Money user who actually completed authorization and its `account_id` as the selected budget account. Do not infer that identity from browser cookies, callback fields, `budget_name`, the user who was active before authorization, or token contents.
|
|
42
|
+
|
|
43
|
+
### Select a different budget account
|
|
44
|
+
|
|
45
|
+
Applications that may retain more than one Lunch Money identity should show the active Lunch Money user and which saved connection is the **active budget**. Provide two distinct actions:
|
|
46
|
+
|
|
47
|
+
- Select another saved connection belonging to the active Lunch Money user to switch the active budget without starting OAuth again.
|
|
48
|
+
- Choose **Authorize another budget** to start OAuth and connect a budget account that is not yet saved.
|
|
49
|
+
|
|
50
|
+
To connect to a new, previously unauthorized, budget account, send the user through authorization again and have them select it. Changing a locally stored account ID does not change which account an existing token can access. Refreshing a token renews access for its existing authorization; it does not select another budget account.
|
|
51
|
+
|
|
52
|
+
Applications do not need a separate client-side “use another user” action. The ordinary **Authorize another budget** action starts authorization; Lunch Money handles any login reuse or user switching. After `/v2/me` identifies the result, make that Lunch Money identity active and show only its connections. Clear or partition the previously displayed profile, configuration, and cached financial data before showing the new identity.
|
|
53
|
+
|
|
54
|
+
Authorizing a second budget account for the same Lunch Money user creates or reuses that user's connection and does not revoke the first one. Update each connection's credentials and identity together, and keep cached data from one account separate from data loaded for another.
|
|
55
|
+
|
|
56
|
+
### Reauthorize an existing budget account
|
|
57
|
+
|
|
58
|
+
If authorization returns the same Lunch Money user `id` and budget-account `account_id` as an existing owned connection, treat it as a reconnection. Atomically replace that connection's stored access-token and refresh-token set with the credentials from the successful exchange. A different Lunch Money user authorizing the same shared `account_id` creates or updates a separate connection; it must not overwrite the first user's credentials.
|
|
59
|
+
|
|
60
|
+
When the user chooses to switch between existing authorized budgets, select a saved connection only from the active Lunch Money identity and use that connection's stored access token to make API calls. All account-specific actions must use the active connection. Clear or partition cached financial data when the active connection changes so data from the previous budget is not shown under the new selection. If the active connection is removed, select a documented remaining connection for the same Lunch Money user or enter a disconnected state. Never fall back to another user's hidden connection.
|
|
61
|
+
|
|
62
|
+
### Retain connections for an inactive Lunch Money user
|
|
63
|
+
|
|
64
|
+
An application may retain credentials for a Lunch Money user who is not currently active when its application-user ownership model permits it. Switching identities should hide the previous user's connections and clear or partition that user's displayed data, but hiding a connection does not revoke it or delete its stored credentials. If that Lunch Money user authorizes again later, the application may make the user's retained connections visible again.
|
|
65
|
+
|
|
66
|
+
An application may instead delete stored credentials as part of its own sign-out or user-switch policy. Make that policy understandable in the interface. In particular, distinguish disconnecting or remotely revoking a budget-account authorization from forgetting its local credential without revoking remote access.
|
|
67
|
+
|
|
13
68
|
## Client types and credentials
|
|
14
69
|
|
|
15
70
|
When a developer registers a client, they must choose a client type based on whether the application code can keep a client secret secure. This choice cannot be changed after the client is registered. The developer selects either **Confidential web client** or **Native or public client**.
|
|
16
71
|
|
|
17
|
-
- **Confidential web client:** Runs on a server and can securely store client secrets. In OAuth terminology, this is called a *confidential client*. Choose this type for a web application—or any other application architecture with a centralized server. Its client secret helps Lunch Money verify that a token request came from the application that registered the client. The client secret and refresh tokens must stay on the server. The application must protect access tokens wherever its architecture uses them, and associate each authorization with the correct application user and authorized Lunch Money
|
|
72
|
+
- **Confidential web client:** Runs on a server and can securely store client secrets. In OAuth terminology, this is called a *confidential client*. Choose this type for a web application—or any other application architecture with a centralized server. Its client secret helps Lunch Money verify that a token request came from the application that registered the client. The client secret and refresh tokens must stay on the server. The application must protect access tokens wherever its architecture uses them, and associate each authorization with the correct application user and authorized Lunch Money budget account.
|
|
18
73
|
- **Native or public client:** Runs on a user-controlled device and uses PKCE without a client secret because installed application code cannot keep a secret secure. In OAuth terminology, this is called a *native public client*. Choose this type for a standalone mobile or desktop application. The app stores each user's tokens securely on that user's device—for example, in Keychain on Apple platforms or appropriate Keystore-backed storage on Android—and must avoid exposing them through backups, logs, or application data shared with other apps.
|
|
19
74
|
|
|
75
|
+
These client families are not interchangeable. A confidential server-side sample cannot be moved into a native application by embedding its client secret or server-held credentials; use a native-client flow and platform secure storage instead.
|
|
76
|
+
|
|
20
77
|
Every client receives a client ID that identifies its Lunch Money registration. The client ID is not secret. Both client types also use Proof Key for Code Exchange (PKCE) to bind the authorization response to the application that started the flow.
|
|
21
78
|
|
|
22
79
|
## Redirect URIs
|
|
@@ -5,14 +5,16 @@ Use this guide after you have [registered a client](/oauth/register-client) and
|
|
|
5
5
|
The goal now is to test that complete workflow—including its failure and recovery paths—before asking Lunch Money to approve the application for other users.
|
|
6
6
|
|
|
7
7
|
> [!NOTE] Development access is owner-only
|
|
8
|
-
> While an OAuth client is in development, only the Lunch Money user who owns it can authorize the application. Your team should have the developer doing most of the initial Lunch Money work create and own the client so they can test the complete flow with their
|
|
8
|
+
> While an OAuth client is in development, only the Lunch Money user who owns it can authorize the application. Your team should have the developer doing most of the initial Lunch Money work create and own the client so they can test the complete flow with their budget accounts. Other team members cannot authorize the application until the client has been reviewed and approved.
|
|
9
9
|
|
|
10
10
|
## Set up a safe test environment
|
|
11
11
|
|
|
12
|
-
Use a separate Lunch Money test
|
|
12
|
+
Use a separate Lunch Money test budget account when exercising create, update, or delete operations. The [Getting Started guide](/getting-started#create-a-test-budget-account) walks through creating one and adding sample data.
|
|
13
13
|
|
|
14
14
|
Keep production client secrets, tokens, and user data out of test fixtures, logs, screenshots, and bug reports.
|
|
15
15
|
|
|
16
|
+
If you want a working reference flow for comparison, [try OAuth with the confidential Node.js sample](/oauth/sample-applications#try-oauth-with-your-lunch-money-account). Its `me:read` walkthrough helps validate client registration, exact local callback configuration, discovery, authorization, `GET /v2/me`, and revocation before you debug application-specific features. Add `offline_access` when registering the sample client only if you also want to exercise its optional refresh branch.
|
|
17
|
+
|
|
16
18
|
## Local loopback callbacks
|
|
17
19
|
|
|
18
20
|
When you run a confidential web application on your own computer, its callback handler may not have a public HTTPS address yet. A loopback redirect lets the browser return the authorization result directly to the local process you are developing.
|
|
@@ -25,30 +27,42 @@ For a client in development, register an HTTP redirect using a supported loopbac
|
|
|
25
27
|
|
|
26
28
|
You may choose any available port, but the complete redirect URI sent during authorization must match the registered value exactly. `localhost` and `127.0.0.1` are different hosts, so register the form your application sends. Non-loopback HTTP hosts, embedded credentials, and URI fragments are not supported.
|
|
27
29
|
|
|
28
|
-
The user's browser—not Lunch Money's server—connects to the loopback listener. Keep PKCE and `state` protections in place just as you would for a hosted callback. Before requesting review, also register the HTTPS callback used by the deployed application; the loopback URI can remain available for local testing.
|
|
30
|
+
The user's browser—not Lunch Money's server—connects to the loopback listener. Keep PKCE and `state` protections in place just as you would for a hosted callback. Before requesting review, also register the HTTPS callback used by the deployed application; the loopback URI can remain available for local testing. After approval, you can add or keep a loopback redirect as long as that production HTTPS callback remains. See [after approval](/oauth/review-and-approval#after-approval).
|
|
29
31
|
|
|
30
32
|
> [!NOTE] Test an approved client with your development team
|
|
31
|
-
> After a client is approved, other team members can continue developing and testing the application's Lunch Money functionality.
|
|
33
|
+
> After a client is approved, other team members can continue developing and testing the application's Lunch Money functionality. You can add or keep a loopback redirect on the approved client as long as the production HTTPS callback remains. If a loopback redirect is registered, each developer who can run the application locally may authorize access to their own Lunch Money budget account. The client ID is public, but developers working on a confidential web client also need access to its client secret through your team's secure credential-management process. Do not share access tokens or refresh tokens between developers.
|
|
32
34
|
|
|
33
35
|
## Repeat or reset authorization
|
|
34
36
|
|
|
35
|
-
During development, the client owner can run authorization again whenever they want to repeat the sign-in,
|
|
37
|
+
During development, the client owner can run authorization again whenever they want to repeat the sign-in, budget-account selection, consent, and callback flow. They do not need to revoke the current token first. The authorization server may reuse the current browser login or let the person continue with a different Lunch Money user. Treat the validated `/v2/me` user/account pair—not previous browser state—as the completed authorization's identity.
|
|
36
38
|
|
|
37
39
|
To test how the application responds after access is revoked, revoke the current token and make another API request with it. Lunch Money should reject the request, and the application should discard its saved credentials and begin authorization again. The [token revocation guide](/oauth/tokens#revoke-access) includes copyable `curl` requests for development testing.
|
|
38
40
|
|
|
39
41
|
## Test the complete client
|
|
40
42
|
|
|
43
|
+
Test with one Lunch Money user authorizing multiple budget accounts, then with a second Lunch Money user authorizing through the same browser or device. For a client registered with `me:read`, strictly validate the returned `id` and `account_id` after every exchange. Store credentials under the authenticated application user and that Lunch Money user/account pair. For a standalone app without its own accounts, use the Lunch Money user/account pair as the local connection identity.
|
|
44
|
+
|
|
41
45
|
1. Complete authorization. For each attempt, your application should create a random `state` value, save it with the application user's session, and verify that Lunch Money returns the same value to the callback. Rejecting a missing, changed, or reused value prevents a callback started elsewhere from being attached to the wrong session.
|
|
42
46
|
2. Keep the PKCE verifier with that same authorization attempt and use it when exchanging the returned code. Confirm that an exchange with a missing or changed verifier fails; this prevents someone who intercepts the code from using it.
|
|
43
47
|
3. Read the token response's `scope` field and confirm that it contains the complete scope set registered for the client. Do not inspect or parse the access token itself.
|
|
44
48
|
4. Call every scope-dependent feature, including negative permission cases.
|
|
45
|
-
5. Test user denial, missing or changed `state`, callback errors, and interrupted authorization attempts.
|
|
49
|
+
5. Test user denial, missing or changed `state`, callback errors, and interrupted authorization attempts. Confirm that denial or a failed `/v2/me` validation leaves all existing connections unchanged.
|
|
50
|
+
6. Make `GET /v2/me` fail or return an invalid shape after a successful exchange. Confirm that the application saves no unidentified or partial connection.
|
|
51
|
+
7. Reauthorize an already connected Lunch Money user/account pair. Confirm that the application atomically replaces that connection's credentials, makes it active, and does not create a duplicate.
|
|
52
|
+
8. Authorize as a second Lunch Money user through the same browser or device. Confirm that the previously displayed profile, configuration, saved-budget choices, and cached financial data disappear, while any retained credentials remain hidden.
|
|
53
|
+
9. Return to the first Lunch Money user. Confirm that only that user's retained connections become visible again and that the other user's connections cannot be selected.
|
|
54
|
+
10. Have two different Lunch Money users independently authorize the same shared `account_id`. Confirm that the application stores separate credentials keyed by Lunch Money user `id` and `account_id`, without overwriting either connection.
|
|
55
|
+
11. Give two visible budgets the same `budget_name`. Confirm that they remain separate by `account_id` and that the UI disambiguates them only where needed without using the name as a key.
|
|
56
|
+
12. Attempt to select a connection belonging to an inactive Lunch Money user. Confirm that the request is rejected before credentials or cached data are loaded.
|
|
57
|
+
13. Switch the active budget and exercise API calls, refresh, revocation, and local deletion. Confirm that each action and every cache entry affects only the active user/account connection.
|
|
58
|
+
14. Remove the active Lunch Money user's final budget. Confirm that the application enters a disconnected state rather than exposing or selecting another user's hidden connection.
|
|
59
|
+
15. Test remote disconnect and local-only credential deletion separately. Confirm local-only deletion, explain that the remote authorization remains active, and keep unrelated connections unchanged.
|
|
46
60
|
|
|
47
61
|
## Test reauthorization before refresh
|
|
48
62
|
|
|
49
63
|
First make sure your application can recover without a refresh token. Record when the token response arrives and use `expires_in` to determine when the access token is expected to expire. After it expires, make a harmless API request and confirm that Lunch Money returns an authentication failure identifying the token as invalid.
|
|
50
64
|
|
|
51
|
-
Your application should discard the unusable token and start authorization again. Confirm that the same application user can complete the flow, select
|
|
65
|
+
Your application should discard the unusable token for that connection and start authorization again. Confirm that the same application user can complete the flow, select the intended budget account, and continue using that connection with the replacement token. This recovery path is required when a client does not have `offline_access`, and it remains the fallback when a refresh token expires, is revoked, or otherwise stops working. Keep other connections usable while this one recovers.
|
|
52
66
|
|
|
53
67
|
After reauthorization works, clients registered with `offline_access` can add and test refresh-token handling. Verify replacement-token storage, concurrent-refresh protection, revocation, and terminal refresh recovery before relying on unattended operation. See [token lifecycle and recovery](/oauth/tokens).
|
|
54
68
|
|
package/docs/oauth/index.md
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
OAuth lets your application access Lunch Money on behalf of a user without asking that person to copy and share a personal access token. **If you are building an application for anyone other than yourself, use OAuth.** It gives each user a familiar Lunch Money sign-in and consent experience while keeping their personal access token out of your application.
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
|
|
7
7
|
## Choose OAuth or a personal access token
|
|
8
8
|
|
|
9
9
|
| Question | Personal access token | OAuth client |
|
|
10
10
|
| --- | --- | --- |
|
|
11
|
-
| Whose data can it access? | One
|
|
11
|
+
| Whose data can it access? | One budget account belonging to the user who created the token | One budget account selected by each user who authorizes the application |
|
|
12
12
|
| Best fit | API exploration, one-off scripts, and short-lived work on your own account | Persistent integrations and applications intended for other users |
|
|
13
13
|
| How is access granted? | The user creates a token on the [Developers page](https://my.lunchmoney.app/developers) in the Lunch Money web app | The user signs in and approves the permissions requested by the application |
|
|
14
14
|
| Credential handling | The user keeps the token and sends it with their own API requests; third-party applications should use OAuth instead of asking users to share one | The authorization flow delivers application-specific tokens without asking for a personal token |
|
|
15
|
-
| Permissions | Full access to the Lunch Money APIs available for that
|
|
15
|
+
| Permissions | Full access to the Lunch Money APIs available for that budget account, with no fine-grained permission controls | Only the permissions selected when the OAuth client was registered |
|
|
16
16
|
| Lifecycle | Created and revoked by the user | Short-lived access tokens and optional finite refresh access; the user can revoke the application's access |
|
|
17
17
|
|
|
18
18
|
Personal access tokens remain useful for quick work on your own account. OAuth is the recommended model for applications and integrations that other Lunch Money users will connect to, as well as automations that need to run over time.
|
|
@@ -21,8 +21,10 @@ Personal access tokens remain useful for quick work on your own account. OAuth i
|
|
|
21
21
|
|
|
22
22
|
An OAuth client is an application's registration with Lunch Money. When a developer registers the client, they select the scopes—the specific permissions—the application needs. Later, when a Lunch Money user authorizes the application, Lunch Money shows them that complete permission set before they approve access. Choose only the permissions the application's features require. A focused permission request is easier for users to understand and trust, and reduces the risk of the application reading or changing data it does not need.
|
|
23
23
|
|
|
24
|
+
One Lunch Money user can have multiple budget accounts and multiple connections to the same OAuth client. Each OAuth access token represents that user and the single budget account they selected during authorization. It does not provide access to all of their budgets. Read [users, budget accounts, and access tokens](/oauth/concepts#users-budget-accounts-and-access-tokens) for an example and how to identify the connected account.
|
|
25
|
+
|
|
24
26
|
## Before you start
|
|
25
27
|
|
|
26
28
|
You need an active Lunch Money account to [register and manage an OAuth client](/oauth/applications) for your application. During development, only the client owner can authorize the application. Approval is required before other Lunch Money users can authorize it.
|
|
27
29
|
|
|
28
|
-
Start with [OAuth concepts](/oauth/concepts), [register a client](/oauth/register-client), and then [implement the authorization-code flow](/oauth/authorization-code). Use the [scope catalog](/oauth/scopes) to plan permissions and [troubleshooting](/oauth/troubleshooting) when a flow fails.
|
|
30
|
+
Start with [OAuth concepts](/oauth/concepts), [register a client](/oauth/register-client), and then [implement the authorization-code flow](/oauth/authorization-code). You can also run the [confidential Node.js sample application](/oauth/sample-applications) to see registration, authorization, an API call, revocation, and local reset working together. Use the [scope catalog](/oauth/scopes) to plan permissions and [troubleshooting](/oauth/troubleshooting) when a flow fails.
|
|
@@ -15,12 +15,36 @@ Use Lunch Money's authorization-server discovery document and configure `token_e
|
|
|
15
15
|
|
|
16
16
|
Use a redirect mechanism that returns control to your app and that your platform can bind to it. Claimed Universal Links or Android App Links provide stronger app ownership than a custom URI scheme when correctly configured. A private-use scheme must contain a dot, such as `app.example.demo:/oauth/callback`, and must be protected against interception.
|
|
17
17
|
|
|
18
|
-
Native clients may use an HTTP loopback redirect with `localhost`, `127.0.0.1`, or `[::1]`. The scheme, host, path, and query string must exactly match the registered URI, but the port may differ so the application can bind an ephemeral port at runtime. The exception applies only to loopback redirects for native clients; native HTTPS and private-use scheme redirects must match every component of the registered URI exactly.
|
|
18
|
+
Native clients may use an HTTP loopback redirect with `localhost`, `127.0.0.1`, or `[::1]`. The scheme, host, path, and query string must exactly match the registered URI, but the port may differ so the application can bind an ephemeral port at runtime. The exception applies only to loopback redirects for native clients; native HTTPS and private-use scheme redirects must match every component of the registered URI exactly. The loopback hosts are not interchangeable: a client registered with `http://127.0.0.1/cb` cannot authorize with `http://localhost:4000/cb` or `http://[::1]:4000/cb`, so register the host your app actually binds to.
|
|
19
19
|
|
|
20
20
|
## Store and renew tokens
|
|
21
21
|
|
|
22
22
|
Store tokens in Keychain on Apple platforms. On Android, use current Keystore-backed storage guidance from your maintained library; do not start new work with deprecated `EncryptedSharedPreferences` APIs. Coordinate refresh-token use, persist replacements, and fall back to interactive authorization after terminal failure.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
After every code exchange, call and strictly validate `GET /v2/me` before adding the credentials to the app's normal connection store. For an app without its own user accounts, identify each local connection by the returned Lunch Money user `id` and budget-account `account_id` pair. Atomically create a record for a new pair or replace the credential set for an existing pair. Two Lunch Money users may authorize the same shared `account_id`; their credentials must remain in separate records. If identification or persistence fails, discard the temporary credentials instead of saving a partial or unidentified connection. Retain `budget_name` for display, but never use it as a key because different budgets can share a name.
|
|
25
|
+
|
|
26
|
+
The platform authentication browser may reuse an existing Lunch Money login, and Lunch Money may let the person use a different user from the authorization screen. An ephemeral-session request is only an intent to avoid shared browser state; it does not prove which user completed authorization. Do not infer identity from browser cookies, callback fields, budget names, or token contents. The validated `/v2/me` response is authoritative.
|
|
27
|
+
|
|
28
|
+
Show the active Lunch Money identity when the app may retain more than one, show which authorized budget is active, and provide one separate **Authorize another budget** action that starts OAuth. Do not require another client-side action for switching Lunch Money users. Selecting an existing connection must not start authorization again, and the app must allow selection only among saved budgets for the active Lunch Money user.
|
|
29
|
+
|
|
30
|
+
All API calls, refreshes, revocations, local deletions, and cached data must apply to the active user/account connection. Clear or partition profile, configuration, and cached financial data when the identity or budget changes. When the active connection is removed, choose a deterministic remaining connection for that Lunch Money user or enter a disconnected state; never expose another user's hidden connection as a fallback. Use a secondary label such as the account ID only when duplicate visible budget names need disambiguation.
|
|
31
|
+
|
|
32
|
+
The app may retain credentials for inactive Lunch Money users in secure storage. Switching users hides the previous identity's connections without revoking or deleting them, and authorizing as that identity later may restore its saved budgets. Alternatively, an app may delete credentials during its own sign-out or user-switch lifecycle. Make the chosen behavior understandable without prescribing a particular native control.
|
|
33
|
+
|
|
34
|
+
Present remote disconnect or revocation separately from forgetting a credential only on the device. Confirm local-only deletion and explain that it leaves the remote authorization active.
|
|
35
|
+
|
|
36
|
+
### Keep application users' connections separate
|
|
37
|
+
|
|
38
|
+
A native app can support multiple application users on the same device. If your app has its own sign-in system, keep each user's saved Lunch Money connections in a separate storage namespace. Bind the authorization attempt to the application user who started it, and retain the Lunch Money `id` and `account_id` returned by `GET /v2/me` with each credential set. Only load a connection after verifying that it belongs to the currently authenticated application user. Secure device storage does not perform that application-level ownership check for you.
|
|
39
|
+
|
|
40
|
+
On application sign-out or application-user switching, stop work using the previous application user's credentials and clear in-memory tokens, the active connection selection, and cached financial data. Remove saved credentials if your app does not retain connections across sign-ins; otherwise, make them available only after their application owner signs in again. Do not attach an OAuth callback or refresh result from the previous session to the newly signed-in application user.
|
|
41
|
+
|
|
42
|
+
If your app has no separate user accounts, the device's OS account and app storage protections provide the local access boundary. Anyone allowed to use the unlocked app may be able to use its saved connections; separate budget-account records alone do not authenticate different people.
|
|
43
|
+
|
|
44
|
+
Sending tokens to an application backend introduces server-side credential storage. If your architecture does that, apply the [credential ownership rules](/oauth/security#associate-credentials-with-your-application-user) on the backend as well as protecting credentials on the device.
|
|
45
|
+
|
|
46
|
+
Platform code should delegate protocol validation to the maintained library while your application supplies safe configuration, lifecycle storage, API calls, revocation, and user-facing recovery.
|
|
47
|
+
|
|
48
|
+
Lunch Money does not currently provide complete Swift or Kotlin samples; the upstream AppAuth projects provide maintained platform examples. Expo developers can use the [native Expo sample](/oauth/sample-applications#native-expo-sample) for a complete Lunch Money walkthrough and reference implementation.
|
|
25
49
|
|
|
26
50
|
Next: [Review OAuth security guidance](/oauth/security).
|
|
@@ -11,6 +11,8 @@ Before you add OAuth to your application code, register an OAuth client with Lun
|
|
|
11
11
|
|
|
12
12
|
List the Lunch Money features your application will provide, then use the [scope catalog](/oauth/scopes) to choose the smallest complete set of permissions those features require. Select `offline_access` only if the application needs to continue making API requests after the initial access token expires and while the user is away.
|
|
13
13
|
|
|
14
|
+
If your application may support more than one Lunch Money user or budget account, always include `me:read`. After authorization, `GET /v2/me` lets your application record both the Lunch Money user's `id` and the selected budget account's `account_id`, then store the connection under the complete application-owner and Lunch Money user/account identity. The same scope is also required when your application only needs to identify one connected budget account.
|
|
15
|
+
|
|
14
16
|
Scopes cannot be changed after registration. While you are developing your application, creating a replacement client is inexpensive, so let the scope set evolve as you learn what the application needs. Aim to have the application's core functionality—and its required permissions—settled before you submit the client for review.
|
|
15
17
|
|
|
16
18
|
If functionality added after launch needs a scope that is not already registered, you must register a replacement client with the new complete scope set and have it reviewed before rollout. Existing authorizations do not transfer to the replacement client, so users must authorize it before they can use the new functionality. Treat that reauthorization as part of the feature launch: explain what the application can now do with their Lunch Money data and invite them to authorize the replacement client when they want to enable it.
|
|
@@ -30,6 +32,10 @@ A redirect URI tells Lunch Money where to return the user after authorization. R
|
|
|
30
32
|
|
|
31
33
|
Web applications normally use an HTTPS callback. If you need a callback for local development, review the [loopback guidance](/oauth/development#local-loopback-callbacks) before registering one. Mobile and desktop applications may use a private-use scheme containing a dot, such as `app.example.demo:/oauth/callback`, or a verified HTTPS link accepted by the Developer Portal.
|
|
32
34
|
|
|
35
|
+
After the client is approved, you can add or replace redirect URIs in the Developer Portal without submitting another initial review. An approved confidential web client must keep a production HTTPS callback. See [after approval](/oauth/review-and-approval#after-approval).
|
|
36
|
+
|
|
37
|
+
Each client can have up to 10 redirect URIs, and each URI can be up to 2,048 characters. If you reach the limit, remove a callback the application no longer uses before adding another.
|
|
38
|
+
|
|
33
39
|
## Register the OAuth client
|
|
34
40
|
|
|
35
41
|
Open the [new OAuth client form](/oauth/applications/new) in the Developer Portal. Then:
|
|
@@ -41,12 +47,16 @@ Open the [new OAuth client form](/oauth/applications/new) in the Developer Porta
|
|
|
41
47
|
5. Select the planned scopes.
|
|
42
48
|
6. Accept the current Lunch Money API Terms of Use and select **Register OAuth client**.
|
|
43
49
|
|
|
50
|
+
You can own up to 25 non-deleted OAuth clients. If you reach the limit, delete a client you no longer use before registering another.
|
|
51
|
+
|
|
44
52
|
After registration, record the client ID in your application configuration. A client ID identifies the registration but is not a secret.
|
|
45
53
|
|
|
46
54
|
If you registered a **Confidential web client**, create a client secret from its details page. Lunch Money shows the secret value only once. Copy it immediately into a secret manager or protected server configuration; it cannot be retrieved later. Never commit it or expose it in browser or mobile code.
|
|
47
55
|
|
|
48
|
-
A confidential web client can have
|
|
56
|
+
A confidential web client can have up to three non-revoked secrets. This allows you to introduce a replacement secret, update and verify the deployed application, and then revoke the old secret without interrupting authorization. Expired secrets still count toward the limit until you revoke them. Revoking an obsolete secret frees a slot, and revoked secrets no longer appear in the client's secret list. See [OAuth security guidance](/oauth/security#operate-credentials-safely) when planning ongoing rotation.
|
|
49
57
|
|
|
50
58
|
You now have the client settings needed to connect your application to Lunch Money.
|
|
51
59
|
|
|
60
|
+
To exercise those settings with a focused confidential-client implementation, [try OAuth with the Node.js sample](/oauth/sample-applications#try-oauth-with-your-lunch-money-account).
|
|
61
|
+
|
|
52
62
|
Next: [Implement authorization](/oauth/authorization-code).
|
|
@@ -10,7 +10,7 @@ When the application is ready, submit its client for review in the Developer Por
|
|
|
10
10
|
| --- | --- | --- |
|
|
11
11
|
| `development` | The client has not been submitted for review; only its owner can authorize it | Configure and test, then request review. |
|
|
12
12
|
| `pending_review` | Review has been requested and is waiting for or receiving review; review-critical fields are frozen | Continue owner testing or cancel the request. |
|
|
13
|
-
| `active` | The review was approved; other Lunch Money users may authorize the application |
|
|
13
|
+
| `active` | The review was approved; other Lunch Money users may authorize the application | Keep configuration current; identity updates reach users after Lunch Money reviews them. |
|
|
14
14
|
| `rejected` | Changes were requested | Read feedback, revise editable configuration, and resubmit. |
|
|
15
15
|
| `disabled` | Lunch Money disabled the client; its owner is notified, authorization is unavailable, and existing grants no longer work | Review the reason provided and contact developer support when appropriate. |
|
|
16
16
|
|
|
@@ -52,6 +52,10 @@ Native clients may be reviewed with loopback or private-use scheme redirects.
|
|
|
52
52
|
|
|
53
53
|
Submitting the request moves the client to `pending_review` and temporarily freezes review-critical fields. Reviews are usually completed within a couple of business days. You can continue developing and testing the application as the client owner while you wait. If you need to change a frozen field, cancel the request to return the client to `development`, make the change, and submit it again.
|
|
54
54
|
|
|
55
|
+
You can make up to five initial review submissions across all your clients in a rolling 24-hour period. Cancelled submissions and submissions made again after a rejection still count. Deleting a client does not remove its submissions from the window. Reviews opened automatically after you update the identity of an active client do not count toward this limit.
|
|
56
|
+
|
|
57
|
+
If you reach the limit, the Developer Portal tells you when you can submit again. Wait until that time before retrying; cancelling, deleting, or replacing a client does not reset the window.
|
|
58
|
+
|
|
55
59
|
Lunch Money emails you when the review is complete. You can also check the current status and review history on the client's page in the Developer Portal.
|
|
56
60
|
|
|
57
61
|
## If review is denied
|
|
@@ -62,8 +66,12 @@ There is no review comment thread, so use the new request's additional context t
|
|
|
62
66
|
|
|
63
67
|
## After approval
|
|
64
68
|
|
|
65
|
-
An `active` client can be authorized by other users.
|
|
69
|
+
An `active` client can be authorized by other users. Keep its configuration current in the Developer Portal. You do not need to contact Lunch Money to rename the application, move hosting, or update a support address.
|
|
70
|
+
|
|
71
|
+
Changes save immediately, and the client stays `active`. Redirect URIs, support email, description, and developer name take effect as soon as you save them. An approved confidential web client must keep at least one public HTTPS redirect.
|
|
72
|
+
|
|
73
|
+
Name, logo, homepage URL, and privacy policy URL also save immediately, but Lunch Money users continue to see the last approved identity on the consent screen and Connected Apps page until Lunch Money reviews the update. The Developer Portal shows that as an identity update in review; it is not a return to `rejected`, and existing authorizations keep working.
|
|
66
74
|
|
|
67
|
-
|
|
75
|
+
Client-secret rotation and revocation remain available subject to lifecycle and security checks. Scopes and client type cannot be changed after registration. A scope change requires a replacement client and user reauthorization.
|
|
68
76
|
|
|
69
77
|
Next: [Review the security checklist](/oauth/security).
|