| @@ -76,6 +76,19 @@ export const registrationScopes = ( · 75 unmodified lines |
| 76 | discoveredScopes: readonly string[], | 76 | discoveredScopes: readonly string[], |
| 77 | ): readonly string[] => (declaredScopes.length > 0 ? declaredScopes : discoveredScopes); | 77 | ): readonly string[] => (declaredScopes.length > 0 ? declaredScopes : discoveredScopes); |
| 78 | | 78 | |
| | 79 | /** The `originIntegration` to send with a `createClient` payload. When the |
| | 80 | * caller passes an explicit `intentIntegration` (edit flow: the app's |
| | 81 | * preserved recorded intent, which may legitimately be `null`), it wins |
| | 82 | * verbatim — editing must never silently overwrite a stamp. Otherwise this is |
| | 83 | * a fresh registration from an integration's dialog, which stamps the current |
| | 84 | * integration as recorded intent (or `null` outside any integration |
| | 85 | * context). */ |
| | 86 | export const resolveOriginIntegration = ( |
| | 87 | intentIntegration: IntegrationSlug | null | undefined, |
| | 88 | integrationSlug: IntegrationSlug | undefined, |
| | 89 | ): IntegrationSlug | null => |
| | 90 | intentIntegration !== undefined ? intentIntegration : (integrationSlug ?? null); |
| | 91 | |
| 79 | export const canSubmitOAuthClientForm = (input: { | 92 | export const canSubmitOAuthClientForm = (input: { |
| 80 | readonly submitting: boolean; | 93 | readonly submitting: boolean; |
| 81 | readonly name: string; | 94 | readonly name: string; |
| @@ -101,6 +114,13 @@ export function OAuthClientForm(props: { · 19 unmodified lines |
| 101 | * when editing (an existing app's origin is fixed) or when there is no single | 114 | * when editing (an existing app's origin is fixed) or when there is no single |
| 102 | * integration context. */ | 115 | * integration context. */ |
| 103 | readonly integrationSlug?: IntegrationSlug; | 116 | readonly integrationSlug?: IntegrationSlug; |
| | 117 | /** Explicit recorded-intent stamp to send verbatim, overriding the default |
| | 118 | * derivation from `integrationSlug`. Set this when editing an existing app |
| | 119 | * so its ALREADY-recorded origin (which may be `null`) is preserved rather |
| | 120 | * than re-derived from the current dialog's integration context. Omit for a |
| | 121 | * fresh registration, where the default (stamp `integrationSlug`, or `null` |
| | 122 | * outside an integration context) is correct. */ |
| | 123 | readonly intentIntegration?: IntegrationSlug | null; |
| 104 | /** Existing client slugs, so the generated slug stays unique across apps. */ | 124 | /** Existing client slugs, so the generated slug stays unique across apps. */ |
| 105 | readonly existingSlugs: readonly string[]; | 125 | readonly existingSlugs: readonly string[]; |
| 106 | /** Endpoints/scopes declared by the integration's OAuth method. */ | 126 | /** Endpoints/scopes declared by the integration's OAuth method. */ |
| @@ -125,6 +145,7 @@ export function OAuthClientForm(props: { · 18 unmodified lines |
| 125 | const { | 145 | const { |
| 126 | integrationName, | 146 | integrationName, |
| 127 | integrationSlug, | 147 | integrationSlug, |
| | 148 | intentIntegration, |
| 128 | existingSlugs, | 149 | existingSlugs, |
| 129 | prefill, | 150 | prefill, |
| 130 | fixedSlug, | 151 | fixedSlug, |
| @@ -307,9 +328,10 @@ export function OAuthClientForm(props: { · 176 unmodified lines |
| 307 | clientId: clientId.trim(), | 328 | clientId: clientId.trim(), |
| 308 | clientSecret: clientSecret.trim(), | 329 | clientSecret: clientSecret.trim(), |
| 309 | resource, | 330 | resource, |
| 310 | // Editing keeps the app's original origin; only a fresh registration | 331 | // Editing preserves the app's already-recorded origin (via |
| 311 | // from an integration's dialog stamps recorded intent. | 332 | // `intentIntegration`, passed verbatim by the caller); a fresh |
| 312 | originIntegration: fixedSlug ? null : (integrationSlug ?? null), | 333 | // registration from an integration's dialog stamps recorded intent. |
| | 334 | originIntegration: resolveOriginIntegration(intentIntegration, integrationSlug), |
| 313 | }, | 335 | }, |
| 314 | reactivityKeys: oauthClientWriteKeys, | 336 | reactivityKeys: oauthClientWriteKeys, |
| 315 | }); | 337 | }); |