public Mono<MessageAndRecipientIds> authAndCloneAndSaveMessage(
            boolean queryRecipientIds,
            @NotNull Long requesterId,
            @Nullable byte[] requesterIp,
            @NotNull Long referenceId,
            @NotNull Boolean isGroupMessage,
            @NotNull Boolean isSystemMessage,
            @NotNull Long targetId) {
        return queryMessage(referenceId).flatMap(message -> isMessageRecipientOrSender(requesterId,
                message.getIsGroupMessage(),
                message.getTargetId(),
                message.getSenderId()).flatMap(isMessageRecipientOrSender -> {
                    if (!isMessageRecipientOrSender) {
                        return ERROR_NOT_MESSAGE_RECIPIENT_OR_SENDER_TO_FORWARD_MESSAGE;
                    }
                    return authAndSaveMessage(queryRecipientIds,
                            null,
                            node.nextLargeGapId(ServiceType.MESSAGE),
                            requesterId,
                            requesterIp,
                            targetId,
                            isGroupMessage,
                            isSystemMessage,
                            message.getText(),
                            message.getRecords(),
                            message.getBurnAfter(),
                            null,
                            referenceId,
                            null);
                }))
                // We should not tell the client that the message was not found.
                // Otherwise, the user can check if any message exists or not.
                .switchIfEmpty(ERROR_NOT_MESSAGE_RECIPIENT_OR_SENDER_TO_FORWARD_MESSAGE);
    }
@return {@link reactor.core.publisher.MonoEmpty} if {@link MessageProperties#persistMessage}
        is false and no recipient.
        <p>
        {@link MessageAndRecipientIds#message} is null if
        {@link MessageProperties#persistMessage} is false.
turms-service/src/main/java/im/turms/service/domain/message/service/MessageService.java