Skip to content

Commit af72817

Browse files
authored
fix(webclient): Remove restrictive cert validation
1 parent 2658881 commit af72817

3 files changed

Lines changed: 26 additions & 149 deletions

File tree

deps/cloudxr/webxr_client/helpers/utils.ts

Lines changed: 10 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -362,45 +362,24 @@ export function isLocalServer(hostname: string): boolean {
362362
* @param certAcceptanceLink - Container element for the certificate link
363363
* @param certLink - Anchor element for the certificate URL
364364
* @param location - Optional location object (defaults to window.location)
365-
* @returns Certificate link controller with cleanup and verification helpers
365+
* @returns Cleanup function that removes listeners created by this helper
366366
*/
367-
export interface CertStatusInfo {
368-
accepted: boolean;
369-
required: boolean;
370-
verified: boolean;
371-
}
372-
373-
export interface CertLinkController {
374-
/** Removes listeners created by setupCertificateAcceptanceLink(). */
375-
(): void;
376-
/** Forces a cert check for the current effective URL and updates status. */
377-
verifyNow: () => Promise<CertStatusInfo>;
378-
/** Waits for an in-flight cert check started elsewhere (if any). */
379-
waitForPendingVerification: () => Promise<CertStatusInfo>;
380-
}
381-
382367
export function setupCertificateAcceptanceLink(
383368
serverIpInput: HTMLInputElement,
384369
portInput: HTMLInputElement,
385370
proxyUrlInput: HTMLInputElement,
386371
certAcceptanceLink: HTMLElement,
387372
certLink: HTMLAnchorElement,
388-
onStatusChange?: (status: CertStatusInfo) => void,
389373
location: Location = window.location,
390374
fetchFn: typeof fetch = globalThis.fetch
391-
): CertLinkController {
375+
): () => void {
392376
let abortController: AbortController | null = null;
393377
let accepted = false;
394378
let certRequired = false;
395-
let verified = false;
396379
let activeCertUrl: string | null = null;
397-
let pendingVerification: Promise<CertStatusInfo> | null = null;
380+
let pendingVerification: Promise<void> | null = null;
398381
let pendingVerificationUrl: string | null = null;
399382

400-
function notifyStatus(): void {
401-
onStatusChange?.({ accepted, required: certRequired, verified });
402-
}
403-
404383
function markAccepted(url: string): void {
405384
if (url !== activeCertUrl) {
406385
return;
@@ -409,35 +388,17 @@ export function setupCertificateAcceptanceLink(
409388
console.warn('[CloudXR] Certificate accepted for %s', url);
410389
}
411390
accepted = true;
412-
verified = true;
413-
certAcceptanceLink.classList.remove('cert-unverified');
414391
certAcceptanceLink.classList.add('cert-accepted');
415392
certLink.textContent = `Certificate accepted (${url})`;
416-
notifyStatus();
417393
}
418394

419395
function markUnverified(url: string): void {
420396
if (url !== activeCertUrl) {
421397
return;
422398
}
423399
accepted = false;
424-
verified = false;
425-
certAcceptanceLink.classList.remove('cert-accepted');
426-
certAcceptanceLink.classList.add('cert-unverified');
427-
certLink.textContent = `Click ${url} to accept cert`;
428-
notifyStatus();
429-
}
430-
431-
function markPending(url: string): void {
432-
if (url !== activeCertUrl) {
433-
return;
434-
}
435-
accepted = false;
436-
verified = true;
437-
certAcceptanceLink.classList.remove('cert-unverified');
438400
certAcceptanceLink.classList.remove('cert-accepted');
439401
certLink.textContent = `Click ${url} to accept cert`;
440-
notifyStatus();
441402
}
442403

443404
async function checkCert(url: string): Promise<void> {
@@ -459,7 +420,7 @@ export function setupCertificateAcceptanceLink(
459420
if (err instanceof DOMException && err.name === 'AbortError') {
460421
return;
461422
}
462-
markPending(url);
423+
markUnverified(url);
463424
console.warn(
464425
'[CloudXR] Certificate not yet accepted — cert polling errors for %s are expected.',
465426
url
@@ -471,7 +432,7 @@ export function setupCertificateAcceptanceLink(
471432
* Updates the certificate acceptance link based on current configuration
472433
* Shows link only when in HTTPS mode without proxy (direct WSS)
473434
*/
474-
const updateCertLink = (runCertCheck: boolean) => {
435+
const updateCertLink = () => {
475436
const isHttps = location.protocol === 'https:';
476437
const hasProxy = proxyUrlInput.value.trim().length > 0;
477438
const portValue = parseInt(portInput.value, 10);
@@ -490,20 +451,13 @@ export function setupCertificateAcceptanceLink(
490451
activeCertUrl = url;
491452
certAcceptanceLink.style.display = 'block';
492453
certLink.href = url;
493-
// Keep blue "unverified" until a probe result is known.
494454
markUnverified(url);
495-
if (runCertCheck) {
496-
void checkCert(url);
497-
}
498455
} else {
499456
activeCertUrl = null;
500457
accepted = false;
501-
verified = false;
502458
if (abortController) abortController.abort();
503-
certAcceptanceLink.classList.remove('cert-unverified');
504459
certAcceptanceLink.classList.remove('cert-accepted');
505460
certAcceptanceLink.style.display = 'none';
506-
notifyStatus();
507461
}
508462
};
509463

@@ -514,13 +468,13 @@ export function setupCertificateAcceptanceLink(
514468
};
515469

516470
const onInput = () => {
517-
updateCertLink(false);
471+
updateCertLink();
518472
};
519473
const onCommittedChange = () => {
520474
void startVerification();
521475
};
522476
const onProxyCommittedChange = () => {
523-
updateCertLink(false);
477+
updateCertLink();
524478
if (certRequired && activeCertUrl) {
525479
void startVerification();
526480
}
@@ -541,29 +495,16 @@ export function setupCertificateAcceptanceLink(
541495
// Run initial cert state after localStorage restoration.
542496
void startVerification();
543497

544-
async function verifyNow(): Promise<CertStatusInfo> {
545-
updateCertLink(false);
546-
if (certRequired && activeCertUrl) {
547-
await checkCert(activeCertUrl);
548-
} else {
549-
notifyStatus();
550-
}
551-
return { accepted, required: certRequired, verified };
552-
}
553-
554-
function startVerification(): Promise<CertStatusInfo> {
555-
updateCertLink(false);
498+
function startVerification(): Promise<void> {
499+
updateCertLink();
556500
const currentUrl = certRequired ? activeCertUrl : null;
557501
if (pendingVerification && pendingVerificationUrl === currentUrl) {
558502
return pendingVerification;
559503
}
560504
const run = (async () => {
561505
if (currentUrl) {
562506
await checkCert(currentUrl);
563-
} else {
564-
notifyStatus();
565507
}
566-
return { accepted, required: certRequired, verified };
567508
})();
568509
pendingVerification = run;
569510
pendingVerificationUrl = currentUrl;
@@ -575,18 +516,7 @@ export function setupCertificateAcceptanceLink(
575516
});
576517
}
577518

578-
function waitForPendingVerification(): Promise<CertStatusInfo> {
579-
if (pendingVerification) {
580-
return pendingVerification;
581-
}
582-
if (certRequired && !verified) {
583-
return startVerification();
584-
}
585-
return Promise.resolve({ accepted, required: certRequired, verified });
586-
}
587-
588-
// Return callable controller with cleanup and verification helpers.
589-
const cleanup = () => {
519+
return () => {
590520
serverIpInput.removeEventListener('input', onInput);
591521
portInput.removeEventListener('input', onInput);
592522
proxyUrlInput.removeEventListener('input', onInput);
@@ -599,9 +529,4 @@ export function setupCertificateAcceptanceLink(
599529
window.removeEventListener('focus', onFocus);
600530
if (abortController) abortController.abort();
601531
};
602-
const controller = Object.assign(cleanup, {
603-
verifyNow,
604-
waitForPendingVerification,
605-
}) as CertLinkController;
606-
return controller;
607532
}

deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ import {
4848
getResolutionFromInputs,
4949
setSelectValueIfAvailable,
5050
setupCertificateAcceptanceLink,
51-
type CertLinkController,
52-
type CertStatusInfo,
5351
} from '@helpers/utils';
5452
import {
5553
getGridValidationError,
@@ -162,9 +160,8 @@ export class CloudXR2DUI {
162160
event: string;
163161
handler: EventListener;
164162
}> = [];
165-
/** Certificate link controller (cleanup + verification helpers) */
166-
private certLinkController: CertLinkController | null = null;
167-
private certStatus: CertStatusInfo = { accepted: true, required: false, verified: true };
163+
/** Certificate link cleanup function */
164+
private certLinkCleanup: (() => void) | null = null;
168165

169166
/**
170167
* Creates a new CloudXR2DUI instance
@@ -444,16 +441,12 @@ export class CloudXR2DUI {
444441
});
445442

446443
// Set up certificate acceptance link and store cleanup function
447-
this.certLinkController = setupCertificateAcceptanceLink(
444+
this.certLinkCleanup = setupCertificateAcceptanceLink(
448445
this.serverIpInput,
449446
this.portInput,
450447
this.proxyUrlInput,
451448
this.certAcceptanceLink,
452-
this.certLink,
453-
(status: CertStatusInfo) => {
454-
this.certStatus = status;
455-
this.updateConnectButtonState();
456-
}
449+
this.certLink
457450
);
458451
}
459452

@@ -522,12 +515,7 @@ export class CloudXR2DUI {
522515
reprojectionGridCols,
523516
reprojectionGridRows
524517
);
525-
const certPending =
526-
this.certStatus.required && this.certStatus.verified === true && !this.certStatus.accepted;
527-
const certMessage = certPending
528-
? 'Accept the certificate using the link below before connecting.'
529-
: '';
530-
const combinedConnectMessage = [connectMessage, gridConnectMessage, certMessage]
518+
const combinedConnectMessage = [connectMessage, gridConnectMessage]
531519
.filter(Boolean)
532520
.join('\n');
533521
if (combinedConnectMessage) {
@@ -539,7 +527,7 @@ export class CloudXR2DUI {
539527
}
540528
// Only update button when idle (don't override "CONNECT (starting...)" or "CONNECT (XR session active)")
541529
if (this.startButton && this.startButton.innerHTML === 'CONNECT') {
542-
const shouldEnable = !resolutionError && !gridError && !certPending;
530+
const shouldEnable = !resolutionError && !gridError;
543531
this.setStartButtonState(!shouldEnable, 'CONNECT');
544532
}
545533
}
@@ -762,24 +750,6 @@ export class CloudXR2DUI {
762750
// Create new handler
763751
this.handleConnectClick = async () => {
764752
this.updateConnectButtonState();
765-
if (this.certStatus.required && !this.certStatus.accepted && this.certLinkController) {
766-
this.setStartButtonState(true, 'CONNECT (waiting for certificate check...)');
767-
let certWaitTimeoutId: ReturnType<typeof setTimeout> | null = null;
768-
try {
769-
await Promise.race([
770-
this.certLinkController.verifyNow(),
771-
new Promise<void>(resolve => {
772-
certWaitTimeoutId = setTimeout(resolve, 500);
773-
}),
774-
]);
775-
} finally {
776-
if (certWaitTimeoutId !== null) {
777-
clearTimeout(certWaitTimeoutId);
778-
}
779-
}
780-
this.setStartButtonState(false, 'CONNECT');
781-
this.updateConnectButtonState();
782-
}
783753
if (this.startButton?.disabled) {
784754
this.updateConnectButtonState();
785755
return;
@@ -858,9 +828,9 @@ export class CloudXR2DUI {
858828
}
859829

860830
// Clean up certificate acceptance link listeners
861-
if (this.certLinkController) {
862-
this.certLinkController();
863-
this.certLinkController = null;
831+
if (this.certLinkCleanup) {
832+
this.certLinkCleanup();
833+
this.certLinkCleanup = null;
864834
}
865835
}
866836
}

deps/cloudxr/webxr_client/src/index.html

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,8 @@
449449

450450
/* Certificate Acceptance Link */
451451
.cert-acceptance-link {
452-
background: #fdecea;
453-
border: 2px solid #f44336;
452+
background: #e3f2fd;
453+
border: 2px solid #2196f3;
454454
border-radius: 4px;
455455
padding: 12px 16px;
456456
margin: 8px 0 16px 0;
@@ -461,18 +461,19 @@
461461
.cert-acceptance-link .cert-icon {
462462
display: inline-block;
463463
margin-right: 8px;
464+
color: #1565c0;
464465
}
465466

466467
.cert-acceptance-link a {
467-
color: #c62828;
468+
color: #1565c0;
468469
text-decoration: none;
469470
font-weight: 600;
470-
border-bottom: 1px solid #c62828;
471+
border-bottom: 1px solid #1565c0;
471472
}
472473

473474
.cert-acceptance-link a:hover {
474-
color: #b71c1c;
475-
border-bottom-color: #b71c1c;
475+
color: #0d47a1;
476+
border-bottom-color: #0d47a1;
476477
}
477478

478479
.cert-acceptance-link.cert-accepted {
@@ -494,25 +495,6 @@
494495
border-bottom-color: #1b5e20;
495496
}
496497

497-
.cert-acceptance-link.cert-unverified {
498-
background: #e3f2fd;
499-
border-color: #2196f3;
500-
}
501-
502-
.cert-acceptance-link.cert-unverified .cert-icon {
503-
color: #1565c0;
504-
}
505-
506-
.cert-acceptance-link.cert-unverified a {
507-
color: #1565c0;
508-
border-bottom-color: #1565c0;
509-
}
510-
511-
.cert-acceptance-link.cert-unverified a:hover {
512-
color: #0d47a1;
513-
border-bottom-color: #0d47a1;
514-
}
515-
516498
/* Hide 2D UI when in XR mode */
517499
body.xr-mode #2d-ui {
518500
display: none;

0 commit comments

Comments
 (0)