( response: Response, )
| 629 | * absent or empty, and normalize Slack's comma separator back to RFC space-delimited |
| 630 | * scope syntax at this boundary. */ |
| 631 | const nestedAuthedUserGrant = async ( |
| 632 | response: Response, |
| 633 | ): Promise<NestedAuthedUserGrant | undefined> => { |
| 634 | const body = await response |
| 635 | .clone() |
| 636 | .json() |
| 637 | .then( |
| 638 | (value: unknown) => value, |
| 639 | () => null, |
| 640 | ); |
| 641 | const decoded = decodeNestedAuthedUserScope(body); |
| 642 | if (Option.isNone(decoded)) return undefined; |
| 643 | const normalized = decoded.value.authed_user.scope |
| 644 | .split(/[\s,]+/) |
| 645 | .filter(Boolean) |
| 646 | .join(" "); |
| 647 | if (normalized.length === 0) return undefined; |
| 648 | const nestedAccessToken = decoded.value.authed_user.access_token; |
| 649 | const nestedTokenType = decoded.value.authed_user.token_type; |
| 650 | const nestedRefreshToken = decoded.value.authed_user.refresh_token; |
| 651 | const nestedExpiresIn = decoded.value.authed_user.expires_in; |
| 652 | return { |
| 653 | scope: normalized, |
| 654 | ...(nestedAccessToken === undefined ? {} : { accessToken: nestedAccessToken }), |
| 655 | ...(nestedTokenType === undefined ? {} : { tokenType: nestedTokenType }), |
| 656 | ...(nestedRefreshToken === undefined ? {} : { refreshToken: nestedRefreshToken }), |
| 657 | ...(nestedExpiresIn === undefined ? {} : { expiresIn: nestedExpiresIn }), |
| 658 | }; |
| 659 | }; |
| 660 | |
| 661 | // MCP source connections are pure OAuth 2.0. Some providers (PostHog, etc.) |
| 662 | // front an OIDC backend and emit an `id_token` anyway; oauth4webapi then |
no test coverage detected