PageSourceSearch

https://www.theadviser.com.au/media/com_custom/js/membership/login.js?a9f118

js theadviser.com.au collected 2026-09-24 17:34:57 UTC 8,737 bytes, 232 lines download raw bytes

1class MembershipLogin
2{
3    $LOGIN_FORM = $('form[name="membershipLoginForm"]');
4
5    fusionAuthWebAuthnObj = new FusionAuthWebAuthn();
6
7    initialise() {
8        if (window.location.pathname === '/login') {
9            $('body').addClass('theme-bg');
10            $(window).on('scroll', this.loadRocketChat);
11
12            if ($('#system-message-container').children().length > 1) {
13                $('._iDld').toggleClass('hasError');
14            }
15        }
16
17        this.setEventHandlers();
18    }
19
20    loadRocketChat() {
21        setTimeout(() => {
22            const rocketChatHost = 'https://chat.momentummedia.com.au';
23
24            // Start of Rocket.Chat Livechat Script
25            (function(w, d, s, u) {
26                w.RocketChat = function(c) { w.RocketChat._.push(c) }; w.RocketChat._ = []; w.RocketChat.url = u;
27                var h = d.getElementsByTagName(s)[0], j = d.createElement(s);
28                j.async = true; j.src = u + '/rocketchat-livechat.min.js?_=201903270000';
29                h.parentNode.insertBefore(j, h);
30            })(window, document, 'script', `${rocketChatHost}/livechat`);
31
32            RocketChat(function () {
33                this.setDepartment('Memberships');
34                this.setCustomField('site_domain', 'theadviser.com.au');
35
36                this.onServiceOffline((data) => {
37                    document.querySelector('#rocketchat-iframe').contentWindow.postMessage({fn : 'serviceOffline'}, rocketChatHost);
38                });
39            });
40            // End of Rocket.Chat Livechat Script
41        }, 1000);
42
43        $(window).off('scroll', this.loadRocketChat);
44    }
45
46    setEventHandlers() {
47        // Declared to properly access class-level scope.
48        const self = this;
49
50        $('#loginTooltip').on('click', () => {
51            if ($(window).width() < 769) {
52                $('.tooltiptextmobile').fadeToggle();
53            }
54        });
55
56        $('#showPassword').on('click', function() {
57            const $passwordElement = $('input[name="password"]');
58            $passwordElement.attr('type', ($passwordElement.attr('type') === 'password') ? 'text' : 'password');
59            $(this).find('i').toggleClass('fa-eye-slash fa-eye');
60        });
61
62        self.$LOGIN_FORM
63            .on('click', '.btn-submit', function (event) {
64                event.preventDefault();
65                self.hideInlineErrors();
66
67                const loginType = $(this).data('login_type');
68                if (self.validateInputs(loginType) === false) {
69                    return;
70                }
71
72                self.$LOGIN_FORM.data('formLoginType', loginType);
73                self.$LOGIN_FORM.get(0).requestSubmit();
74            })
75            .on('submit', async function (event) {
76                if (
77                    1 === 1
78                    && typeof window.MomentumTurnstileGate !== 'undefined'
79                    && window.MomentumTurnstileGate !== null
80                    && typeof window.MomentumTurnstileGate.shouldWaitForGate === 'function'
81                    && window.MomentumTurnstileGate.shouldWaitForGate(self.$LOGIN_FORM) === true
82                ) {
83                    return;
84                }
85
86                event.preventDefault();
87
88                const loginType  = $(this).data('formLoginType');
89                const $btnSubmit = self.$LOGIN_FORM.find(`.btn-submit[data-login_type="${loginType}"]`);
90                let response     = null;
91
92                try {
93                    self.toggleLoading($btnSubmit);
94
95                    if (loginType === 'fusionauth') {
96                        response = await self.doPasskeyLogin();
97                    } else {
98                        response = await self.doRegularLogin();
99                    }
100
101                    if (response.result === false) {
102                        throw response;
103                    }
104
105                    if (response.hasOwnProperty('paywall_user') === true) {
106                        try {
107                            localStorage.setItem('paywall_user', JSON.stringify(response.paywall_user));
108                        } catch (exception) {
109                            console.error('Error setting paywall_user', exception);
110                        }
111                    }
112
113                    window.location.href = response.redirect;
114                } catch (exception) {
115                    console.error(exception);
116
117                    self.toggleLoading($btnSubmit);
118                    self.toggleMessage(exception);
119                }
120            });
121    }
122
123    async doPasskeyLogin() {
124        try {
125            this.fusionAuthWebAuthnObj.setExtraPayloadData({
126                username : this.$LOGIN_FORM.find('input[name="username"]').val()
127            });
128
129            const publicKeyCredential = await this.fusionAuthWebAuthnObj.startPasskeyAssertion();
130            if (publicKeyCredential.result === false) {
131                return publicKeyCredential;
132            }
133
134            return await this.executeHttpRequest(
135                'membershipLogin',
136                {
137                    captcha_turnstile_response : (
138                        1 === 1
139                        && typeof window.MomentumTurnstileGate !== 'undefined'
140                        && window.MomentumTurnstileGate !== null
141                        && typeof window.MomentumTurnstileGate.getTokenFromForm === 'function'
142                    ) ? window.MomentumTurnstileGate.getTokenFromForm(this.$LOGIN_FORM) : '',
143                    login_type                 : 'fusionauth',
144                    public_key                 : await this.fusionAuthWebAuthnObj.preparePasskeyAssertionCompletionPayload(publicKeyCredential),
145                    return                     : this.$LOGIN_FORM.find('input[name="return"]').val(),
146                    username                   : this.$LOGIN_FORM.find('input[name="username"]').val()
147                }
148            );
149        } catch (error) {
150            throw {
151                result  : false,
152                message : 'An error has been encountered while logging in. Please try again.'
153            };
154        }
155    }
156
157    async doRegularLogin() {
158        const formData = new FormData(this.$LOGIN_FORM.get(0));
159        formData.append('login_type', 'joomla');
160
161        return await this.executeHttpRequest(
162            'membershipLogin',
163            Object.fromEntries(formData)
164        );
165    }
166
167    validateInputs(loginType) {
168        let errorCount = 0;
169
170        if (this.$LOGIN_FORM.find('input[name="username"]').val().trim().length === 0) {
171            this.displayInlineError(this.$LOGIN_FORM.find('input[name="username"]'));
172            errorCount++;
173        }
174
175        if (loginType === 'joomla' && this.$LOGIN_FORM.find('input[name="password"]').val().trim().length === 0) {
176            this.displayInlineError(this.$LOGIN_FORM.find('input[name="password"]'));
177            errorCount++;
178        }
179
180        return errorCount === 0;
181    }
182
183    displayInlineError(elem) {
184        $(elem).parents('._kbtd').find('._6Rpk').addClass('label-error');
185        $(elem).addClass('border-error');
186        $(elem).after('<span class="inline-error">This field is required.</span>');
187    }
188
189    hideInlineErrors() {
190        this.$LOGIN_FORM.find('.no-margin-bottom').removeClass('no-margin-bottom');
191        this.$LOGIN_FORM.find('.label-error').removeClass('label-error');
192        this.$LOGIN_FORM.find('.border-error').removeClass('border-error');
193        this.$LOGIN_FORM.find('.inline-error').remove();
194    }
195
196    toggleLoading($btnSubmit) {
197        this.$LOGIN_FORM.find('.btn-submit').removeAttr('disabled');
198        this.$LOGIN_FORM.find('.message-area').hide();
199
200        $btnSubmit[(($btnSubmit.hasClass('processing') === true) ? 'remove' : 'add') + 'Class']('processing');
201        if ($btnSubmit.hasClass('processing') === true) {
202            this.$LOGIN_FORM.find('.btn-submit').attr('disabled', true);
203        }
204    }
205
206    toggleMessage(response) {
207        this.$LOGIN_FORM
208            .find('.message-area')
209            .html(response.message)
210            .removeClass('text-danger text-success')
211            .addClass('text-' + ((response.result === true) ? 'success' : 'danger'))
212            .css('display', 'inline-block');
213    }
214
215    async executeHttpRequest(endpoint, data) {
216        return await $.ajax({
217            url      : '/?' + $.param({
218                option : 'com_ajax',
219                plugin : endpoint,
220                format : 'json'
221            }),
222            data     : data,
223            method   : 'POST',
224            dataType : 'json'
225        })
226        .then((response) => response.data[response.data.length - 1]);
227    }
228}
229
230$(function() {
231    (new MembershipLogin()).initialise();
232});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.