All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.auties.whatsapp.registration.WhatsappMetadata Maven / Gradle / Ivy

package it.auties.whatsapp.registration;

import com.fasterxml.jackson.annotation.JsonProperty;
import it.auties.curve25519.Curve25519;
import it.auties.whatsapp.controller.Keys;
import it.auties.whatsapp.crypto.MD5;
import it.auties.whatsapp.model.business.BusinessVerifiedNameCertificateBuilder;
import it.auties.whatsapp.model.business.BusinessVerifiedNameCertificateSpec;
import it.auties.whatsapp.model.business.BusinessVerifiedNameDetailsBuilder;
import it.auties.whatsapp.model.business.BusinessVerifiedNameDetailsSpec;
import it.auties.whatsapp.model.signal.auth.UserAgent.PlatformType;
import it.auties.whatsapp.model.signal.auth.Version;
import it.auties.whatsapp.net.HttpClient;
import it.auties.whatsapp.util.Json;

import java.net.URI;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.HexFormat;
import java.util.concurrent.CompletableFuture;

public final class WhatsappMetadata {
    private static final Version MOBILE_BUSINESS_IOS_VERSION = Version.of("2.24.16.78");
    private static final Version MOBILE_PERSONAL_IOS_VERSION = Version.of("2.24.17.71");
    private static final URI WEB_UPDATE_URL = URI.create("https://web.whatsapp.com/check-update?version=2.2245.9&platform=web");
    private static final String MOBILE_IOS_STATIC = "0a1mLfGUIBVrMKF1RdvLI5lkRBvof6vn0fD2QRSM";
    private static final String MOBILE_BUSINESS_IOS_STATIC = "USUDuDYDeQhY4RF2fCSp5m3F6kJ1M2J8wS7bbNA2";

    private static volatile Version webVersion;
    
    public static CompletableFuture getVersion(PlatformType platform) {
        return switch (platform) {
            case WEB, WINDOWS, MACOS ->
                    getWebVersion();
            case IOS ->
                    CompletableFuture.completedFuture(MOBILE_PERSONAL_IOS_VERSION);
            case IOS_BUSINESS ->
                    CompletableFuture.completedFuture(MOBILE_BUSINESS_IOS_VERSION);
            default -> throw new IllegalStateException("Unsupported mobile os: " + platform);
        };
    }

    private static CompletableFuture getWebVersion() {
        if (webVersion != null) {
            return CompletableFuture.completedFuture(webVersion);
        }

        var client = new HttpClient(HttpClient.Platform.DEFAULT, false);
        return client.getString(WEB_UPDATE_URL).thenApplyAsync(response -> {
            var webVersionResponse = Json.readValue(response, WebVersionResponse.class);
            return webVersion = Version.of(webVersionResponse.currentVersion());
        });
    }

    public static CompletableFuture getToken(long phoneNumber, PlatformType platform, Version appVersion) {
        return switch (platform) {
            case IOS, IOS_BUSINESS -> getIosToken(phoneNumber, appVersion, platform.isBusiness());
            default -> throw new IllegalStateException("Unsupported mobile os: " + platform);
        };
    }

    private static CompletableFuture getIosToken(long phoneNumber, Version version, boolean business) {
        var staticToken = business ? MOBILE_BUSINESS_IOS_STATIC : MOBILE_IOS_STATIC;
        var token = staticToken + HexFormat.of().formatHex(version.toHash()) + phoneNumber;
        return CompletableFuture.completedFuture(HexFormat.of().formatHex(MD5.calculate(token)));
    }

    public static String generateBusinessCertificate(Keys keys) {
        var details = new BusinessVerifiedNameDetailsBuilder()
                .name("")
                .issuer("smb:wa")
                .serial(Math.abs(new SecureRandom().nextLong()))
                .build();
        var encodedDetails = BusinessVerifiedNameDetailsSpec.encode(details);
        var certificate = new BusinessVerifiedNameCertificateBuilder()
                .encodedDetails(encodedDetails)
                .signature(Curve25519.sign(keys.identityKeyPair().privateKey(), encodedDetails, true))
                .build();
        return Base64.getUrlEncoder().encodeToString(BusinessVerifiedNameCertificateSpec.encode(certificate));
    }


    private record WebVersionResponse(@JsonProperty("isBroken") boolean broken,
                                     @JsonProperty("isBelowSoft") boolean outdatedSoft,
                                     @JsonProperty("isBelowHard") boolean outdatedHard,
                                     @JsonProperty("hardUpdateTime") long outdatedUpdateTime,
                                     @JsonProperty("beta") String beta,
                                     @JsonProperty("currentVersion") String currentVersion) {

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy