( input: CreateOAuthClientInput, endpointUrlPolicy: OAuthEndpointUrlPolicy | undefined, )
| 438 | }).pipe(Effect.asVoid); |
| 439 | |
| 440 | const validateClientEndpoints = ( |
| 441 | input: CreateOAuthClientInput, |
| 442 | endpointUrlPolicy: OAuthEndpointUrlPolicy | undefined, |
| 443 | ): Effect.Effect<void, StorageFailure> => |
| 444 | Effect.gen(function* () { |
| 445 | yield* validateSupportedEndpoint(input.tokenUrl, "token_url", endpointUrlPolicy); |
| 446 | if (input.resource != null && input.resource.trim().length > 0) { |
| 447 | yield* validateSupportedEndpoint(input.resource, "resource", endpointUrlPolicy); |
| 448 | } |
| 449 | if (input.grant !== "authorization_code") return; |
| 450 | yield* validateSupportedEndpoint( |
| 451 | input.authorizationUrl, |
| 452 | "authorization_url", |
| 453 | endpointUrlPolicy, |
| 454 | ); |
| 455 | if (isWellKnownOAuthMetadataUrl(input.authorizationUrl)) { |
| 456 | return yield* new StorageError({ |
| 457 | message: |
| 458 | "Invalid OAuth client endpoint configuration: authorization_url must be the OAuth authorization endpoint, not a .well-known metadata URL.", |
| 459 | cause: undefined, |
| 460 | }); |
| 461 | } |
| 462 | if (canonicalUrlString(input.authorizationUrl) === canonicalUrlString(input.tokenUrl)) { |
| 463 | return yield* new StorageError({ |
| 464 | message: |
| 465 | "Invalid OAuth client endpoint configuration: authorization_url must not equal token_url.", |
| 466 | cause: undefined, |
| 467 | }); |
| 468 | } |
| 469 | }); |
| 470 | |
| 471 | export const makeOAuthService = (deps: OAuthServiceDeps): OAuthService => { |
| 472 | const httpClientLayer = deps.httpClientLayer ?? FetchHttpClient.layer; |
no test coverage detected