syntax = "proto3";

message HashcashChallenge {
    bytes prefix = 1;
    int32 length = 2;
}

message HashcashSolution {
    bytes suffix = 1;
}

message CodeChallenge {
    Method method = 1;
    enum Method {
        UNKNOWN = 0;
        SMS = 1;
    }
    
    int32 code_length = 2;
    int32 expires_in = 3;
    string canonical_phone_number = 4;
}

message CodeSolution {
    string code = 1;
}

message ClientInfo {
    string client_id = 1;
    string device_id = 2;
}

message UserInfo {
    string name = 1;
    string email = 2;
    bool email_verified = 3;
    string birthdate = 4;
    
    Gender gender = 5;
    enum Gender {
        UNKNOWN = 0;
        MALE = 1;
        FEMALE = 2;
        NEUTRAL = 3;
    }
    
    string phone_number = 6;
    bool phone_number_verified = 7;
    bool email_already_registered = 8;
}

message StoredCredential {
    string username = 1;
    bytes data = 2;
}

message Password {
    string id = 1;
    string password = 2;
    bytes padding = 3;
}

message Challenges {
    repeated Challenge challenges = 1;
}

message Challenge {
    oneof challenge {
        HashcashChallenge hashcash = 1;
        CodeChallenge code = 2;
    }
}

message ChallengeSolutions {
    repeated ChallengeSolution solutions = 1;
}

message ChallengeSolution {
    oneof solution {
        HashcashSolution hashcash = 1;
        CodeSolution code = 2;
    }
}

message Finish {
    int32 unknown1 = 1;
    string uri = 2;
    string nonce = 3;
    int32 unknown2 = 4;
}

message Hint {
    string ui_locales = 1;
}

message Interaction {
    string unknown = 1;
    Finish finish = 2;
    Hint hint = 3;
}

message LoginRequest {
    ClientInfo client_info = 1;
    bytes login_context = 2;
    ChallengeSolutions challenge_solutions = 3;
    Interaction interaction = 4;
    
    oneof login_method {
        StoredCredential stored_credential = 100;
        Password password = 101;
        Password password_v4 = 109;
    }
}

message LoginOk {
    string username = 1;
    string access_token = 2;
    bytes stored_credential = 3;
    int32 access_token_expires_in = 4;
}

message LoginResponse {
    repeated Warnings warnings = 4;
    enum Warnings {
        UNKNOWN_WARNING = 0;
        DEPRECATED_PROTOCOL_VERSION = 1;
    }
    
    bytes login_context = 5;
    string identifier_token = 6;
    UserInfo user_info = 7;
    
    oneof response {
        LoginOk ok = 1;
        LoginError error = 2;
        Challenges challenges = 3;
    }
}

enum LoginError {
    UNKNOWN_ERROR = 0;
    INVALID_CREDENTIALS = 1;
    BAD_REQUEST = 2;
    UNSUPPORTED_LOGIN_PROTOCOL = 3;
    TIMEOUT = 4;
    UNKNOWN_IDENTIFIER = 5;
    TOO_MANY_ATTEMPTS = 6;
    INVALID_PHONENUMBER = 7;
    TRY_AGAIN_LATER = 8;
}
