mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
fix: scope public domain to single binding and return single port check
Accept internalPort in AddPublicDomainParams to target a specific
binding. Disable the domain on all other bindings. Return a single
CheckPortRes instead of Vec. Revert multi-port UI to singular port
display from 0f8a66b35.
This commit is contained in:
@@ -161,6 +161,7 @@ pub fn address_api<C: Context, Kind: HostApiKind>()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Parser, TS)]
|
#[derive(Deserialize, Serialize, Parser, TS)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct AddPublicDomainParams {
|
pub struct AddPublicDomainParams {
|
||||||
#[arg(help = "help.arg.fqdn")]
|
#[arg(help = "help.arg.fqdn")]
|
||||||
@@ -169,6 +170,8 @@ pub struct AddPublicDomainParams {
|
|||||||
pub acme: Option<AcmeProvider>,
|
pub acme: Option<AcmeProvider>,
|
||||||
#[arg(help = "help.arg.gateway-id")]
|
#[arg(help = "help.arg.gateway-id")]
|
||||||
pub gateway: GatewayId,
|
pub gateway: GatewayId,
|
||||||
|
#[arg(help = "help.arg.internal-port")]
|
||||||
|
pub internal_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
|
||||||
@@ -177,7 +180,7 @@ pub struct AddPublicDomainParams {
|
|||||||
pub struct AddPublicDomainRes {
|
pub struct AddPublicDomainRes {
|
||||||
#[ts(type = "string | null")]
|
#[ts(type = "string | null")]
|
||||||
pub dns: Option<Ipv4Addr>,
|
pub dns: Option<Ipv4Addr>,
|
||||||
pub port: Vec<CheckPortRes>,
|
pub port: CheckPortRes,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_public_domain<Kind: HostApiKind>(
|
pub async fn add_public_domain<Kind: HostApiKind>(
|
||||||
@@ -186,10 +189,11 @@ pub async fn add_public_domain<Kind: HostApiKind>(
|
|||||||
fqdn,
|
fqdn,
|
||||||
acme,
|
acme,
|
||||||
gateway,
|
gateway,
|
||||||
|
internal_port,
|
||||||
}: AddPublicDomainParams,
|
}: AddPublicDomainParams,
|
||||||
inheritance: Kind::Inheritance,
|
inheritance: Kind::Inheritance,
|
||||||
) -> Result<AddPublicDomainRes, Error> {
|
) -> Result<AddPublicDomainRes, Error> {
|
||||||
let ports = ctx
|
let ext_port = ctx
|
||||||
.db
|
.db
|
||||||
.mutate(|db| {
|
.mutate(|db| {
|
||||||
if let Some(acme) = &acme {
|
if let Some(acme) = &acme {
|
||||||
@@ -224,14 +228,46 @@ pub async fn add_public_domain<Kind: HostApiKind>(
|
|||||||
let available_ports = db.as_private().as_available_ports().de()?;
|
let available_ports = db.as_private().as_available_ports().de()?;
|
||||||
let host = Kind::host_for(&inheritance, db)?;
|
let host = Kind::host_for(&inheritance, db)?;
|
||||||
host.update_addresses(&hostname, &gateways, &available_ports)?;
|
host.update_addresses(&hostname, &gateways, &available_ports)?;
|
||||||
|
|
||||||
|
// Find the external port for the target binding
|
||||||
let bindings = host.as_bindings().de()?;
|
let bindings = host.as_bindings().de()?;
|
||||||
let ports: BTreeSet<u16> = bindings
|
let target_bind = bindings
|
||||||
.values()
|
.get(&internal_port)
|
||||||
.flat_map(|b| &b.addresses.available)
|
.ok_or_else(|| Error::new(eyre!("binding not found for internal port {internal_port}"), ErrorKind::NotFound))?;
|
||||||
.filter(|a| a.public && a.hostname == fqdn)
|
let ext_port = target_bind
|
||||||
.filter_map(|a| a.port)
|
.addresses
|
||||||
.collect();
|
.available
|
||||||
Ok(ports)
|
.iter()
|
||||||
|
.find(|a| a.public && a.hostname == fqdn)
|
||||||
|
.and_then(|a| a.port)
|
||||||
|
.ok_or_else(|| Error::new(eyre!("no public address found for {fqdn} on port {internal_port}"), ErrorKind::NotFound))?;
|
||||||
|
|
||||||
|
// Disable the domain on all other bindings
|
||||||
|
host.as_bindings_mut().mutate(|b| {
|
||||||
|
for (&port, bind) in b.iter_mut() {
|
||||||
|
if port == internal_port {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let has_addr = bind
|
||||||
|
.addresses
|
||||||
|
.available
|
||||||
|
.iter()
|
||||||
|
.any(|a| a.public && a.hostname == fqdn);
|
||||||
|
if has_addr {
|
||||||
|
let other_ext = bind
|
||||||
|
.addresses
|
||||||
|
.available
|
||||||
|
.iter()
|
||||||
|
.find(|a| a.public && a.hostname == fqdn)
|
||||||
|
.and_then(|a| a.port)
|
||||||
|
.unwrap_or(ext_port);
|
||||||
|
bind.addresses.disabled.insert((fqdn.clone(), other_ext));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(ext_port)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.result?;
|
.result?;
|
||||||
@@ -239,7 +275,7 @@ pub async fn add_public_domain<Kind: HostApiKind>(
|
|||||||
let ctx2 = ctx.clone();
|
let ctx2 = ctx.clone();
|
||||||
let fqdn2 = fqdn.clone();
|
let fqdn2 = fqdn.clone();
|
||||||
|
|
||||||
let (dns_result, port_results) = tokio::join!(
|
let (dns_result, port_result) = tokio::join!(
|
||||||
async {
|
async {
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
crate::net::dns::query_dns(ctx2, crate::net::dns::QueryDnsParams { fqdn: fqdn2 })
|
crate::net::dns::query_dns(ctx2, crate::net::dns::QueryDnsParams { fqdn: fqdn2 })
|
||||||
@@ -247,20 +283,18 @@ pub async fn add_public_domain<Kind: HostApiKind>(
|
|||||||
.await
|
.await
|
||||||
.with_kind(ErrorKind::Unknown)?
|
.with_kind(ErrorKind::Unknown)?
|
||||||
},
|
},
|
||||||
futures::future::join_all(ports.into_iter().map(|port| {
|
check_port(
|
||||||
check_port(
|
ctx.clone(),
|
||||||
ctx.clone(),
|
CheckPortParams {
|
||||||
CheckPortParams {
|
port: ext_port,
|
||||||
port,
|
gateway: gateway.clone(),
|
||||||
gateway: gateway.clone(),
|
},
|
||||||
},
|
)
|
||||||
)
|
|
||||||
}))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(AddPublicDomainRes {
|
Ok(AddPublicDomainRes {
|
||||||
dns: dns_result?,
|
dns: dns_result?,
|
||||||
port: port_results.into_iter().collect::<Result<Vec<_>, _>>()?,
|
port: port_result?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ export type AddPublicDomainParams = {
|
|||||||
fqdn: string
|
fqdn: string
|
||||||
acme: AcmeProvider | null
|
acme: AcmeProvider | null
|
||||||
gateway: GatewayId
|
gateway: GatewayId
|
||||||
|
internalPort: number
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
import type { CheckPortRes } from './CheckPortRes'
|
import type { CheckPortRes } from './CheckPortRes'
|
||||||
|
|
||||||
export type AddPublicDomainRes = {
|
export type AddPublicDomainRes = { dns: string | null; port: CheckPortRes }
|
||||||
dns: string | null
|
|
||||||
port: Array<CheckPortRes>
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ export default {
|
|||||||
741: 'In Ihrem Domain-Registrar für',
|
741: 'In Ihrem Domain-Registrar für',
|
||||||
742: 'diesen DNS-Eintrag erstellen',
|
742: 'diesen DNS-Eintrag erstellen',
|
||||||
743: 'In Ihrem Gateway',
|
743: 'In Ihrem Gateway',
|
||||||
744: 'diese Portweiterleitungsregeln erstellen',
|
744: 'diese Portweiterleitungsregel erstellen',
|
||||||
745: 'Externer Port',
|
745: 'Externer Port',
|
||||||
747: 'Interner Port',
|
747: 'Interner Port',
|
||||||
749: 'DNS-Server-Konfiguration',
|
749: 'DNS-Server-Konfiguration',
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ export const ENGLISH: Record<string, number> = {
|
|||||||
'In your domain registrar for': 741, // partial sentence, followed by a domain name
|
'In your domain registrar for': 741, // partial sentence, followed by a domain name
|
||||||
'create this DNS record': 742,
|
'create this DNS record': 742,
|
||||||
'In your gateway': 743, // partial sentence, followed by a gateway name
|
'In your gateway': 743, // partial sentence, followed by a gateway name
|
||||||
'create these port forwarding rules': 744,
|
'create this port forwarding rule': 744,
|
||||||
'External Port': 745,
|
'External Port': 745,
|
||||||
'Internal Port': 747,
|
'Internal Port': 747,
|
||||||
'DNS Server Config': 749,
|
'DNS Server Config': 749,
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ export default {
|
|||||||
741: 'En su registrador de dominios para',
|
741: 'En su registrador de dominios para',
|
||||||
742: 'cree este registro DNS',
|
742: 'cree este registro DNS',
|
||||||
743: 'En su puerta de enlace',
|
743: 'En su puerta de enlace',
|
||||||
744: 'cree estas reglas de reenvío de puertos',
|
744: 'cree esta regla de reenvío de puertos',
|
||||||
745: 'Puerto externo',
|
745: 'Puerto externo',
|
||||||
747: 'Puerto interno',
|
747: 'Puerto interno',
|
||||||
749: 'Configuración del servidor DNS',
|
749: 'Configuración del servidor DNS',
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ export default {
|
|||||||
741: 'Dans votre registraire de domaine pour',
|
741: 'Dans votre registraire de domaine pour',
|
||||||
742: 'créez cet enregistrement DNS',
|
742: 'créez cet enregistrement DNS',
|
||||||
743: 'Dans votre passerelle',
|
743: 'Dans votre passerelle',
|
||||||
744: 'créez ces règles de redirection de port',
|
744: 'créez cette règle de redirection de port',
|
||||||
745: 'Port externe',
|
745: 'Port externe',
|
||||||
747: 'Port interne',
|
747: 'Port interne',
|
||||||
749: 'Configuration du serveur DNS',
|
749: 'Configuration du serveur DNS',
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ export default {
|
|||||||
741: 'W rejestratorze domeny dla',
|
741: 'W rejestratorze domeny dla',
|
||||||
742: 'utwórz ten rekord DNS',
|
742: 'utwórz ten rekord DNS',
|
||||||
743: 'W bramie',
|
743: 'W bramie',
|
||||||
744: 'utwórz te reguły przekierowania portów',
|
744: 'utwórz tę regułę przekierowania portów',
|
||||||
745: 'Port zewnętrzny',
|
745: 'Port zewnętrzny',
|
||||||
747: 'Port wewnętrzny',
|
747: 'Port wewnętrzny',
|
||||||
749: 'Konfiguracja serwera DNS',
|
749: 'Konfiguracja serwera DNS',
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ export class InterfaceAddressesComponent {
|
|||||||
fqdn,
|
fqdn,
|
||||||
gateway: gatewayId,
|
gateway: gatewayId,
|
||||||
acme: !authority || authority === 'local' ? null : authority,
|
acme: !authority || authority === 'local' ? null : authority,
|
||||||
|
internalPort: iface?.addressInfo.internalPort || 80,
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
} from '@taiga-ui/kit'
|
} from '@taiga-ui/kit'
|
||||||
import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||||
import { PortCheckIconComponent } from 'src/app/routes/portal/components/port-check-icon.component'
|
import { PortCheckIconComponent } from 'src/app/routes/portal/components/port-check-icon.component'
|
||||||
|
import { PortCheckWarningsComponent } from 'src/app/routes/portal/components/port-check-warnings.component'
|
||||||
import { TableComponent } from 'src/app/routes/portal/components/table.component'
|
import { TableComponent } from 'src/app/routes/portal/components/table.component'
|
||||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||||
import { T } from '@start9labs/start-sdk'
|
import { T } from '@start9labs/start-sdk'
|
||||||
@@ -28,11 +29,8 @@ export type DnsGateway = T.NetworkInterfaceInfo & {
|
|||||||
export type DomainValidationData = {
|
export type DomainValidationData = {
|
||||||
fqdn: string
|
fqdn: string
|
||||||
gateway: DnsGateway
|
gateway: DnsGateway
|
||||||
ports: number[]
|
port: number
|
||||||
initialResults?: {
|
initialResults?: { dnsPass: boolean; portResult: T.CheckPortRes | null }
|
||||||
dnsPass: boolean
|
|
||||||
portResults: (T.CheckPortRes | null)[]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -94,50 +92,32 @@ export type DomainValidationData = {
|
|||||||
<h2>{{ 'Port Forwarding' | i18n }}</h2>
|
<h2>{{ 'Port Forwarding' | i18n }}</h2>
|
||||||
<p>
|
<p>
|
||||||
{{ 'In your gateway' | i18n }} "{{ gatewayName }}",
|
{{ 'In your gateway' | i18n }} "{{ gatewayName }}",
|
||||||
{{ 'create these port forwarding rules' | i18n }}
|
{{ 'create this port forwarding rule' | i18n }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@let portRes = portResult();
|
||||||
|
|
||||||
<table [appTable]="[null, 'External Port', 'Internal Port', null]">
|
<table [appTable]="[null, 'External Port', 'Internal Port', null]">
|
||||||
@for (port of context.data.ports; track port; let i = $index) {
|
<tr>
|
||||||
<tr>
|
<td class="status">
|
||||||
<td class="status">
|
<port-check-icon [result]="portRes" [loading]="portLoading()" />
|
||||||
<port-check-icon
|
</td>
|
||||||
[result]="portResults()[i]"
|
<td>{{ context.data.port }}</td>
|
||||||
[loading]="!!portLoadings()[i]"
|
<td>{{ context.data.port }}</td>
|
||||||
/>
|
<td>
|
||||||
</td>
|
<button
|
||||||
<td>{{ port }}</td>
|
tuiButton
|
||||||
<td>{{ port }}</td>
|
size="s"
|
||||||
<td>
|
[loading]="portLoading()"
|
||||||
<button
|
(click)="testPort()"
|
||||||
tuiButton
|
>
|
||||||
size="s"
|
{{ 'Test' | i18n }}
|
||||||
[loading]="!!portLoadings()[i]"
|
</button>
|
||||||
(click)="testPort(i)"
|
</td>
|
||||||
>
|
</tr>
|
||||||
{{ 'Test' | i18n }}
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@if (anyNotRunning()) {
|
<port-check-warnings [result]="portRes" />
|
||||||
<p class="g-warning">
|
|
||||||
{{
|
|
||||||
'Port status cannot be determined while service is not running'
|
|
||||||
| i18n
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
@if (anyNoHairpinning()) {
|
|
||||||
<p class="g-warning">
|
|
||||||
{{
|
|
||||||
'This address will not work from your local network due to a router hairpinning limitation'
|
|
||||||
| i18n
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (!isManualMode) {
|
@if (!isManualMode) {
|
||||||
<footer class="g-buttons padding-top">
|
<footer class="g-buttons padding-top">
|
||||||
@@ -236,6 +216,7 @@ export type DomainValidationData = {
|
|||||||
TuiIcon,
|
TuiIcon,
|
||||||
TuiLoader,
|
TuiLoader,
|
||||||
PortCheckIconComponent,
|
PortCheckIconComponent,
|
||||||
|
PortCheckWarningsComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class DomainValidationComponent {
|
export class DomainValidationComponent {
|
||||||
@@ -251,28 +232,16 @@ export class DomainValidationComponent {
|
|||||||
parse(this.context.data.fqdn).domain || this.context.data.fqdn
|
parse(this.context.data.fqdn).domain || this.context.data.fqdn
|
||||||
|
|
||||||
readonly dnsLoading = signal(false)
|
readonly dnsLoading = signal(false)
|
||||||
readonly portLoadings = signal<boolean[]>(
|
readonly portLoading = signal(false)
|
||||||
this.context.data.ports.map(() => false),
|
|
||||||
)
|
|
||||||
readonly dnsPass = signal<boolean | undefined>(undefined)
|
readonly dnsPass = signal<boolean | undefined>(undefined)
|
||||||
readonly portResults = signal<(T.CheckPortRes | undefined)[]>(
|
readonly portResult = signal<T.CheckPortRes | undefined>(undefined)
|
||||||
this.context.data.ports.map(() => undefined),
|
|
||||||
)
|
|
||||||
|
|
||||||
readonly anyNotRunning = computed(() =>
|
|
||||||
this.portResults().some(r => r && !r.openInternally),
|
|
||||||
)
|
|
||||||
|
|
||||||
readonly anyNoHairpinning = computed(() =>
|
|
||||||
this.portResults().some(r => r && r.openExternally && !r.hairpinning),
|
|
||||||
)
|
|
||||||
|
|
||||||
readonly allPass = computed(() => {
|
readonly allPass = computed(() => {
|
||||||
const results = this.portResults()
|
const result = this.portResult()
|
||||||
return (
|
return (
|
||||||
this.dnsPass() === true &&
|
this.dnsPass() === true &&
|
||||||
results.length > 0 &&
|
!!result?.openInternally &&
|
||||||
results.every(r => !!r?.openInternally && !!r?.openExternally)
|
!!result?.openExternally
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -282,9 +251,7 @@ export class DomainValidationComponent {
|
|||||||
const initial = this.context.data.initialResults
|
const initial = this.context.data.initialResults
|
||||||
if (initial) {
|
if (initial) {
|
||||||
this.dnsPass.set(initial.dnsPass)
|
this.dnsPass.set(initial.dnsPass)
|
||||||
this.portResults.set(
|
if (initial.portResult) this.portResult.set(initial.portResult)
|
||||||
initial.portResults.map(r => r ?? undefined),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,32 +271,20 @@ export class DomainValidationComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async testPort(index: number) {
|
async testPort() {
|
||||||
this.portLoadings.update(l => {
|
this.portLoading.set(true)
|
||||||
const copy = [...l]
|
|
||||||
copy[index] = true
|
|
||||||
return copy
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this.api.checkPort({
|
const result = await this.api.checkPort({
|
||||||
gateway: this.context.data.gateway.id,
|
gateway: this.context.data.gateway.id,
|
||||||
port: this.context.data.ports[index]!,
|
port: this.context.data.port,
|
||||||
})
|
})
|
||||||
|
|
||||||
this.portResults.update(r => {
|
this.portResult.set(result)
|
||||||
const copy = [...r]
|
|
||||||
copy[index] = result
|
|
||||||
return copy
|
|
||||||
})
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.errorService.handleError(e)
|
this.errorService.handleError(e)
|
||||||
} finally {
|
} finally {
|
||||||
this.portLoadings.update(l => {
|
this.portLoading.set(false)
|
||||||
const copy = [...l]
|
|
||||||
copy[index] = false
|
|
||||||
return copy
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ export class DomainHealthService {
|
|||||||
if (!gateway) return
|
if (!gateway) return
|
||||||
|
|
||||||
let dnsPass: boolean
|
let dnsPass: boolean
|
||||||
let ports: number[]
|
let port: number
|
||||||
let portResults: (T.CheckPortRes | null)[]
|
let portResult: T.CheckPortRes | null
|
||||||
|
|
||||||
if (typeof portOrRes === 'number') {
|
if (typeof portOrRes === 'number') {
|
||||||
ports = [portOrRes]
|
port = portOrRes
|
||||||
const [dns, portResult] = await Promise.all([
|
const [dns, portRes] = await Promise.all([
|
||||||
this.api
|
this.api
|
||||||
.queryDns({ fqdn })
|
.queryDns({ fqdn })
|
||||||
.then(ip => ip === gateway.ipInfo.wanIp)
|
.then(ip => ip === gateway.ipInfo.wanIp)
|
||||||
@@ -41,23 +41,24 @@ export class DomainHealthService {
|
|||||||
.catch((): null => null),
|
.catch((): null => null),
|
||||||
])
|
])
|
||||||
dnsPass = dns
|
dnsPass = dns
|
||||||
portResults = [portResult]
|
portResult = portRes
|
||||||
} else {
|
} else {
|
||||||
dnsPass = portOrRes.dns === gateway.ipInfo.wanIp
|
dnsPass = portOrRes.dns === gateway.ipInfo.wanIp
|
||||||
ports = portOrRes.port.map(r => r.port)
|
port = portOrRes.port.port
|
||||||
portResults = portOrRes.port
|
portResult = portOrRes.port
|
||||||
}
|
}
|
||||||
|
|
||||||
const allPortsOk = portResults.every(
|
const portOk =
|
||||||
r => !!r?.openInternally && !!r?.openExternally && !!r?.hairpinning,
|
!!portResult?.openInternally &&
|
||||||
)
|
!!portResult?.openExternally &&
|
||||||
|
!!portResult?.hairpinning
|
||||||
|
|
||||||
if (!dnsPass || !allPortsOk) {
|
if (!dnsPass || !portOk) {
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() =>
|
() =>
|
||||||
this.openPublicDomainModal(fqdn, gateway, ports, {
|
this.openPublicDomainModal(fqdn, gateway, port, {
|
||||||
dnsPass,
|
dnsPass,
|
||||||
portResults,
|
portResult,
|
||||||
}),
|
}),
|
||||||
250,
|
250,
|
||||||
)
|
)
|
||||||
@@ -99,7 +100,7 @@ export class DomainHealthService {
|
|||||||
const gateway = await this.getGatewayData(gatewayId)
|
const gateway = await this.getGatewayData(gatewayId)
|
||||||
if (!gateway) return
|
if (!gateway) return
|
||||||
|
|
||||||
this.openPublicDomainModal(fqdn, gateway, [port])
|
this.openPublicDomainModal(fqdn, gateway, port)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.errorService.handleError(e)
|
this.errorService.handleError(e)
|
||||||
}
|
}
|
||||||
@@ -164,17 +165,17 @@ export class DomainHealthService {
|
|||||||
private openPublicDomainModal(
|
private openPublicDomainModal(
|
||||||
fqdn: string,
|
fqdn: string,
|
||||||
gateway: DnsGateway,
|
gateway: DnsGateway,
|
||||||
ports: number[],
|
port: number,
|
||||||
initialResults?: {
|
initialResults?: {
|
||||||
dnsPass: boolean
|
dnsPass: boolean
|
||||||
portResults: (T.CheckPortRes | null)[]
|
portResult: T.CheckPortRes | null
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
this.dialog
|
this.dialog
|
||||||
.openComponent(DOMAIN_VALIDATION, {
|
.openComponent(DOMAIN_VALIDATION, {
|
||||||
label: 'Address Requirements',
|
label: 'Address Requirements',
|
||||||
size: 'm',
|
size: 'm',
|
||||||
data: { fqdn, gateway, ports, initialResults },
|
data: { fqdn, gateway, port, initialResults },
|
||||||
})
|
})
|
||||||
.subscribe()
|
.subscribe()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export type PortForwardValidationData = {
|
|||||||
<h2>{{ 'Port Forwarding' | i18n }}</h2>
|
<h2>{{ 'Port Forwarding' | i18n }}</h2>
|
||||||
<p>
|
<p>
|
||||||
{{ 'In your gateway' | i18n }} "{{ gatewayName }}",
|
{{ 'In your gateway' | i18n }} "{{ gatewayName }}",
|
||||||
{{ 'create these port forwarding rules' | i18n }}
|
{{ 'create this port forwarding rule' | i18n }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@let portRes = portResult();
|
@let portRes = portResult();
|
||||||
|
|||||||
@@ -1467,15 +1467,13 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
dns: null,
|
dns: null,
|
||||||
port: [
|
port: {
|
||||||
{
|
ip: '0.0.0.0',
|
||||||
ip: '0.0.0.0',
|
port: 443,
|
||||||
port: 443,
|
openExternally: false,
|
||||||
openExternally: false,
|
openInternally: false,
|
||||||
openInternally: false,
|
hairpinning: false,
|
||||||
hairpinning: false,
|
},
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1575,15 +1573,13 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
dns: null,
|
dns: null,
|
||||||
port: [
|
port: {
|
||||||
{
|
ip: '0.0.0.0',
|
||||||
ip: '0.0.0.0',
|
port: 443,
|
||||||
port: 443,
|
openExternally: false,
|
||||||
openExternally: false,
|
openInternally: false,
|
||||||
openInternally: false,
|
hairpinning: false,
|
||||||
hairpinning: false,
|
},
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user