@Override
  public Mono<GetPreKeysResponse> getPreKeys(final GetPreKeysAnonymousRequest request) {
    final ServiceIdentifier serviceIdentifier =
        ServiceIdentifierUtil.fromGrpcServiceIdentifier(request.getRequest().getTargetIdentifier());

    final byte deviceId = DeviceIdUtil.validate(request.getRequest().getDeviceId());

    return switch (request.getAuthorizationCase()) {
      case GROUP_SEND_TOKEN ->
          groupSendTokenUtil.checkGroupSendToken(request.getGroupSendToken(), List.of(serviceIdentifier))
              .then(lookUpAccount(serviceIdentifier, Status.NOT_FOUND))
              .flatMap(targetAccount -> KeysGrpcHelper.getPreKeys(targetAccount, serviceIdentifier.identityType(), deviceId, keysManager));
      case UNIDENTIFIED_ACCESS_KEY ->
          lookUpAccount(serviceIdentifier, Status.UNAUTHENTICATED)
              .flatMap(targetAccount ->
                  UnidentifiedAccessUtil.checkUnidentifiedAccess(targetAccount, request.getUnidentifiedAccessKey().toByteArray())
                  ? KeysGrpcHelper.getPreKeys(targetAccount, serviceIdentifier.identityType(), deviceId, keysManager)
                  : Mono.error(Status.UNAUTHENTICATED.asException()));
      default -> Mono.error(Status.INVALID_ARGUMENT.asException());
    };
  }
@Test
  void getPreKeysUnidentifiedAccessKey() {
    final Account targetAccount = mock(Account.class);

    final Device targetDevice = DevicesHelper.createDevice(Device.PRIMARY_ID);
    when(targetAccount.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(targetDevice));

    final ECKeyPair identityKeyPair = Curve.generateKeyPair();
    final IdentityKey identityKey = new IdentityKey(identityKeyPair.getPublicKey());
    final UUID uuid = UUID.randomUUID();
    final AciServiceIdentifier identifier = new AciServiceIdentifier(uuid);
    final byte[] unidentifiedAccessKey = TestRandomUtil.nextBytes(UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH);

    when(targetAccount.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey));
    when(targetAccount.getIdentifier(IdentityType.ACI)).thenReturn(uuid);
    when(targetAccount.getIdentityKey(IdentityType.ACI)).thenReturn(identityKey);
    when(accountsManager.getByServiceIdentifierAsync(identifier))
        .thenReturn(CompletableFuture.completedFuture(Optional.of(targetAccount)));

    final ECPreKey ecPreKey = new ECPreKey(1, Curve.generateKeyPair().getPublicKey());
    final ECSignedPreKey ecSignedPreKey = KeysHelper.signedECPreKey(2, identityKeyPair);
    final KEMSignedPreKey kemSignedPreKey = KeysHelper.signedKEMPreKey(3, identityKeyPair);

    when(keysManager.takeEC(uuid, Device.PRIMARY_ID))
        .thenReturn(CompletableFuture.completedFuture(Optional.of(ecPreKey)));

    when(keysManager.takePQ(uuid, Device.PRIMARY_ID))
        .thenReturn(CompletableFuture.completedFuture(Optional.of(kemSignedPreKey)));

    when(keysManager.getEcSignedPreKey(uuid, Device.PRIMARY_ID))
        .thenReturn(CompletableFuture.completedFuture(Optional.of(ecSignedPreKey)));

    final GetPreKeysResponse response = unauthenticatedServiceStub().getPreKeys(GetPreKeysAnonymousRequest.newBuilder()
        .setUnidentifiedAccessKey(ByteString.copyFrom(unidentifiedAccessKey))
        .setRequest(GetPreKeysRequest.newBuilder()
            .setTargetIdentifier(ServiceIdentifierUtil.toGrpcServiceIdentifier(identifier))
            .setDeviceId(Device.PRIMARY_ID))
        .build());

    final GetPreKeysResponse expectedResponse = GetPreKeysResponse.newBuilder()
        .setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
        .putPreKeys(Device.PRIMARY_ID, GetPreKeysResponse.PreKeyBundle.newBuilder()
            .setEcOneTimePreKey(toGrpcEcPreKey(ecPreKey))
            .setEcSignedPreKey(toGrpcEcSignedPreKey(ecSignedPreKey))
            .setKemOneTimePreKey(toGrpcKemSignedPreKey(kemSignedPreKey))
            .build())
        .build();

    assertEquals(expectedResponse, response);
  }