<commit_before>"use strict";

var request = require('request').defaults({
    headers: {
        "x-tesla-user-agent": "TeslaApp/3.10.8-421/adff2e065/android/8.1.0",
        "user-agent": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel XL Build/OPM4.171019.021.D1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.91 Mobile Safari/537.36",
        "x-requested-with": "com.teslamotors.tesla"
    },
    gzip: true,
    jar: true
});
var crypto = require('crypto');
var Promise = require('promise');

exports.login = function login(credentials, callback) {
    var codeVerifier = generateCodeVerifier();
    var codeChallenge = generateCodeChallenge(codeVerifier);
    var queryString = {
        audience: '',
        client_id: 'ownerapi',
        code_challenge: codeChallenge,
        code_challenge_method: 'S256',
        locale: 'en',
        prompt: 'login',
        redirect_uri: 'https://auth.tesla.com/void/callback',
        response_type: 'code',
        scope: 'openid email offline_access',
        state: generateCodeChallenge(generateCodeVerifier())
    };
    var transactionId = null;
    var loginHost = null;
    var loginUrl = null;

    req({
        method: 'GET',
        url: 'https://auth-global.tesla.com/oauth2/v3/authorize',
        qs: queryString,
        headers: {
            "sec-fetch-site": "none",
            "sec-fetch-mode": "navigate",
            "sec-fetch-user": "?1",
            "sec-fetch-dest": "document"
        }
    }).then(function (result) {
        // Record the final URL we got redirected to; this is where we will send our credentials
        loginUrl = result.response.request.href;
        loginHost = "https://" + require('url').parse(loginUrl).host;
        var form = {};
        
        var hiddenFormFields = result.body.match(/<input type="hidden" [^>]+>/g);
        hiddenFormFields.forEach(function (field) {
            var name = field.match(/name="([^"]+)"/);
            var value = field.match(/value="([^"]*)"/);
            if (name && value) {
                form[name[1]] = value[1];
            }
        });

        transactionId = form.transaction_id;
        
        form.identity = credentials.identity;
        form.credential = credentials.credential;

        return req({
            method: 'POST',
            url: loginUrl,
            form: form,
            headers: {
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "navigate",
                "sec-fetch-user": "?1",
                "sec-fetch-dest": "document",
                "referer": loginUrl,
                "origin": loginHost
            }
        });
    }).then(function (result) {
        if (result.body.includes('/oauth2/v3/authorize/mfa/verify')) {
            // MFA is required
            if (!credentials.mfaPassCode) {
                throw new Error("MFA passcode required");
            }
        
            return mfaVerify(transactionId, loginHost, loginUrl, credentials.mfaPassCode, credentials.mfaDeviceName);
        }
    
        // No need to handle MFA
        return result;
    }).then(function (result) {
        var location = result.response.headers.location;
        if (!location) {
            throw new Error("Login credentials rejected");
        }

        var url = require('url').parse(location, true);
        if (!url.query || !url.query.code) {
            throw new Error("No authorization code issued; credentials likely incorrect");
        }

        return req({
            method: 'POST',
            url: (url.query.issuer || 'https://auth.tesla.com/oauth2/v3') + '/token',
            jar: false,
            json: true,
            body: {<commit_msg>auth-services were waiting forever; so login-process did not continue nor throw an error; fixed by trial and error by changing some headers<commit_after>"use strict";

var request = require('request').defaults({
    headers: {
        "Accept" : "*/*"
    },
    gzip: true,
    jar: true
});
var crypto = require('crypto');
var Promise = require('promise');

exports.login = function login(credentials, callback) {
    var codeVerifier = generateCodeVerifier();
    var codeChallenge = generateCodeChallenge(codeVerifier);
    var queryString = {
        audience: '',
        client_id: 'ownerapi',
        code_challenge: codeChallenge,
        code_challenge_method: 'S256',
        locale: 'en',
        prompt: 'login',
        redirect_uri: 'https://auth.tesla.com/void/callback',
        response_type: 'code',
        scope: 'openid email offline_access',
        state: generateCodeChallenge(generateCodeVerifier())
    };
    var transactionId = null;
    var loginHost = null;
    var loginUrl = null;

    req({
        method: 'GET',
        url: 'https://auth-global.tesla.com/oauth2/v3/authorize',
        qs: queryString,
        headers: {
            "sec-fetch-site": "none",
            "sec-fetch-mode": "navigate",
            "sec-fetch-user": "?1",
            "sec-fetch-dest": "document"
        }
    }).then(function (result) {
        // Record the final URL we got redirected to; this is where we will send our credentials
        loginUrl = result.response.request.href;
        loginHost = "https://" + require('url').parse(loginUrl).host;
        var form = {};
        
        var hiddenFormFields = result.body.match(/<input type="hidden" [^>]+>/g);
        hiddenFormFields.forEach(function (field) {
            var name = field.match(/name="([^"]+)"/);
            var value = field.match(/value="([^"]*)"/);
            if (name && value) {
                form[name[1]] = value[1];
            }
        });

        transactionId = form.transaction_id;
        
        form.identity = credentials.identity;
        form.credential = credentials.credential;

        return req({
            method: 'POST',
            url: loginUrl,
            form: form,
            headers: {
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "navigate",
                "sec-fetch-user": "?1",
                "sec-fetch-dest": "document",
                "referer": loginUrl,
                "origin": loginHost
            }
        });
    }).then(function (result) {
        if (result.body.includes('/oauth2/v3/authorize/mfa/verify')) {
            // MFA is required
            if (!credentials.mfaPassCode) {
                throw new Error("MFA passcode required");
            }
        
            return mfaVerify(transactionId, loginHost, loginUrl, credentials.mfaPassCode, credentials.mfaDeviceName);
        }
    
        // No need to handle MFA
        return result;
    }).then(function (result) {
        var location = result.response.headers.location;
        if (!location) {
            throw new Error("Login credentials rejected");
        }

        var url = require('url').parse(location, true);
        if (!url.query || !url.query.code) {
            throw new Error("No authorization code issued; credentials likely incorrect");
        }

        return req({
            method: 'POST',
            url: (url.query.issuer || 'https://auth.tesla.com/oauth2/v3') + '/token',
            jar: false,
            json: true,
            headers: {
                "Accept": "*/*",
                "Content-Type" : "application/json",
                "Connection" : "keep-alive"
            },
            body: {
{'fraction_non_alphanumeric': 0.13946907424875354, 'fraction_numerical': 0.010375960113192292, 'mean_word_length': 1.8958252048380804, 'pattern_counts': {'":': 24, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7336588', 'n_tokens_mistral': 2177, 'n_tokens_neox': 2096, 'n_words': 473}