PageSourceSearch

https://xgm.guru/public/mjs/79df25d1/components/login.js

js xgm.guru collected 2026-09-24 10:34:11 UTC 11,371 bytes, 287 lines download raw bytes

1import {Modal} from '../ui/modal.js'
2import {firemsg} from '../ui/firemsg.js'
3import {Compatible} from '../vendor/compatible.js'
4import {globalProgress, L} from '../ui/utils.js'
5import {Cookie} from '../ui/cookie.js'
6
7const error = {error: 'Неизвестная ошибка'}
8
9const __fp = async (le) => {
10    const set = val => {
11        const _cs = ['\x66\x70', '\x67\x6d', '\x2e\x78', '\x76']
12        const els = document.querySelectorAll(_cs[2] + _cs[1] + _cs[0] + _cs[3])
13        els.forEach(el => el.value = val)
14    }
15    if(le) {
16        set('')
17        return
18    }
19    set('i')
20    set('t')
21    const u = await Compatible.load()
22    set('l')
23    const r = await u.get()
24    set('r')
25    const h = r.components
26    const l = document.createElement('\x63\x61\x6e\x76\x61\x73')
27    const lc = l && l.getContext('\x77\x65\x62\x67\x6c')
28    const ld = lc && lc.getExtension('\x57\x45\x42\x47\x4c\x5f\x64\x65\x62\x75\x67\x5f\x72\x65\x6e\x64\x65\x72\x65\x72\x5f\x69\x6e\x66\x6f')
29    h.gpu = {value: lc && ld && lc.getParameter(ld['\x55\x4e\x4d\x41\x53\x4b\x45\x44\x5f\x52\x45\x4e\x44\x45\x52\x45\x52\x5f\x57\x45\x42\x47\x4c']) || null}
30    l.remove()
31    set(btoa(JSON.stringify(h, null, ' ')))
32}
33
34/** @type string */
35let _fpvError
36
37const _dblclickDebugHandler = () => {
38    const element = document.createElement('a')
39    const text = _fpvError || document.querySelector('.xgmfpv').value
40    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))
41    element.setAttribute('download', 'xgm-debug.txt')
42
43    element.style.display = 'none'
44    document.body.appendChild(element)
45
46    element.click()
47
48    document.body.removeChild(element)
49}
50
51/**
52 * @param {HTMLButtonElement} button
53 * @returns {Promise<void>}
54 */
55const _fp = async button => {
56    _fpvError = undefined
57    button.disabled = true
58    try {
59        await __fp()
60    } catch (e) {
61        _fpvError = e.toString()
62    }
63    button.disabled = false
64}
65
66/** @type {HTMLFormElement} */
67const loginForm = document.getElementById('login-form')
68if (loginForm) {
69    const debugLabel = loginForm.querySelector('[for="login-password"]')
70    debugLabel && debugLabel.addEventListener('dblclick', _dblclickDebugHandler)
71
72    const submit = loginForm.querySelector('[type=submit]')
73    submit.disabled = true
74
75    document.body.addEventListener('ui.modal-open', e => {
76        if (e.detail.name !== 'login') return
77        _fp(submit)
78        Modal.open(async () => {
79            // noinspection JSUnresolvedVariable
80            if(e.target.dataset && e.target.dataset.loginPresetUsername) {
81                loginForm.elements.username.value = e.target.dataset.loginPresetUsername
82                loginForm.elements.password.focus()
83            } else {
84                loginForm.elements.username.focus()
85            }
86            return loginForm
87        })
88    })
89
90    loginForm.addEventListener('submit', async e => {
91        e.preventDefault()
92
93        const formData = new FormData()
94        formData.set('do', 'login')
95        formData.set('ajax', '1')
96        // noinspection JSUnresolvedVariable
97        formData.set('username', loginForm.elements.username.value)
98        // noinspection JSUnresolvedVariable
99        formData.set('password', loginForm.elements.password.value)
100        formData.set('fromRoute', location.pathname)
101
102        const request = await fetch('/authentication/login', {method: 'post', body: formData})
103        const response = await request.json().catch(() => error)
104        if (response === 'OK') {
105            loginForm.submit()
106            Modal.close()
107            globalProgress(false)
108            return
109        }
110        firemsg(`Ошибка! ${response.error}`)
111    })
112}
113
114/** @type {HTMLFormElement} */
115const registerForm = document.getElementById('register-form')
116if (registerForm) {
117    const debugLabel = registerForm.querySelector('[for="registration-password"]')
118    debugLabel && debugLabel.addEventListener('dblclick', _dblclickDebugHandler)
119    const pleaseWaitEl = registerForm.querySelector(".please-wait")
120    const submitTick = /** @type {HTMLElement} */ registerForm.querySelector('.please-wait-tick')
121    const submitIcon = /** @type {HTMLElement} */ registerForm.querySelector('.please-wait-icon')
122
123    const submit = registerForm.querySelector('[type=submit]')
124
125    const acceptLegal = registerForm.querySelector('.registration-accept-legal')
126    let forceDisable = true
127    const refreshRegisterButton = () => {
128        /** @type {HTMLButtonElement|null} */
129        let registerButton = registerForm.querySelector('.register-button')
130        if (acceptLegal.checked && !forceDisable) {
131            registerButton.disabled = false
132            registerButton.classList.add('btn-primary')
133            registerButton.classList.remove('disabled')
134        } else {
135            registerButton.disabled = true
136            registerButton.classList.remove('btn-primary')
137            registerButton.classList.add('disabled')
138        }
139    }
140    acceptLegal.addEventListener('change', refreshRegisterButton)
141
142    // noinspection JSUnresolvedVariable
143    /** @type HTMLInputElement */
144    const username = registerForm.elements.username
145
146    document.body.addEventListener('ui.modal-open', e => {
147        if (e.detail.name !== 'register') return
148
149        let it = 30
150        let t = it
151        let i = null
152        __fp(0x364111)
153
154        pleaseWaitEl.style.display = 'block'
155        submitIcon.style.setProperty('--fa-animation-duration', (t / 20) + 's')
156        i = setInterval(() => {
157            if (t <= 1) {
158                clearInterval(i)
159                pleaseWaitEl.style.display = 'none'
160                forceDisable = false
161                _fp(submit)
162                refreshRegisterButton()
163                return
164            }
165            t--
166            submitTick.innerHTML = t.toString()
167            submitIcon.classList.add('fa-spin', 'fa-spin-reverse')
168            if (t % 5 === 0) {
169                submitIcon.style.setProperty('--fa-animation-duration', (t / 20) + 's')
170            }
171            refreshRegisterButton()
172        }, 1000)
173        
174        Modal.open(async () => {
175            username.focus()
176            return registerForm
177        })
178    })
179
180    username.addEventListener('focusout', async e => {
181        /** @type {HTMLElement} */
182        const div = e.target.nextElementSibling
183
184        if (username.value.length < 4) {
185            div.innerHTML = '<span class="text-error">' + L('Имя пользователя должно быть длиннее', 'The username must be longer', '用户名必须更长') + '</span>'
186            return
187        }
188
189        const formData = new FormData()
190        formData.set('username', username.value)
191
192        const request = await fetch('/registration/check-identity', {method: 'post', body: formData})
193        const response = await request.json().catch(() => error)
194
195        if (response.error) {
196            firemsg(response.error)
197            return
198        }
199
200        if (response === 1) {
201            div.innerHTML = '<span class="text-success">' + L('Это имя доступно', 'This username is available', '此用户名可用') + '</span>'
202            return
203        }
204
205        div.innerHTML = '<span class="text-warning">' + L('Это имя недоступно', 'This username is not available', '此用户名不可用') + '</span>'
206    })
207
208    // noinspection JSUnresolvedVariable
209    /** @type HTMLInputElement */
210    const email = registerForm.elements.email
211    email.addEventListener('input', e => {
212        /** @type {HTMLElement} */
213        const div = e.target.nextElementSibling
214        const reg = /^[._A-Za-z\d-]+@[.a-z\d-]+(\.[a-z]{2,4})$/
215        if (!reg.exec(email.value)) {
216            div.innerHTML = '<span class="text-error">' + L('Неверный формат', 'Wrong format', '格式错误') + '</span>'
217            return
218        }
219        div.innerHTML = '<span class="text-success">' + L('ОК', 'OK', '好的') + '</span>'
220    })
221
222
223    // noinspection JSUnresolvedVariable
224    /** @type HTMLInputElement */
225    const password = registerForm.elements.password
226    const passwordDiv = password.nextElementSibling
227
228    // noinspection JSUnresolvedVariable
229    /** @type HTMLInputElement */
230    const confirmpassword = registerForm.elements.confirmpassword
231    const confirmpasswordDiv = confirmpassword.nextElementSibling
232
233    /** @param e Event */
234    const passwordHandler = e => {
235        if (e.target === password) {
236            passwordDiv.innerHTML = password.value.length < 8
237                ? '<span class="text-warning">' + L('Слабый пароль', 'Weak password', '密码强度低') + '</span>'
238                : '<span class="text-success">' + L('Нормальный пароль', 'The password is ok', '密码没问题') + '</span>'
239        }
240
241        confirmpasswordDiv.innerHTML = password.value === confirmpassword.value
242            ? '<span class="text-success">' + L('Пароли совпадают', 'Passwords match', '密码匹配') + '</span>'
243            : '<span class="text-error">' + L('Пароли не совпадают', 'Passwords do not match', '密码不匹配') + '</span>'
244    }
245
246    password.addEventListener('input', passwordHandler)
247    confirmpassword.addEventListener('input', passwordHandler)
248}
249
250if (document.querySelector('.integration-vk-auth')) setTimeout(__fp, 260)
251
252/**
253 * @event CustomEvent#security.authentication
254 * @event CustomEvent#security.registration
255 * @event CustomEvent#security.logout
256 * @event CustomEvent#security.change-identity
257 * @event CustomEvent#security.change-credentials
258 * @event CustomEvent#security.reset-credentials
259 */
260const securityAction = Cookie.getItem('securityAction')
261if(securityAction) {
262    const securitySource = Cookie.getItem('securitySource')
263    Cookie.removeItem('securityAction')
264    Cookie.removeItem('securitySource')
265
266    setTimeout(() => { // wait for the subscribers in the same thread
267        if(securityAction == 'authentication') {
268            document.body.dispatchEvent(new CustomEvent("security.authentication", { bubbles: true, detail: { source: securitySource } }))
269        } else if(securityAction == 'registration') {
270            document.body.dispatchEvent(new CustomEvent("security.registration", { bubbles: true, detail: { source: securitySource } }))
271        } else if(securityAction == 'logout') {
272            document.body.dispatchEvent(new CustomEvent("security.logout", { bubbles: true, detail: { 
273                source: securitySource,
274                identity: Cookie.getItem('securityIdentity'),
275                id: Cookie.getItem('securityId')
276            } }))
277            Cookie.removeItem('securityIdentity')
278            Cookie.removeItem('securityId')
279        } else if(securityAction == 'change-identity') {
280            document.body.dispatchEvent(new CustomEvent("security.change-identity", { bubbles: true, detail: { source: securitySource } }))
281        } else if(securityAction == 'change-credentials') {
282            document.body.dispatchEvent(new CustomEvent("security.change-credentials", { bubbles: true, detail: { source: securitySource } }))
283        } else if(securityAction == 'reset-credentials') {
284            document.body.dispatchEvent(new CustomEvent("security.reset-credentials", { bubbles: true, detail: { source: securitySource } }))
285        }
286    }, 0)
287}

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.