mm-math 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.html +36 -26
- package/package.json +1 -1
package/index.html
CHANGED
|
@@ -522,17 +522,35 @@ document.getElementById('fUser').addEventListener('keydown', e => {
|
|
|
522
522
|
const _onCalc = window.location.hostname === 'calc.moshelab.com';
|
|
523
523
|
const BRIDGE_ORIGIN = 'https://calc.moshelab.com';
|
|
524
524
|
|
|
525
|
-
// Preload invisible auth-bridge iframe
|
|
526
|
-
//
|
|
527
|
-
// the result back. This bypasses Cloudflare's cross-origin fetch restrictions.
|
|
525
|
+
// Preload invisible auth-bridge iframe. The iframe is on calc.moshelab.com so its
|
|
526
|
+
// fetch to /api/login is same-origin — no CORS, no Cloudflare cross-origin checks.
|
|
528
527
|
let _bridge = null;
|
|
528
|
+
let _bridgeReadyResolve = null;
|
|
529
|
+
const _bridgeReady = new Promise(function(resolve) { _bridgeReadyResolve = resolve; });
|
|
530
|
+
|
|
529
531
|
if (!_onCalc) {
|
|
530
532
|
_bridge = document.createElement('iframe');
|
|
531
533
|
_bridge.src = BRIDGE_ORIGIN + '/login-frame.html';
|
|
532
534
|
_bridge.style.cssText = 'display:none;width:0;height:0;border:0;position:absolute;left:-9999px;top:-9999px;';
|
|
533
535
|
_bridge.setAttribute('aria-hidden', 'true');
|
|
534
536
|
document.body.appendChild(_bridge);
|
|
535
|
-
}
|
|
537
|
+
} else {
|
|
538
|
+
// On calc.moshelab.com, bridge isn't used — resolve immediately
|
|
539
|
+
_bridgeReadyResolve();
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Shared message handler — resolves the ready promise and dispatches login results
|
|
543
|
+
const _pendingLogins = {};
|
|
544
|
+
window.addEventListener('message', function(event) {
|
|
545
|
+
if (event.origin !== BRIDGE_ORIGIN) return;
|
|
546
|
+
const d = event.data;
|
|
547
|
+
if (!d) return;
|
|
548
|
+
if (d.type === 'bridge_ready') { _bridgeReadyResolve(); return; }
|
|
549
|
+
if (d.type === 'login_result' && d.nonce && _pendingLogins[d.nonce]) {
|
|
550
|
+
_pendingLogins[d.nonce](d);
|
|
551
|
+
delete _pendingLogins[d.nonce];
|
|
552
|
+
}
|
|
553
|
+
});
|
|
536
554
|
|
|
537
555
|
function _loginDirect(username, password) {
|
|
538
556
|
return fetch('/api/login', {
|
|
@@ -547,28 +565,20 @@ function _loginDirect(username, password) {
|
|
|
547
565
|
}
|
|
548
566
|
|
|
549
567
|
function _loginViaBridge(username, password) {
|
|
550
|
-
return
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
clearTimeout(timer);
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
}
|
|
565
|
-
window.addEventListener('message', handler);
|
|
566
|
-
|
|
567
|
-
if (!_bridge || !_bridge.contentWindow) {
|
|
568
|
-
clearTimeout(timer);
|
|
569
|
-
return reject(new Error('Auth bridge unavailable'));
|
|
570
|
-
}
|
|
571
|
-
_bridge.contentWindow.postMessage({ type: 'login', username, password, nonce }, BRIDGE_ORIGIN);
|
|
568
|
+
return _bridgeReady.then(function() {
|
|
569
|
+
return new Promise(function(resolve, reject) {
|
|
570
|
+
if (!_bridge || !_bridge.contentWindow) {
|
|
571
|
+
return reject(new Error('Auth bridge unavailable'));
|
|
572
|
+
}
|
|
573
|
+
const nonce = Math.random().toString(36).slice(2, 10);
|
|
574
|
+
const timer = setTimeout(function() {
|
|
575
|
+
delete _pendingLogins[nonce];
|
|
576
|
+
reject(new Error('Sign-in timed out. Try again.'));
|
|
577
|
+
}, 15000);
|
|
578
|
+
|
|
579
|
+
_pendingLogins[nonce] = function(d) { clearTimeout(timer); resolve(d); };
|
|
580
|
+
_bridge.contentWindow.postMessage({ type: 'login', username: username, password: password, nonce: nonce }, BRIDGE_ORIGIN);
|
|
581
|
+
});
|
|
572
582
|
});
|
|
573
583
|
}
|
|
574
584
|
|