( input: CreateOAuthClientInput, endpointUrlPolicy: OAuthEndpointUrlPolicy | undefined, )
| 643 | }).pipe(Effect.asVoid); |
| 644 | |
| 645 | const validateClientEndpoints = ( |
| 646 | input: CreateOAuthClientInput, |
| 647 | endpointUrlPolicy: OAuthEndpointUrlPolicy | undefined, |
| 648 | ): Effect.Effect<void, StorageFailure> => |
| 649 | Effect.gen(function* () { |
| 650 | yield* validateSupportedEndpoint(input.tokenUrl, "token_url", endpointUrlPolicy); |
| 651 | if (input.resource != null && input.resource.trim().length > 0) { |
| 652 | yield* validateSupportedEndpoint(input.resource, "resource", endpointUrlPolicy); |
| 653 | } |
| 654 | if (input.grant !== "authorization_code") return; |
| 655 | yield* validateSupportedEndpoint( |
| 656 | input.authorizationUrl, |
| 657 | "authorization_url", |
| 658 | endpointUrlPolicy, |
| 659 | ); |
| 660 | if (isWellKnownOAuthMetadataUrl(input.authorizationUrl)) { |
| 661 | return yield* new StorageError({ |
| 662 | message: |
| 663 | "Invalid OAuth client endpoint configuration: authorization_url must be the OAuth authorization endpoint, not a .well-known metadata URL.", |
| 664 | cause: undefined, |
| 665 | }); |
| 666 | } |
| 667 | if (canonicalUrlString(input.authorizationUrl) === canonicalUrlString(input.tokenUrl)) { |
| 668 | return yield* new StorageError({ |
| 669 | message: |
| 670 | "Invalid OAuth client endpoint configuration: authorization_url must not equal token_url.", |
| 671 | cause: undefined, |
| 672 | }); |
| 673 | } |
| 674 | }); |
| 675 | |
| 676 | /** Resolve a config-declared first-party app to the loaded-client shape the |
| 677 | * flow/refresh paths consume. First-party apps are authorization_code only: |
no test coverage detected