PageSourceSearch

https://pbx.io/portal/

html pbx.io collected 2026-10-08 11:49:11 UTC 15,623 bytes, 420 lines download raw bytes

1<!DOCTYPE html>
2<html lang=en>
3<head>
4     	
5	
6	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />	<title>
7	Manager Portal	</title>
8	<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
9
10			
11		
11<script type="text/javascript" src="/portal/locale/icu.js"></script>
11
12		
12<script type="text/javascript" src="/portal/locale/translate.js"></script>
12
13		
13<script type="text/javascript" src="/portal/locale/en_us/LC_MESSAGES/i18nJS.js"></script>
13
14		
14<script type="text/javascript">
15		//window.addEventListener('load', function(){
16		if (i18nJSON) _.setTranslation(i18nJSON);//POTENTIAL ERROR: Removed window onload event listener because it was causing problems with validationEngine translations
17		//});
18		</script>
18
19		<link rel="shortcut icon" type="image/x-icon" href="https://pbx.io/ns-api/?object=image&action=read&filename=favicon.gif&server=pbx.io" />
20		<link rel="icon" type="image/x-icon" href="https://pbx.io/ns-api/?object=image&action=read&filename=favicon.gif&server=pbx.io" />
21								<link rel="stylesheet" href="/portal/css/basicCSS.php?version=1766098087&ver=44.4.6 " type="text/css">
22		<link rel="stylesheet" href="/portal/css/portal.php?background=%23212223&primary1=%237f223b&primary2=%23c0919e&bar1=%238c8c8c&bar2=%23cccccc" type="text/css">
23				<link rel="stylesheet" href="/custom/custom.css" type="text/css">
24						
24<script type="text/javascript" src='/portal/js/basicJS.php?version=1766098087&ver=44.4.6 '></script>
24
25		
25<script type="text/javascript">
26		var servertime = '2026-10-08 11:49:11';
27		</script>
27
28
29</head>
30<body>
31		<div class="page-container" style="">
32	<div class="fixed-container">
33			</div>
34	<div id="login-container">
vendor: 72 bytes, lines 34-38
34
35		    <script src='//www.google.com/recaptcha/api.js'></script>
36    
37
38
39<style>
40    #LoginForm {
41        overflow: auto;
42        margin: 0 0 8px;
43    }
44
45    .separator {
46        margin-top: 12px;
47        display: flex;
48        position: relative;
49        margin: 1rem 0;
50        text-align: center;
51        justify-content: space-between;
52        align-items: center;
53        flex: 1
54    }
55
56    .separator__content {
57        margin: 0 3rem
58    }
59
60    .separator::before, .separator::after {
61        flex: 1;
62        content: '';
63        border-bottom: 1px solid #5f6c72
64    }
65
66    .separator--light {
67        font-weight: 700;
68        letter-spacing: 1px;
69        text-transform: uppercase;
70        color: #969ea2;
71        font-size: 1.3rem
72    }
73
74    .separator--light::before, .separator--light::after {
75        border-color: #dadfe2
76    }
77
78    .sso-container {
79        padding: 2px 0 8px;
80        text-align: center;
81    }
82
83    .sso-container:last-of-type {
84        margin-bottom: 20px;
85    }
86
87    #login-group.with-redirect-uri {
88        margin-top: 10px;
89    }
90
91</style>
92
93<div id="login-spinner" class="loading-container relative"
94     style="margin: auto; position: absolute !important;top: 0;left: 0;background: transparent; display: none;">
95    <div class="loading-spinner la-ball-spin-clockwise">
96        <div></div>
97        <div></div>
98        <div></div>
99        <div></div>
100        <div></div>
101        <div></div>
102        <div></div>
103        <div></div>
104    </div>
105</div>
106<div id="login-group" class="">
107    <div id="login-box">
108        <div id="login-logo">
109            
110            <img src="https://pbx.io/ns-api/?object=image&action=read&server=pbx.io&filename=portal_landing.png&server=pbx.io"/>
111        </div>
112
113        <form action="/portal/login/login" id="LoginForm" class="form-stacked" method="post" accept-charset="utf-8"><div style="display:none;"><input type="hidden" name="_method" value="POST" /></div>        <div class='hide'>
114            <input name="data[Login][vendor]" type="text" id="SsoVendor" /><input name="data[Login][id_token]" type="text" id="SsoIdToken" />        </div>
115
116                    <div id="login-fields">
117                <div>
118                    <label for="username">Login Name</label>
119                    <div>
120                        <input name="data[Login][username]" type="text" id="LoginUsername" />                    </div>
121                </div>
122
123                <div>
124                    <label for="password">Password</label>
125                    <div>
126                        <input type="password" name="data[Login][password]" class="hide" id="LoginPassword" />                    </div>
127                                    </div>
128            </div>
129
130            <div id="login-submit" style="padding-bottom: 15px;">
131                <div class="submit"><input class="btn btn-large color-primary" update="#login" complete="hideModalIf(&quot;#login&quot;);" type="submit" value="Log In" /></div>            </div>
132
133            <div id="reset-container" style="margin-bottom: 12px;">
134                                    <div id="reset-links">
135                        <a href="/portal/resets/forgotlogin"
136                           style="padding-right: 7px;">Forgot Login Name</a>|<a
137                                href="/portal/resets/forgotpassword"
138                                style="padding-left: 7px;">Forgot Password</a>
139                    </div>
140                            </div>
141
142            <div id="ssoSeparator" class="separator separator--light" style="display: none">
143                <span class="separator__content">OR</span>
144            </div>
145
146            
147        <div class="sso-container">
148            <div id="google-sso" style="height: 44px; overflow: hidden; display: flex; justify-content: center"></div>
149        </div>
150    
151            
151<script>
152              const aScript = document.createElement('script');
153              aScript.type = 'text/javascript';
154              aScript.src = 'https://accounts.google.com/gsi/client';
155              document.head.appendChild(aScript);
156
157              aScript.onload = () => {
158                $('#ssoSeparator').show();
159
160                window.google.accounts.id.initialize({
161                  client_id: '311082626465-qkkene5d077r6tjociq4sj7bfkdkhfc4.apps.googleusercontent.com',
162                  callback: (res) => {
163                    if (res && res.credential) {
164                      $('#SsoVendor').val('google');
165                      $('#SsoIdToken').val(res.credential);
166                      onSubmit();
167                    }
168                  },
169                });
170
171                window.google.accounts.id.renderButton(
172                  document.getElementById('google-sso'),
173                  {
174                    theme: 'outline',
175                    size: 'large',
176                    shape: 'rectangle',
177                    width: 302,
178                    logo_alignment: 'left',
179                    locale: 'en_us' || 'en_US',
180                  },
181                );
182              };
183            </script>
183
184        
185<style>
186    #appleid-signin {
187        display: none;
188    }
189</style>
190
191        <div class="sso-container">
192            <div id="appleid-btn-custom"  class="ssoLoginBtn btn btn-large">
193                <span class="icon"><img src="/portal/img/apple-logo.png"/></span>
194                <span class="buttonText">
195                    Log in with Apple                </span>
196            </div>
197            <div id="appleid-signin" class="ssoLoginBtn btn btn-large">
198                <span class="icon"><img src="/portal/img/apple-logo.png"/></span>
199                <span class="buttonText">
200                    Log in with Apple                </span>
201            </div>
202        </div>
203    
204            
204<script type="text/javascript" src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>
204
205            
205<script>
206                $('#ssoSeparator').show();
207
208                var redirectURI = window.location.origin + '/portal/login/';
209
210                $(document).ready(function() {
211                    $('#ssoSeparator').show();
212
213                    $('#appleid-btn-custom').click(function() {
214                        window.history.pushState('portal', 'Login', '/portal/login/'); // force base path so url can match allowed redirect urls
215                        document.getElementById("appleid-signin").click();
216                    });
217
218                    AppleID.auth.init({
219                        clientId: 'io.pbx.sso', // 'com.netsapiens.local',
220                        scope: 'name email',
221                        redirectURI: redirectURI,
222                        usePopup: true,
223                    });
224
225                    document.addEventListener('AppleIDSignInOnSuccess', (data) => {
226                        var authCode = data.detail.authorization.code;
227                        var idToken = data.detail.authorization.id_token;
228                        //var parsedToken = parseJwt(idToken);
229                        //var email = parsedToken.email;
230
231                        $('#LoginUsername').val('');
232                        $('#LoginPassword').val('');
233                        $('#SsoVendor').val('apple');
234                        $('#SsoIdToken').val(idToken);
235                        
236                        onSubmit();
237                    });
238
239                    document.addEventListener('AppleIDSignInOnFailure', (error) => {
240                        console.error('AppleIDSignInOnFailure', error)
241                    });
242                });
243
244                function parseJwt(token) {
245                    var base64Url = token.split('.')[1];
246                    var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
247                    var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
248                        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
249                    }).join(''));
250
251                    return JSON.parse(jsonPayload);
252                };
253            </script>
253
254        
255        <div class="sso-container">
256            <div id="officeSigninBtn" class="ssoLoginBtn btn btn-large">
257                <span class="icon"><img src="/portal/img/office-logo.svg"/></span>
258                <span class="buttonText">
259                    Log in with Office 365                </span>
260            </div>
261
262            <div id="officeSigninLoader" style="display: none;">
263                <span class="icon"></span>
264                <span class="buttonText">
265                    Checking Office authorization...
266                </span>
267            </div>
268
269            <div id="officeContinueBtn" class="ssoLoginBtn btn btn-large" style="display: none;">
270                <span class="icon"><img src="/portal/img/google-logo.png"/></span>
271                <span class="buttonText">
272                    Log in with Office                </span>
273            </div>
274
275            <div id="clientError" style="display: none;">
276                Failed to initialize Office SSO application            </div>
277        </div>
278    
279            
279<script src="https://alcdn.msauth.net/lib/1.0.0/js/msal.js"></script>
279
280
281            
281<script>
282                $('#ssoSeparator').show();
283
284                var officeIdToken = '';
285
286                var msalConfig = {
287                    auth: {
288                        clientId: 'c4572491-ec47-48e6-bfc4-693208bc53e2'
289                    },
290                    cache: {
291                        cacheLocation: 'localStorage'
292                    }
293                };
294
295                var authenticationParameters = {
296                    scopes: ["user.read"], // optional Array<string>
297                    prompt: "select_account",
298                };
299
300                //This maybe needs to be on a page load callback?
301                var msalInstance = new Msal.UserAgentApplication(msalConfig);
302
303                $('#officeSigninBtn').click( function() {
304                    var thisPath = window.location.pathname;
305                    window.history.pushState('portal', 'Login', '/portal/msal.php?c=c4572491-ec47-48e6-bfc4-693208bc53e2'); // force base path so url can match allowed redirect urls
306
307                    msalInstance.loginPopup(authenticationParameters)
308                    .then(response => {
309                        msalInstance.acquireTokenSilent(authenticationParameters)
310                        .then(response => {
311                            window.history.pushState('portal', 'Login', thisPath); // revert path after msal roundtrip
312
313                            officeIdToken = response.accessToken;
314
315                            $('#LoginUsername').val('');
316                            $('#LoginPassword').val('');
317                            $('#SsoVendor').val('office');
318                            $('#SsoIdToken').val(officeIdToken);
319
320                            onSubmit();
321                        })
322                        .catch(err => {
323                            console.log('acquireTokenSilent fresh err',err)
324                        });
325                    })
326                    .catch(err => {
327                        console.log('loginPopup err',err)
328                    });
329                });
330            </script>
330
331        
332
333        
334        </form>    </div>
335
336            <div class="new-user-container">
337            <a href="/portal/resets/newuser">Are you a new user?</a>
338        </div>
339    
340    <div class="login-language-container">
341            </div>
342
343    <div id="footer">
344        
345        <p>Copyright &#169; 2017-2019 by PBX.io</p>
346
347                    <p>Manager Portal: Version                 44.4.6 </p>
348            </div><!-- /login-box -->
349</div><!-- /login-group -->
350
351
352<script type="text/javascript">
353    
354    var ns_t = localStorage.getItem('ns_t');
355    var jwt = parseJwt(ns_t);
356
357    if ($.cookie('is_mask') == null && jwt) {
358                  if (localStorage.getItem('jwtAutoLoginTS') == null || parseInt(localStorage.getItem('jwtAutoLoginTS')) < Date.now().getTime() - 30000) {
359            if (jwt.exp > (Date.now().getTime() / 1000)) {
360              $('#login-spinner').show();
361              $('#login-group').hide();
362              var username = jwt.login || jwt.sub;
363              var expires = jwt.exp;
364              localStorage.setItem('jwtAutoLoginTS', Date.now().getTime());
365              window.location.replace("/portal/login/loginwithtoken?iframe=no&refresh_token=" + ns_t + "&username=" + username + "&avoidExpiredRedirect=true");
366            }
367          }
368            }
369
370    function parseJwt(token) {
371      if (token) {
372        var base64Url = token.split('.')[1];
373        var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
374        var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
375          return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
376        }).join(''));
377
378        return JSON.parse(jsonPayload);
379      }
380    };
381</script>
381
382
383<script type="text/javascript">
384  //OMP-1256
385  //When auto-logged out, prevent redirect to controller if logging back in as a different user
386  loginForm = $('.form-stacked');
387  loginURL = loginForm.attr('action');
388
389  if (loginURL.indexOf('page=') !== -1) {
390    pageURL = loginURL;
391    noPageURL = pageURL.replace(/(&?|\?)page=[a-z]*/g, '');
392    usernameInput = $('#LoginUsername');
393    origUsername = "@";
394
395    usernameInput.on("input", function () {
396      newUsername = usernameInput.val();
397      if (newUsername != origUsername) {
398        loginForm.attr('action', noPageURL);
399        //window.history.pushState({},"", noPageURL);
400      } else {
401        loginForm.attr('action', pageURL);
402        //window.history.pushState({},"", pageURL);
403      }
404    });
405  }
406
407  function enableLogin() {
408    $('.submit input').removeAttr("disabled");
409  }
410
411  function onSubmit() {
412    $('form').submit();
413  }
414</script>
414
415	</div>
416	<!-- majority of javascript at bottom so the page displays faster -->
417		</div>
418</body>
419
420</html>

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.