UNPKG

homebridge-adt-pulse

Version:
1,131 lines 59.9 kB
import axios from 'axios';
import { wrapper } from 'axios-cookiejar-support';
import { JSDOM } from 'jsdom';
import _ from 'lodash';
import { isErrorLike, serializeError } from 'serialize-error';
import { CookieJar } from 'tough-cookie';
import { detectGlobalDebugParser, detectGlobalPortalVersion } from './detect.js';
import { generateFakeDynatracePCHeaderValue, generateFakeLoginFingerprint } from './fake.js';
import { objectKeyClientType, objectKeyLocale, objectKeyLogin, objectKeyPreAuthToken, objectKeySat, requestPathAccessSignIn, requestPathAccessSignInEXxPartnerAdt, requestPathMfaMfaSignInWorkflowChallenge, requestPathNgaServRunRraProxyHrefRestAdtUiClientMultiFactorAuthAddTrustedDeviceSatXx, requestPathNgaServRunRraProxyHrefRestAdtUiClientMultiFactorAuthRequestOtpForRegisteredPropertySatXx, requestPathNgaServRunRraProxyHrefRestAdtUiClientMultiFactorAuthValidateOtpSatXx, requestPathNgaServRunRraProxyHrefRestIcontrolUiClientMultiFactorAuthSatXx, requestPathNgaServRunRraProxyOnlyClientMultiFactorAuthExcludeSatXxHrefRestAdtUiUpdatesSatXx, requestPathSummarySummary, requestPathSystemSystem, textOneTimePasscode, } from './regex.js';
import { multiFactorAuth, otpResponse } from './schema.js';
import { debugLog, fetchErrorMessage, findNullKeys, generateHash, parseMultiFactorMethods, parseMultiFactorTrustedDevices, parseSensorsTable, stackTracer, } from './utility.js';
export class ADTPulseAuth {
    #connection;
    #credentials;
    #internal;
    #session;
    constructor(config, internalConfig) {
        this.#connection = {
            subdomain: config.subdomain,
        };
        this.#credentials = {
            fingerprint: generateFakeLoginFingerprint(),
            password: config.password,
            username: config.username,
        };
        this.#internal = {
            baseUrl: internalConfig.baseUrl ?? `https://${this.#connection.subdomain}.adtpulse.com`,
            debug: internalConfig.debug ?? false,
            logger: internalConfig.logger ?? null,
            reportedHashes: [],
        };
        this.#session = {
            httpClient: wrapper(axios.create({
                jar: new CookieJar(),
                validateStatus: () => true,
            })),
            mfa: {
                clientType: null,
                locale: null,
                login: null,
                preAuthToken: null,
                satCode: null,
                token: null,
                trustedDevices: [],
                verificationMethods: [],
            },
            portalVersion: null,
            status: 'logged-out',
        };
    }
    async getVerificationMethods() {
        let errorObject;
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', `Attempting to retrieve verification methods from "${this.#internal.baseUrl}"`);
        }
        try {
            const sessions = {};
            if (this.#session.status === 'complete'
                || this.#session.status === 'not-required') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', 'Already retrieved verification methods');
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: true,
                    info: {
                        methods: this.#session.mfa.verificationMethods,
                        status: this.#session.status,
                    },
                };
            }
            sessions.axiosIndex = await this.#session.httpClient.get(`${this.#internal.baseUrl}/`, this.getRequestConfig());
            if (sessions.axiosIndex.status >= 400) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', `The remote server responded with a HTTP ${sessions.axiosIndex.status} status code`);
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: `The remote server responded with a HTTP ${sessions.axiosIndex.status} status code`,
                    },
                };
            }
            if (typeof sessions.axiosIndex?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosIndexRequestPath = sessions.axiosIndex.request.path;
            const axiosIndexRequestPathValid = requestPathAccessSignIn.test(axiosIndexRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', `Request path ➜ ${axiosIndexRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', `Request path valid ➜ ${axiosIndexRequestPathValid}`);
            }
            if (!axiosIndexRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', `"${axiosIndexRequestPath} is not the sign-in page`);
                }
                this.handleLoginFailure(axiosIndexRequestPath, sessions.axiosIndex);
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: `"${axiosIndexRequestPath} is not the sign-in page`,
                    },
                };
            }
            const loginForm = new URLSearchParams();
            loginForm.append('usernameForm', this.#credentials.username);
            loginForm.append('passwordForm', this.#credentials.password);
            loginForm.append('sun', 'yes');
            loginForm.append('networkid', '');
            loginForm.append('fingerprint', this.#credentials.fingerprint);
            this.#session.portalVersion = axiosIndexRequestPath.replace(requestPathAccessSignIn, '$2');
            await this.newInformationDispatcher('portal-version', { version: this.#session.portalVersion });
            sessions.axiosSignIn = await this.#session.httpClient.post(`${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/access/signin.jsp?e=ns&partner=adt`, loginForm, this.getRequestConfig({
                headers: {
                    'Cache-Control': 'max-age=0',
                    'Content-Type': 'application/x-www-form-urlencoded',
                    Origin: this.#internal.baseUrl,
                    Referer: `${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/access/signin.jsp?e=ns&partner=adt`,
                    'Sec-Fetch-Site': 'same-origin',
                },
            }));
            if (sessions.axiosSignIn.status >= 400) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', `The remote server responded with a HTTP ${sessions.axiosSignIn.status} status code`);
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: `The remote server responded with a HTTP ${sessions.axiosSignIn.status} status code`,
                    },
                };
            }
            if (typeof sessions.axiosSignIn?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosSignInRequestPath = sessions.axiosSignIn.request.path;
            const axiosSignInRequestPathValid = requestPathMfaMfaSignInWorkflowChallenge.test(axiosSignInRequestPath) || requestPathSummarySummary.test(axiosSignInRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', `Request path ➜ ${axiosSignInRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', `Request path valid ➜ ${axiosSignInRequestPathValid}`);
            }
            if (requestPathSummarySummary.test(axiosSignInRequestPath)) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', `Verification methods not required from "${this.#internal.baseUrl}"`);
                }
                this.#session.status = 'not-required';
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: true,
                    info: {
                        methods: this.#session.mfa.verificationMethods,
                        status: this.#session.status,
                    },
                };
            }
            if (requestPathAccessSignIn.test(axiosSignInRequestPath) || requestPathAccessSignInEXxPartnerAdt.test(axiosSignInRequestPath)) {
                const errorMessage = fetchErrorMessage(sessions.axiosSignIn);
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', errorMessage ?? 'Unknown error');
                }
                this.#session.status = 'logged-out';
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: errorMessage ?? 'Unknown error',
                    },
                };
            }
            if (!axiosSignInRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', `"${axiosSignInRequestPath}" is not the workflow challenge page`);
                }
                this.handleLoginFailure(axiosSignInRequestPath, sessions.axiosSignIn);
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: `"${axiosSignInRequestPath}" is not the workflow challenge page`,
                    },
                };
            }
            if (typeof sessions.axiosSignIn.data !== 'string') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', 'The response body of the workflow challenge page is not of type "string"');
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: 'The response body of the workflow challenge page is not of type "string"',
                    },
                };
            }
            const matchClientType = sessions.axiosSignIn.data.match(objectKeyClientType);
            const matchLocale = sessions.axiosSignIn.data.match(objectKeyLocale);
            const matchLogin = sessions.axiosSignIn.data.match(objectKeyLogin);
            const matchPreAuthToken = sessions.axiosSignIn.data.match(objectKeyPreAuthToken);
            const matchSatCode = sessions.axiosSignIn.data.match(objectKeySat);
            this.#session.mfa.clientType = (matchClientType !== null && matchClientType.length >= 2) ? matchClientType[1] : null;
            this.#session.mfa.locale = (matchLocale !== null && matchLocale.length >= 2) ? matchLocale[1] : null;
            this.#session.mfa.login = (matchLogin !== null && matchLogin.length >= 2) ? matchLogin[1] : null;
            this.#session.mfa.preAuthToken = (matchPreAuthToken !== null && matchPreAuthToken.length >= 2) ? matchPreAuthToken[1] : null;
            this.#session.mfa.satCode = (matchSatCode !== null && matchSatCode.length >= 2) ? matchSatCode[1] : null;
            if (this.#session.mfa.clientType === null
                || this.#session.mfa.locale === null
                || this.#session.mfa.login === null
                || this.#session.mfa.preAuthToken === null
                || this.#session.mfa.satCode === null) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', 'Failed to retrieve required MFA details from the workflow challenge page');
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: 'Failed to retrieve required MFA details from the workflow challenge page',
                    },
                };
            }
            sessions.axiosMethods = await this.#session.httpClient.get(`${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/nga/serv/RunRRAProxy?href=rest/icontrol/ui/client/multiFactorAuth&sat=${this.#session.mfa.satCode}`, this.getRequestConfig({
                headers: {
                    Accept: 'application/json',
                    'Content-Type': undefined,
                    Referer: `${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/mfa/mfaSignIn.jsp?workflow=challenge`,
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Site': 'same-origin',
                    'Sec-Fetch-User': undefined,
                    'Upgrade-Insecure-Requests': undefined,
                    'X-clientType': this.#session.mfa.clientType,
                    'X-format': 'json',
                    'X-locale': this.#session.mfa.locale,
                    'X-login': this.#session.mfa.login,
                    'X-preAuthToken': this.#session.mfa.preAuthToken,
                    'X-version': '7.0',
                    'x-dtpc': generateFakeDynatracePCHeaderValue('multi-factor'),
                },
            }));
            if (sessions.axiosMethods.status >= 400) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', `The remote server responded with a HTTP ${sessions.axiosMethods.status} status code`);
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: `The remote server responded with a HTTP ${sessions.axiosMethods.status} status code`,
                    },
                };
            }
            if (typeof sessions.axiosMethods?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosMethodsRequestPath = sessions.axiosMethods.request.path;
            const axiosMethodsRequestPathValid = requestPathNgaServRunRraProxyHrefRestIcontrolUiClientMultiFactorAuthSatXx.test(axiosMethodsRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', `Request path ➜ ${axiosMethodsRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'info', `Request path valid ➜ ${axiosMethodsRequestPathValid}`);
            }
            if (!axiosMethodsRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', `"${axiosMethodsRequestPath}" is not the MFA auth page`);
                }
                this.handleLoginFailure(axiosMethodsRequestPath, sessions.axiosMethods);
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: `"${axiosMethodsRequestPath}" is not the MFA auth page`,
                    },
                };
            }
            const parsedMethods = multiFactorAuth.safeParse(sessions.axiosMethods.data);
            if (!parsedMethods.success) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', 'The response body of the MFA auth page is invalid');
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: 'The response body of the MFA auth page is invalid',
                    },
                };
            }
            const parsedMultiFactorMethods = parseMultiFactorMethods(parsedMethods.data);
            if (parsedMultiFactorMethods.length === 0) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', 'Failed to retrieve verification methods');
                }
                return {
                    action: 'GET_VERIFICATION_METHODS',
                    success: false,
                    info: {
                        message: 'Failed to retrieve verification methods',
                    },
                };
            }
            this.#session.mfa.verificationMethods = parsedMultiFactorMethods;
            this.#session.status = 'complete';
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'success', `Successfully retrieved verification methods from "${this.#internal.baseUrl}"`);
            }
            return {
                action: 'GET_VERIFICATION_METHODS',
                success: true,
                info: {
                    methods: parsedMultiFactorMethods,
                    status: this.#session.status,
                },
            };
        }
        catch (error) {
            errorObject = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error'));
        }
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getVerificationMethods()', 'error', 'Method encountered an error during execution');
            stackTracer('serialize-error', errorObject);
        }
        return {
            action: 'GET_VERIFICATION_METHODS',
            success: false,
            info: {
                error: errorObject,
            },
        };
    }
    async requestCode(methodId) {
        let errorObject;
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'info', `Attempting to request a code using the "${methodId}" method at "${this.#internal.baseUrl}"`);
        }
        if (this.#session.mfa.verificationMethods.find((device) => device.id === methodId) === undefined) {
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'error', `The "${methodId}" verification method does not exist. Did you run the "getVerificationMethods()" yet?`);
            }
            return {
                action: 'REQUEST_CODE',
                success: false,
                info: {
                    message: `The "${methodId}" verification method does not exist. Did you run the "getVerificationMethods()" yet?`,
                },
            };
        }
        try {
            const sessions = {};
            const requestCodeForm = new URLSearchParams();
            requestCodeForm.append('id', methodId);
            sessions.axiosRequestCode = await this.#session.httpClient.post(`${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/nga/serv/RunRRAProxy?href=rest/adt/ui/client/multiFactorAuth/requestOtpForRegisteredProperty&sat=${this.#session.mfa.satCode}`, requestCodeForm, this.getRequestConfig({
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                    Origin: this.#internal.baseUrl,
                    Referer: `${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/mfa/mfaSignIn.jsp?workflow=challenge`,
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Site': 'same-origin',
                    'Sec-Fetch-User': undefined,
                    'Upgrade-Insecure-Requests': undefined,
                    'X-clientType': this.#session.mfa.clientType,
                    'X-format': 'json',
                    'X-locale': this.#session.mfa.locale,
                    'X-login': this.#session.mfa.login,
                    'X-preAuthToken': this.#session.mfa.preAuthToken,
                    'X-version': '7.0',
                    'x-dtpc': generateFakeDynatracePCHeaderValue('multi-factor'),
                },
            }));
            if (typeof sessions.axiosRequestCode?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'REQUEST_CODE',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosRequestCodeRequestPath = sessions.axiosRequestCode.request.path;
            const axiosRequestCodeRequestPathValid = requestPathNgaServRunRraProxyHrefRestAdtUiClientMultiFactorAuthRequestOtpForRegisteredPropertySatXx.test(axiosRequestCodeRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'info', `Request path ➜ ${axiosRequestCodeRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'info', `Request path valid ➜ ${axiosRequestCodeRequestPathValid}`);
            }
            if (!axiosRequestCodeRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'error', `"${axiosRequestCodeRequestPath}" is not the request code page`);
                }
                this.handleLoginFailure(axiosRequestCodeRequestPath, sessions.axiosRequestCode);
                return {
                    action: 'REQUEST_CODE',
                    success: false,
                    info: {
                        message: `"${axiosRequestCodeRequestPath}" is not the request code page`,
                    },
                };
            }
            const parsedRequestCode = otpResponse.safeParse(sessions.axiosRequestCode.data);
            if (!parsedRequestCode.success) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'error', 'The response body of the request code page is invalid');
                }
                return {
                    action: 'REQUEST_CODE',
                    success: false,
                    info: {
                        message: 'The response body of the request code page is invalid',
                    },
                };
            }
            if (!parsedRequestCode.data.detail.includes('OK')) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'error', `Unable to get a verification code ➜ "${parsedRequestCode.data.detail}"`);
                }
                return {
                    action: 'REQUEST_CODE',
                    success: false,
                    info: {
                        message: `Unable to get a verification code ➜ "${parsedRequestCode.data.detail}"`,
                    },
                };
            }
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'success', `Successfully requested a code for "${methodId}" at "${this.#internal.baseUrl}"`);
            }
            return {
                action: 'REQUEST_CODE',
                success: true,
                info: null,
            };
        }
        catch (error) {
            errorObject = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error'));
        }
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.requestCode()', 'error', 'Method encountered an error during execution');
            stackTracer('serialize-error', errorObject);
        }
        return {
            action: 'REQUEST_CODE',
            success: false,
            info: {
                error: errorObject,
            },
        };
    }
    async validateCode(otpCode) {
        let errorObject;
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'info', `Attempting to validate verification code at "${this.#internal.baseUrl}"`);
        }
        if (!textOneTimePasscode.test(otpCode)) {
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'error', `"${otpCode}" is an invalid verification code format`);
            }
            return {
                action: 'VALIDATE_CODE',
                success: false,
                info: {
                    message: `"${otpCode}" is an invalid verification code format`,
                },
            };
        }
        try {
            const sessions = {};
            const validateCodeForm = new URLSearchParams();
            validateCodeForm.append('otp', otpCode);
            sessions.axiosValidateCode = await this.#session.httpClient.post(`${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/nga/serv/RunRRAProxy?href=rest/adt/ui/client/multiFactorAuth/validateOtp&sat=${this.#session.mfa.satCode}`, validateCodeForm, this.getRequestConfig({
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                    Origin: this.#internal.baseUrl,
                    Referer: `${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/mfa/mfaSignIn.jsp?workflow=challenge`,
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Site': 'same-origin',
                    'Sec-Fetch-User': undefined,
                    'Upgrade-Insecure-Requests': undefined,
                    'X-clientType': this.#session.mfa.clientType,
                    'X-format': 'json',
                    'X-locale': this.#session.mfa.locale,
                    'X-login': this.#session.mfa.login,
                    'X-preAuthToken': this.#session.mfa.preAuthToken,
                    'X-version': '7.0',
                    'x-dtpc': generateFakeDynatracePCHeaderValue('multi-factor'),
                },
            }));
            if (typeof sessions.axiosValidateCode?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'VALIDATE_CODE',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosValidateCodeRequestPath = sessions.axiosValidateCode.request.path;
            const axiosValidateCodeRequestPathValid = requestPathNgaServRunRraProxyHrefRestAdtUiClientMultiFactorAuthValidateOtpSatXx.test(axiosValidateCodeRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'info', `Request path ➜ ${axiosValidateCodeRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'info', `Request path valid ➜ ${axiosValidateCodeRequestPathValid}`);
            }
            if (!axiosValidateCodeRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'error', `"${axiosValidateCodeRequestPath}" is not the validate code page`);
                }
                this.handleLoginFailure(axiosValidateCodeRequestPath, sessions.axiosValidateCode);
                return {
                    action: 'VALIDATE_CODE',
                    success: false,
                    info: {
                        message: `"${axiosValidateCodeRequestPath}" is not the validate code page`,
                    },
                };
            }
            if (typeof sessions.axiosValidateCode.data === 'string'
                && sessions.axiosValidateCode.data === '') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'error', 'Already passed verification');
                }
                return {
                    action: 'VALIDATE_CODE',
                    success: true,
                    info: null,
                };
            }
            const parsedValidateCode = otpResponse.safeParse(sessions.axiosValidateCode.data);
            if (!parsedValidateCode.success) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'error', 'The response body of the validate code page is invalid');
                }
                return {
                    action: 'VALIDATE_CODE',
                    success: false,
                    info: {
                        message: 'The response body of the validate code page is invalid',
                    },
                };
            }
            if (!parsedValidateCode.data.detail.startsWith('u=')) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'error', 'The verification code submitted is either invalidated or expired');
                }
                return {
                    action: 'VALIDATE_CODE',
                    success: false,
                    info: {
                        message: 'The verification code submitted is either invalidated or expired',
                    },
                };
            }
            this.#session.mfa.token = parsedValidateCode.data.detail;
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'success', `Successfully validated verification code at "${this.#internal.baseUrl}"`);
            }
            return {
                action: 'VALIDATE_CODE',
                success: true,
                info: null,
            };
        }
        catch (error) {
            errorObject = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error'));
        }
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.validateCode()', 'error', 'Method encountered an error during execution');
            stackTracer('serialize-error', errorObject);
        }
        return {
            action: 'VALIDATE_CODE',
            success: false,
            info: {
                error: errorObject,
            },
        };
    }
    async getTrustedDevices() {
        let errorObject;
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getTrustedDevices()', 'info', `Attempting to retrieve trusted devices at "${this.#internal.baseUrl}"`);
        }
        try {
            const sessions = {};
            sessions.axiosDevicePoll = await this.#session.httpClient.get(`${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/nga/serv/RunRRAProxy?only=client.multiFactorAuth&exclude=&sat=${this.#session.mfa.satCode}&href=rest/adt/ui/updates&sat=${this.#session.mfa.satCode}&`, this.getRequestConfig({
                headers: {
                    Accept: 'application/json',
                    Referer: `${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/mfa/mfaSignIn.jsp?workflow=challenge`,
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Site': 'same-origin',
                    'Sec-Fetch-User': undefined,
                    'Upgrade-Insecure-Requests': undefined,
                    'X-clientType': this.#session.mfa.clientType,
                    'X-format': 'json',
                    'X-locale': this.#session.mfa.locale,
                    'X-login': this.#session.mfa.login,
                    'X-token': this.#session.mfa.token,
                    'X-version': '7.0',
                    'x-dtpc': generateFakeDynatracePCHeaderValue('multi-factor'),
                },
            }));
            if (typeof sessions.axiosDevicePoll?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getTrustedDevices()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'GET_TRUSTED_DEVICES',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosDevicePollRequestPath = sessions.axiosDevicePoll.request.path;
            const axiosDevicePollRequestPathValid = requestPathNgaServRunRraProxyOnlyClientMultiFactorAuthExcludeSatXxHrefRestAdtUiUpdatesSatXx.test(axiosDevicePollRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getTrustedDevices()', 'info', `Request path ➜ ${axiosDevicePollRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getTrustedDevices()', 'info', `Request path valid ➜ ${axiosDevicePollRequestPathValid}`);
            }
            if (!axiosDevicePollRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getTrustedDevices()', 'error', `"${axiosDevicePollRequestPath}" is not the device polling page`);
                }
                this.handleLoginFailure(axiosDevicePollRequestPath, sessions.axiosDevicePoll);
                return {
                    action: 'GET_TRUSTED_DEVICES',
                    success: false,
                    info: {
                        message: `"${axiosDevicePollRequestPath}" is not the device polling page`,
                    },
                };
            }
            const parsedDevicePoll = multiFactorAuth.safeParse(_.get(sessions.axiosDevicePoll.data, ['update', 0, 'data', 'client', 'multiFactorAuth']));
            if (!parsedDevicePoll.success) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getTrustedDevices()', 'error', 'The response body of the device polling page is invalid');
                }
                return {
                    action: 'GET_TRUSTED_DEVICES',
                    success: false,
                    info: {
                        message: 'The response body of the device polling page is invalid',
                    },
                };
            }
            const parsedTrustedDevices = parseMultiFactorTrustedDevices(parsedDevicePoll.data);
            this.#session.mfa.trustedDevices = parsedTrustedDevices;
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getTrustedDevices()', 'success', `Successfully retrieved trusted devices at "${this.#internal.baseUrl}"`);
            }
            return {
                action: 'GET_TRUSTED_DEVICES',
                success: true,
                info: {
                    trustedDevices: parsedTrustedDevices,
                },
            };
        }
        catch (error) {
            errorObject = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error'));
        }
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getTrustedDevices()', 'error', 'Method encountered an error during execution');
            stackTracer('serialize-error', errorObject);
        }
        return {
            action: 'GET_TRUSTED_DEVICES',
            success: false,
            info: {
                error: errorObject,
            },
        };
    }
    async addTrustedDevice(deviceName) {
        let errorObject;
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'info', `Attempting to add trusted device at "${this.#internal.baseUrl}"`);
        }
        if (this.#session.mfa.trustedDevices.find((trustedDevice) => trustedDevice.name === encodeURIComponent(deviceName)) !== undefined) {
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'error', 'The name for the trusted device already exists');
            }
            return {
                action: 'ADD_TRUSTED_DEVICE',
                success: false,
                info: {
                    message: 'The name for the trusted device already exists',
                },
            };
        }
        if (deviceName.length < 1 || deviceName.length > 100) {
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'error', 'The name for the trusted device must be between 1 to 100 characters');
            }
            return {
                action: 'ADD_TRUSTED_DEVICE',
                success: false,
                info: {
                    message: 'The name for the trusted device must be between 1 to 100 characters',
                },
            };
        }
        try {
            const sessions = {};
            const trustedDeviceForm = new URLSearchParams();
            trustedDeviceForm.append('name', encodeURIComponent(deviceName));
            sessions.axiosAddDevice = await this.#session.httpClient.post(`${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/nga/serv/RunRRAProxy?href=rest/adt/ui/client/multiFactorAuth/addTrustedDevice&sat=${this.#session.mfa.satCode}`, trustedDeviceForm, this.getRequestConfig({
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                    Origin: this.#internal.baseUrl,
                    Referer: `${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/mfa/mfaSignIn.jsp?workflow=challenge`,
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Site': 'same-origin',
                    'Sec-Fetch-User': undefined,
                    'Upgrade-Insecure-Requests': undefined,
                    'X-clientType': this.#session.mfa.clientType,
                    'X-format': 'json',
                    'X-locale': this.#session.mfa.locale,
                    'X-login': this.#session.mfa.login,
                    'X-token': this.#session.mfa.token,
                    'X-version': '7.0',
                    'x-dtpc': generateFakeDynatracePCHeaderValue('multi-factor'),
                },
            }));
            if (typeof sessions.axiosAddDevice?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'ADD_TRUSTED_DEVICE',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosAddDeviceRequestPath = sessions.axiosAddDevice.request.path;
            const axiosAddDeviceRequestPathValid = requestPathNgaServRunRraProxyHrefRestAdtUiClientMultiFactorAuthAddTrustedDeviceSatXx.test(axiosAddDeviceRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'info', `Request path ➜ ${axiosAddDeviceRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'info', `Request path valid ➜ ${axiosAddDeviceRequestPathValid}`);
            }
            if (!axiosAddDeviceRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'error', `"${axiosAddDeviceRequestPath}" is not the add trusted device page`);
                }
                this.handleLoginFailure(axiosAddDeviceRequestPath, sessions.axiosAddDevice);
                return {
                    action: 'ADD_TRUSTED_DEVICE',
                    success: false,
                    info: {
                        message: `"${axiosAddDeviceRequestPath}" is not the add trusted device page`,
                    },
                };
            }
            const parsedValidateCode = otpResponse.safeParse(sessions.axiosAddDevice.data);
            if (!parsedValidateCode.success) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'error', 'The response body of the add trusted device page is invalid');
                }
                return {
                    action: 'ADD_TRUSTED_DEVICE',
                    success: false,
                    info: {
                        message: 'The response body of the add trusted device page is invalid',
                    },
                };
            }
            if (!parsedValidateCode.data.detail.includes('OK')) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'error', `The trusted device could not be added ➜ "${parsedValidateCode.data.detail}"`);
                }
                return {
                    action: 'ADD_TRUSTED_DEVICE',
                    success: false,
                    info: {
                        message: `The trusted device could not be added ➜ "${parsedValidateCode.data.detail}"`,
                    },
                };
            }
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'success', `Successfully added trusted device at "${this.#internal.baseUrl}"`);
            }
            return {
                action: 'ADD_TRUSTED_DEVICE',
                success: true,
                info: null,
            };
        }
        catch (error) {
            errorObject = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error'));
        }
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.addTrustedDevice()', 'error', 'Method encountered an error during execution');
            stackTracer('serialize-error', errorObject);
        }
        return {
            action: 'ADD_TRUSTED_DEVICE',
            success: false,
            info: {
                error: errorObject,
            },
        };
    }
    async completeSignIn() {
        let errorObject;
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.completeSignIn()', 'info', `Attempting to complete sign in at "${this.#internal.baseUrl}"`);
        }
        try {
            const sessions = {};
            sessions.axiosPostSignIn = await this.#session.httpClient.get(`${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/access/PostSigninProcessServ`, this.getRequestConfig({
                headers: {
                    Referer: `${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/mfa/mfaSignIn.jsp?workflow=challenge`,
                    'Sec-Fetch-Site': 'same-origin',
                },
            }));
            if (sessions.axiosPostSignIn.status >= 400) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.completeSignIn()', 'error', `The remote server responded with a HTTP ${sessions.axiosPostSignIn.status} status code`);
                }
                return {
                    action: 'COMPLETE_SIGN_IN',
                    success: false,
                    info: {
                        message: `The remote server responded with a HTTP ${sessions.axiosPostSignIn.status} status code`,
                    },
                };
            }
            if (typeof sessions.axiosPostSignIn?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.completeSignIn()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'COMPLETE_SIGN_IN',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosPostSignInRequestPath = sessions.axiosPostSignIn.request.path;
            const axiosPostSignInRequestPathValid = requestPathSummarySummary.test(axiosPostSignInRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.completeSignIn()', 'info', `Request path ➜ ${axiosPostSignInRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.completeSignIn()', 'info', `Request path valid ➜ ${axiosPostSignInRequestPathValid}`);
            }
            if (!axiosPostSignInRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.completeSignIn()', 'error', `"${axiosPostSignInRequestPath}" is not the summary page`);
                }
                this.handleLoginFailure(axiosPostSignInRequestPath, sessions.axiosPostSignIn);
                return {
                    action: 'COMPLETE_SIGN_IN',
                    success: false,
                    info: {
                        message: `"${axiosPostSignInRequestPath}" is not the summary page`,
                    },
                };
            }
            this.#session.mfa = {
                clientType: null,
                locale: null,
                login: null,
                preAuthToken: null,
                satCode: null,
                token: null,
                trustedDevices: [],
                verificationMethods: [],
            };
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.completeSignIn()', 'success', `Successfully completed sign in at "${this.#internal.baseUrl}"`);
            }
            return {
                action: 'COMPLETE_SIGN_IN',
                success: true,
                info: null,
            };
        }
        catch (error) {
            errorObject = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error'));
        }
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.completeSignIn()', 'error', 'Method encountered an error during execution');
            stackTracer('serialize-error', errorObject);
        }
        return {
            action: 'COMPLETE_SIGN_IN',
            success: false,
            info: {
                error: errorObject,
            },
        };
    }
    async getSensors() {
        let errorObject;
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'info', `Attempting to retrieve sensors from "${this.#internal.baseUrl}"`);
        }
        try {
            const sessions = {};
            sessions.axiosSystem = await this.#session.httpClient.get(`${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/system/system.jsp`, this.getRequestConfig({
                headers: {
                    Referer: `${this.#internal.baseUrl}/myhome/${this.#session.portalVersion}/summary/summary.jsp`,
                    'Sec-Fetch-Site': 'same-origin',
                },
            }));
            if (sessions.axiosSystem.status >= 400) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'error', `The remote server responded with a HTTP ${sessions.axiosSystem.status} status code`);
                }
                return {
                    action: 'GET_SENSORS',
                    success: false,
                    info: {
                        message: `The remote server responded with a HTTP ${sessions.axiosSystem.status} status code`,
                    },
                };
            }
            if (typeof sessions.axiosSystem?.request === 'undefined') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'error', 'The HTTP client responded without the "request" object');
                }
                return {
                    action: 'GET_SENSORS',
                    success: false,
                    info: {
                        message: 'The HTTP client responded without the "request" object',
                    },
                };
            }
            const axiosSystemRequestPath = sessions.axiosSystem.request.path;
            const axiosSystemRequestPathValid = requestPathSystemSystem.test(axiosSystemRequestPath);
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'info', `Request path ➜ ${axiosSystemRequestPath}`);
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'info', `Request path valid ➜ ${axiosSystemRequestPathValid}`);
            }
            if (!axiosSystemRequestPathValid) {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'error', `"${axiosSystemRequestPath}" is not the system page`);
                }
                this.handleLoginFailure(axiosSystemRequestPath, sessions.axiosSystem);
                return {
                    action: 'GET_SENSORS',
                    success: false,
                    info: {
                        message: `"${axiosSystemRequestPath}" is not the system page`,
                    },
                };
            }
            if (typeof sessions.axiosSystem.data !== 'string') {
                if (this.#internal.debug) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'error', 'The response body of the system page is not of type "string"');
                }
                return {
                    action: 'GET_SENSORS',
                    success: false,
                    info: {
                        message: 'The response body of the system page is not of type "string"',
                    },
                };
            }
            sessions.jsdomSystem = new JSDOM(sessions.axiosSystem.data, {
                url: sessions.axiosSystem.config.url,
                referrer: sessions.axiosSystem.config.headers.Referer,
                contentType: 'text/html',
                pretendToBeVisual: true,
            });
            const jsdomSystemSensorsTable = sessions.jsdomSystem.window.document.querySelectorAll('#systemContentList tr[class^=\'p_row\'] tr.p_listRow');
            const parsedSensorsConfigTable = parseSensorsTable('sensors-config', jsdomSystemSensorsTable);
            await this.newInformationDispatcher('debug-parser', {
                method: 'generateSensorsConfig',
                response: parsedSensorsConfigTable,
                rawHtml: sessions.axiosSystem.data,
            });
            if (this.#internal.debug) {
                debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'success', `Successfully retrieved sensors from "${this.#internal.baseUrl}"`);
            }
            return {
                action: 'GET_SENSORS',
                success: true,
                info: {
                    sensors: parsedSensorsConfigTable,
                },
            };
        }
        catch (error) {
            errorObject = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error'));
        }
        if (this.#internal.debug) {
            debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.getSensors()', 'error', 'Method encountered an error during execution');
            stackTracer('serialize-error', errorObject);
        }
        return {
            action: 'GET_SENSORS',
            success: false,
            info: {
                error: errorObject,
            },
        };
    }
    getFingerprint() {
        return this.#credentials.fingerprint;
    }
    resetSession() {
        this.#session = {
            httpClient: wrapper(axios.create({
                jar: new CookieJar(),
                validateStatus: () => true,
            })),
            mfa: {
                clientType: null,
                locale: null,
                login: null,
                preAuthToken: null,
                satCode: null,
                token: null,
                trustedDevices: [],
                verificationMethods: [],
            },
            portalVersion: null,
            status: 'logged-out',
        };
    }
    async newInformationDispatcher(type, data) {
        const dataHash = generateHash(data);
        if (this.#internal.reportedHashes.find((reportedHash) => dataHash === reportedHash) === undefined) {
            let detectedNew = false;
            switch (type) {
                case 'debug-parser':
                    detectedNew = await detectGlobalDebugParser(data, null, this.#internal.debug);
                    break;
                case 'portal-version':
                    detectedNew = await detectGlobalPortalVersion(data, null, this.#internal.debug);
                    break;
                default:
                    break;
            }
            if (detectedNew) {
                this.#internal.reportedHashes.push(dataHash);
            }
        }
    }
    getRequestConfig(extraConfig) {
        const defaultConfig = {
            family: 4,
            headers: {
                Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
                'Accept-Encoding': 'gzip, deflate, br, zstd',
                'Accept-Language': 'en-US,en;q=0.9',
                'Cache-Control': 'no-cache',
                Connection: 'keep-alive',
                Host: `${this.#connection.subdomain}.adtpulse.com`,
                Pragma: 'no-cache',
                'Sec-Fetch-Dest': 'document',
                'Sec-Fetch-Mode': 'navigate',
                'Sec-Fetch-Site': 'none',
                'Sec-Fetch-User': '?1',
                'Upgrade-Insecure-Requests': '1',
                'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
                'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
                'sec-ch-ua-mobile': '?0',
                'sec-ch-ua-platform': '"macOS"',
            },
            timeout: 15000,
        };
        if (extraConfig === undefined) {
            return defaultConfig;
        }
        return _.merge(_.omit(defaultConfig, findNullKeys(extraConfig)), _.omit(extraConfig, findNullKeys(extraConfig)));
    }
    handleLoginFailure(requestPath, session) {
        if (requestPath === null) {
            return;
        }
        if (requestPathAccessSignIn.test(requestPath) || requestPathAccessSignInEXxPartnerAdt.test(requestPath)) {
            if (this.#internal.debug) {
                const errorMessage = fetchErrorMessage(session);
                if (requestPathAccessSignIn.test(requestPath) || requestPathAccessSignInEXxPartnerAdt.test(requestPath)) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.handleLoginFailure()', 'error', 'Either the username or password is incorrect, fingerprint format is invalid, or was signed out due to inactivity');
                }
                if (requestPathSummarySummary.test(requestPath)) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.handleLoginFailure()', 'error', 'The generated fingerprint is already validated');
                }
                if (errorMessage !== null) {
                    debugLog(this.#internal.logger, 'auth.ts / ADTPulseAuth.handleLoginFailure()', 'warn', `Portal message ➜ "${errorMessage}"`);
                }
            }
            this.resetSession();
        }
    }
}
//# sourceMappingURL=auth.js.map