@NonNull
  public AuthorizationResponse auth(@NonNull AuthorizationRequest request) {

    validateAuthorizationRequest(request);

    var verifier = generatePkceCodeVerifier();

    var codeChallenge = calculateS256CodeChallenge(verifier);

    var relyingPartyCallback = baseUri.resolve("/auth/callback");

    var step1 =
        authenticationFlow.start(
            new AuthenticationFlow.Session(
                request.state(),
                request.nonce(),
                relyingPartyCallback,
                codeChallenge,
                federationConfig.scopes()));

    var identityProviders = step1.fetchIdpOptions();

    var sessionId = IdGenerator.generateID();
    var session =
        Session.create()
            .id(sessionId)
            .state(request.state())
            .nonce(request.nonce())
            .redirectUri(request.redirectUri())
            .clientId(request.clientId())
            .codeVerifier(verifier)
            .selectSectoralIdpStep(step1)
            .build();

    sessionRepo.save(session);

    return new AuthorizationResponse(identityProviders, sessionId);
  }
@Test
  void auth_untrustedRedirect() {
    var config = new RelyingPartyConfig(null, List.of(REDIRECT_URI));

    var sut = new AuthService(BASE_URI, config, null, null, null, null);

    var scope = "openid email";
    var state = UUID.randomUUID().toString();
    var nonce = UUID.randomUUID().toString();
    var responseType = "code";
    var clientId = "myapp";
    var redirectUri = URI.create("https://bad.example.com/evil");
    var req = new AuthorizationRequest(scope, state, responseType, clientId, redirectUri, nonce);

    // when & then
    assertThrows(ValidationException.class, () -> sut.auth(req));
  }