@lunch-money/v2-api-spec 2.11.1-preview.9 → 2.11.2-preview.2

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.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared preflight and authoritative-validation policy for OAuth client logos.
3
+ *
4
+ * Client-side validation improves feedback, but API implementations must
5
+ * independently validate uploaded bytes and remain authoritative.
6
+ */
7
+ export declare const oauthClientLogoPolicy: Readonly<{
8
+ readonly id: "oauth-client-logo-v1";
9
+ readonly acceptedMediaTypes: readonly ["image/png", "image/jpeg", "image/webp"];
10
+ readonly maxBytes: 1000000;
11
+ readonly minWidth: 200;
12
+ readonly minHeight: 200;
13
+ readonly maxWidth: 4096;
14
+ readonly maxHeight: 4096;
15
+ readonly maxPixels: 16000000;
16
+ readonly minAspectRatio: 0.95;
17
+ readonly maxAspectRatio: 1.05;
18
+ readonly allowAnimation: false;
19
+ readonly recommendations: Readonly<{
20
+ width: 512;
21
+ height: 512;
22
+ avoidText: true;
23
+ supportLightAndDarkBackgrounds: true;
24
+ }>;
25
+ }>;
26
+ export type OAuthClientLogoMediaType = typeof oauthClientLogoPolicy.acceptedMediaTypes[number];
27
+ export type OAuthClientLogoErrorCode = 'logo_required' | 'logo_file_too_large' | 'unsupported_logo_media_type' | 'invalid_logo_image' | 'invalid_logo_dimensions' | 'invalid_logo_aspect_ratio' | 'animated_logo_not_supported' | 'logo_processing_failed';
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oauthClientLogoPolicy = void 0;
4
+ /**
5
+ * Shared preflight and authoritative-validation policy for OAuth client logos.
6
+ *
7
+ * Client-side validation improves feedback, but API implementations must
8
+ * independently validate uploaded bytes and remain authoritative.
9
+ */
10
+ exports.oauthClientLogoPolicy = Object.freeze({
11
+ id: 'oauth-client-logo-v1',
12
+ acceptedMediaTypes: Object.freeze([
13
+ 'image/png',
14
+ 'image/jpeg',
15
+ 'image/webp',
16
+ ]),
17
+ maxBytes: 1_000_000,
18
+ minWidth: 200,
19
+ minHeight: 200,
20
+ maxWidth: 4096,
21
+ maxHeight: 4096,
22
+ maxPixels: 16_000_000,
23
+ minAspectRatio: 0.95,
24
+ maxAspectRatio: 1.05,
25
+ allowAnimation: false,
26
+ recommendations: Object.freeze({
27
+ width: 512,
28
+ height: 512,
29
+ avoidText: true,
30
+ supportLightAndDarkBackgrounds: true,
31
+ }),
32
+ });
@@ -9,30 +9,9 @@ exports.validateOAuthCatalog = validateOAuthCatalog;
9
9
  const freezeScope = (scope) => Object.freeze({ ...scope, operationIds: Object.freeze([...scope.operationIds]) });
10
10
  const freezeGroup = (group) => Object.freeze({ ...group, scopes: Object.freeze([...group.scopes]) });
11
11
  const scopeDefinitions = [
12
- {
13
- name: 'openid',
14
- description: 'Verify your identity with Lunch Money',
15
- category: 'identity',
16
- operationIds: [],
17
- status: 'active',
18
- },
19
- {
20
- name: 'email',
21
- description: 'View your email address and whether it has been verified',
22
- category: 'identity',
23
- operationIds: [],
24
- status: 'active',
25
- },
26
- {
27
- name: 'profile',
28
- description: 'View your Lunch Money profile information',
29
- category: 'identity',
30
- operationIds: [],
31
- status: 'active',
32
- },
33
12
  {
34
13
  name: 'offline_access',
35
- description: 'Continue accessing Lunch Money when you are not actively using the app',
14
+ description: 'Allow this app to maintain access without asking you to sign in and authorize it again',
36
15
  category: 'offline',
37
16
  operationIds: [],
38
17
  status: 'active',
@@ -193,7 +172,7 @@ const scopeDefinitions = [
193
172
  },
194
173
  {
195
174
  name: 'transactions:read',
196
- description: 'View transactions, including split and group information and attachment metadata',
175
+ description: 'View transactions, including split and group information',
197
176
  category: 'api',
198
177
  operationIds: ['getAllTransactions', 'getTransactionById'],
199
178
  status: 'active',
@@ -221,7 +200,7 @@ const scopeDefinitions = [
221
200
  },
222
201
  {
223
202
  name: 'transaction_attachments:read',
224
- description: 'Get download access to transaction attachments',
203
+ description: 'View transaction attachment metadata and get download access to attachments',
225
204
  category: 'api',
226
205
  operationIds: ['getTransactionAttachmentUrl'],
227
206
  status: 'active',
@@ -413,7 +392,7 @@ function getOAuthScopeForOperationId(operationId) {
413
392
  return scopeByOperationId.get(operationId);
414
393
  }
415
394
  const canonicalSet = (values) => [...values].sort().join('\u0000');
416
- const SCOPE_NAME_PATTERN = /^(?:openid|email|profile|offline_access|[a-z][a-z0-9_]*:(?:read|create|update|delete))$/;
395
+ const SCOPE_NAME_PATTERN = /^(?:offline_access|[a-z][a-z0-9_]*:(?:read|create|update|delete))$/;
417
396
  const GROUP_ID_PATTERN = /^[a-z][a-z0-9_]*$/;
418
397
  function matchOAuthScopeGroup(scopeNames) {
419
398
  const names = new Set(scopeNames);
@@ -7,7 +7,7 @@ export type OAuthScopeResource = 'me' | 'summary' | 'categories' | 'crypto_manua
7
7
  * Persisted and API-facing scope values remain strings so newer names can be
8
8
  * preserved and reported as unknown by consumers with an older catalog.
9
9
  */
10
- export type KnownOAuthScopeName = 'openid' | 'email' | 'profile' | 'offline_access' | 'me:read' | 'me:update' | 'summary:read' | 'categories:read' | 'categories:create' | 'categories:update' | 'categories:delete' | 'crypto_manual:read' | 'crypto_manual:create' | 'crypto_manual:update' | 'crypto_manual:delete' | 'crypto_synced:read' | 'crypto_synced:update' | 'balance_history:read' | 'balance_history:update' | 'balance_history:delete' | 'manual_accounts:read' | 'manual_accounts:create' | 'manual_accounts:update' | 'manual_accounts:delete' | 'plaid_accounts:read' | 'plaid_accounts:update' | 'transactions:read' | 'transactions:create' | 'transactions:update' | 'transactions:delete' | 'transaction_attachments:read' | 'transaction_attachments:create' | 'transaction_attachments:delete' | 'tags:read' | 'tags:create' | 'tags:update' | 'tags:delete' | 'recurring_items:read' | 'budgets:read' | 'budgets:update' | 'budgets:delete';
10
+ export type KnownOAuthScopeName = 'offline_access' | 'me:read' | 'me:update' | 'summary:read' | 'categories:read' | 'categories:create' | 'categories:update' | 'categories:delete' | 'crypto_manual:read' | 'crypto_manual:create' | 'crypto_manual:update' | 'crypto_manual:delete' | 'crypto_synced:read' | 'crypto_synced:update' | 'balance_history:read' | 'balance_history:update' | 'balance_history:delete' | 'manual_accounts:read' | 'manual_accounts:create' | 'manual_accounts:update' | 'manual_accounts:delete' | 'plaid_accounts:read' | 'plaid_accounts:update' | 'transactions:read' | 'transactions:create' | 'transactions:update' | 'transactions:delete' | 'transaction_attachments:read' | 'transaction_attachments:create' | 'transaction_attachments:delete' | 'tags:read' | 'tags:create' | 'tags:update' | 'tags:delete' | 'recurring_items:read' | 'budgets:read' | 'budgets:update' | 'budgets:delete';
11
11
  export type OAuthScopeName = string;
12
12
  export interface OAuthScopeDefinition {
13
13
  readonly name: KnownOAuthScopeName;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunch-money/v2-api-spec",
3
- "version": "2.11.1-preview.9",
3
+ "version": "2.11.2-preview.2",
4
4
  "description": "OpenAPI specification and version history for the Lunch Money v2 API",
5
5
  "main": "lunch-money-api-v2.yaml",
6
6
  "exports": {
@@ -12,6 +12,11 @@
12
12
  "require": "./oauth-scopes/index.js",
13
13
  "default": "./oauth-scopes/index.js"
14
14
  },
15
+ "./oauth-client-logo": {
16
+ "types": "./oauth-client-logo/index.d.ts",
17
+ "require": "./oauth-client-logo/index.js",
18
+ "default": "./oauth-client-logo/index.js"
19
+ },
15
20
  "./package.json": "./package.json",
16
21
  "./*": "./*"
17
22
  },
@@ -19,13 +24,22 @@
19
24
  "lunch-money-api-v2.yaml",
20
25
  "version-history.md",
21
26
  "oauth-scopes",
27
+ "oauth-client-logo",
22
28
  "README.md"
23
29
  ],
24
30
  "scripts": {
25
31
  "prepare": "husky install",
26
32
  "build:oauth-scopes": "tsc -p tsconfig.oauth-scopes.json",
33
+ "build:oauth-client-logo": "tsc -p tsconfig.oauth-client-logo.json",
34
+ "build:shared-contracts": "npm run build:oauth-scopes && npm run build:oauth-client-logo",
27
35
  "test:oauth-scopes": "npm run build:oauth-scopes && node --test test/oauth-scopes/*.test.js",
28
- "prepublishOnly": "npm run build:oauth-scopes && node scripts/prep-for-publish.js",
36
+ "test:oauth-client-logo": "npm run build:oauth-client-logo && node --test test/oauth-client-logo/*.test.js",
37
+ "generate:oauth-docs": "node scripts/generate-oauth-scope-catalog.js",
38
+ "sync:oauth-sample": "node scripts/sync-oauth-sample-walkthrough.js",
39
+ "check:oauth-sample": "node scripts/sync-oauth-sample-walkthrough.js --check",
40
+ "validate:oauth-sample": "npm run test:oauth-docs && npm run check:oauth-sample --",
41
+ "test:oauth-docs": "node scripts/generate-oauth-scope-catalog.js --check && node --test test/oauth-docs/*.test.js",
42
+ "prepublishOnly": "npm run build:shared-contracts && node scripts/prep-for-publish.js",
29
43
  "postpublish": "node scripts/restore-readme.js",
30
44
  "publish:docs": "node scripts/publish-docs.js --tag preview",
31
45
  "publish:spec": "node scripts/publish-spec.js --tag preview",
@@ -5,12 +5,17 @@ The Lunch Money API spec uses a modified version of SEMVER for its versioning me
5
5
  - The minor version represents the number of main endpoints the current version of the spec supports. For example, a version of the API that supports the /me, /categories, and /transactions endpoints would have a minor version of 3.
6
6
  - The revision number represents the number of updates since the last endpoint was added. For example, each time changes are made to one of the existing three APIs as described above, the revision number will be bumped.
7
7
 
8
+ ## v2.11.2 - TBD
9
+ - Add OAuth 2.0 bearer-token authentication to the v2 API, allowing applications to access Lunch Money on behalf of users who authorize them
10
+ - Document and enforce required OAuth scopes for every v2 operation and publish the scope and scope-group catalog mapped to V2 `operationId` values.
11
+ - Added a new `403` `insufficient_scope` response
12
+ - Document the OAuth 2.0 authorization-code flow used to obtain access tokens
13
+ - Add `include_files` query parameter to `GET /transactions/{id}`
14
+
8
15
  ## v2.11.1 - TBD
9
- - Add the OAuth scope and scope-group catalog mapped to V2 `operationId` values
10
16
  - Add `GET /me/account/settings` and `PUT /me/account/settings` for account-level settings
11
17
  - Add `GET /me/user/settings` and `PUT /me/user/settings` for user-level display and formatting preferences
12
18
  - Add `GET /me/user/account/settings` and `PUT /me/user/account/settings` for settings specific to a user and budgeting account
13
- from `GET /me/account/settings` and `PUT /me/account/settings` to `GET /me/user/account/settings` and `PUT /me/user/account/settings`
14
19
  - Add `include_pending_in_totals` to `GET /me/account/settings` and `PUT /me/account/settings`
15
20
  - Add `default_manual_account_id` to `GET /me/user/account/settings` and `PUT /me/user/account/settings`
16
21
  - Document `GET /budgets/settings` response schema publicly; change `budget_period_quantity` to integer