fix all types

This commit is contained in:
Matt Hill
2025-08-16 23:14:19 -06:00
parent f7f0b7dc1a
commit a0a2c20b08
12 changed files with 83 additions and 91 deletions

View File

@@ -42,7 +42,7 @@ function cmpLan(host: T.Host, a: LanAddress, b: LanAddress): -1 | 0 | 1 {
return cmpWithRankedPredicates(a, b, [
x =>
x.info.hostname.kind === 'domain' &&
!!host.privateDomains[x.info.hostname.value], // private domain
!!host.privateDomains.find(d => d === x.info.hostname.value), // private domain
x => x.info.hostname.kind === 'local', // .local
x => x.info.hostname.kind === 'ipv4', // ipv4
x => x.info.hostname.kind === 'ipv6', // ipv6
@@ -66,7 +66,7 @@ function cmpVpn(host: T.Host, a: VpnAddress, b: VpnAddress): -1 | 0 | 1 {
return cmpWithRankedPredicates(a, b, [
x =>
x.info.hostname.kind === 'domain' &&
!!host.privateDomains[x.info.hostname.value], // private domain
!!host.privateDomains.find(d => d === x.info.hostname.value), // private domain
x => x.info.hostname.kind === 'ipv4', // ipv4
x => x.info.hostname.kind === 'ipv6', // ipv6
// remainder: public domains accessible privately
@@ -102,7 +102,7 @@ function cmpClearnet(
function toDisplayAddress(
{ info, url }: AddressWithInfo,
gateways: GatewayPlus[],
publicDomains: Record<string, T.DomainConfig>,
publicDomains: Record<string, T.PublicDomainConfig>,
): DisplayAddress {
let access: DisplayAddress['access']
let gatewayName: DisplayAddress['gatewayName']
@@ -248,11 +248,13 @@ function toDisplayAddress(
}
export function getPublicDomains(
publicDomains: Record<string, T.DomainConfig>,
publicDomains: Record<string, T.PublicDomainConfig>,
gateways: GatewayPlus[],
): PublicDomain[] {
return Object.entries(publicDomains).map(([fqdn, info]) => ({
fqdn,
...info,
acme: info.acme,
gateway: gateways.find(g => g.id === info.gateway) || null,
}))
}
@@ -302,18 +304,11 @@ export class InterfaceService {
return {
common: bestAddrs.map(a =>
toDisplayAddress(a, gateways, host.publicDomains, host.privateDomains),
toDisplayAddress(a, gateways, host.publicDomains),
),
uncommon: allAddressesWithInfo
.filter(a => !bestAddrs.includes(a))
.map(a =>
toDisplayAddress(
a,
gateways,
host.publicDomains,
host.privateDomains,
),
),
.map(a => toDisplayAddress(a, gateways, host.publicDomains)),
}
}

View File

@@ -150,9 +150,8 @@ export class DnsComponent {
this.loading.set(true)
try {
const ip = await this.api.testDns({
const ip = await this.api.queryDns({
fqdn: this.context.data.fqdn,
gateway: this.context.data.gateway.id,
})
this.pass.set(ip === this.context.data.gateway.ipInfo.wanIp)

View File

@@ -39,7 +39,7 @@ import { PublicDomain, PublicDomainService } from './pd.service'
</header>
<table [appTable]="['Domain', 'Gateway', 'Certificate Authority', null]">
@for (domain of publicDomains(); track $index) {
<tr [domain]="domain"></tr>
<tr [publicDomain]="domain"></tr>
} @empty {
@if (publicDomains()) {
<tr>

View File

@@ -16,10 +16,10 @@ import { PublicDomain, PublicDomainService } from './pd.service'
import { toAuthorityName } from 'src/app/utils/acme'
@Component({
selector: 'tr[domain]',
selector: 'tr[publicDomain]',
template: `
<td>{{ domain().fqdn }}</td>
<td>{{ domain().gateway }}</td>
<td>{{ publicDomain().fqdn }}</td>
<td>{{ publicDomain().gateway?.ipInfo?.name }}</td>
<td>{{ authority() }}</td>
<td>
<button
@@ -39,7 +39,11 @@ import { toAuthorityName } from 'src/app/utils/acme'
new
iconStart="@tui.eye"
(click)="
service.showDns(domain().fqdn, domain().gateway, dnsMessage())
service.showDns(
publicDomain().fqdn,
publicDomain().gateway!,
dnsMessage()
)
"
>
{{ 'View DNS' | i18n }}
@@ -48,7 +52,7 @@ import { toAuthorityName } from 'src/app/utils/acme'
tuiOption
new
iconStart="@tui.pencil"
(click)="service.edit(domain())"
(click)="service.edit(publicDomain())"
>
{{ 'Edit' | i18n }}
</button>
@@ -59,7 +63,7 @@ import { toAuthorityName } from 'src/app/utils/acme'
new
iconStart="@tui.trash"
class="g-negative"
(click)="service.remove(domain().fqdn)"
(click)="service.remove(publicDomain().fqdn)"
>
{{ 'Delete' | i18n }}
</button>
@@ -99,11 +103,11 @@ export class PublicDomainsItemComponent {
open = false
readonly domain = input.required<PublicDomain>()
readonly publicDomain = input.required<PublicDomain>()
readonly authority = computed(() => toAuthorityName(this.domain().acme))
readonly authority = computed(() => toAuthorityName(this.publicDomain().acme))
readonly dnsMessage = computed<i18nKey>(
() =>
`Create one of the DNS records below to cause ${this.domain().fqdn} to resolve to ${this.domain().gateway.ipInfo.wanIp}` as i18nKey,
`Create one of the DNS records below to cause ${this.publicDomain().fqdn} to resolve to ${this.publicDomain().gateway?.ipInfo.wanIp}` as i18nKey,
)
}

View File

@@ -15,7 +15,6 @@ import { configBuilderToSpec } from 'src/app/utils/configBuilderToSpec'
import { PatchDB } from 'patch-db-client'
import { DataModel } from 'src/app/services/patch-db/data-model'
import { toAuthorityName } from 'src/app/utils/acme'
import { GatewayPlus } from 'src/app/services/gateway.service'
import { InterfaceComponent } from '../interface.component'
import { DNS } from './dns.component'
@@ -23,7 +22,7 @@ import { DNS } from './dns.component'
export type PublicDomain = {
fqdn: string
gateway: GatewayPlus
gateway: GatewayWithId | null
acme: string | null
}
@@ -104,7 +103,7 @@ export class PublicDomainService {
},
],
value: {
gateway: domain.gateway.id,
gateway: domain.gateway!.id,
authority: domain.acme,
},
},

View File

@@ -48,7 +48,7 @@ export class ServiceInterfacesComponent {
readonly pkg = input.required<PackageDataEntry>()
readonly disabled = input(false)
readonly interfaces = computed(({ serviceInterfaces, hosts } = this.pkg()) =>
readonly interfaces = computed(({ serviceInterfaces } = this.pkg()) =>
Object.entries(serviceInterfaces)
.sort((a, b) => tuiDefaultSort(a[1], b[1]))
.map(([id, value]) => {

View File

@@ -100,10 +100,6 @@ export default class ServiceInterfaceRoute {
readonly pkg = toSignal(this.patch.watch$('packageData', this.pkgId))
readonly domains = toSignal(
this.patch.watch$('serverInfo', 'network', 'domains'),
)
readonly isRunning = computed(() => {
return this.pkg()?.status.main === 'running'
})
@@ -111,9 +107,8 @@ export default class ServiceInterfaceRoute {
readonly serviceInterface = computed(() => {
const pkg = this.pkg()
const id = this.interfaceId()
const domains = this.domains()
if (!pkg || !id || !domains) {
if (!pkg || !id) {
return
}
@@ -131,20 +126,15 @@ export default class ServiceInterfaceRoute {
return {
...iFace,
addresses: this.interfaceService.getAddresses(
iFace,
host,
domains,
gateways,
),
addresses: this.interfaceService.getAddresses(iFace, host, gateways),
gateways:
gateways.map(g => ({
enabled: true,
...g,
})) || [],
torDomains: host.onions.map(o => `${o}.onion`),
publicDomains: getPublicDomains(host.domains.public),
privateDomains: host.domains.private,
publicDomains: getPublicDomains(host.publicDomains, gateways),
privateDomains: host.privateDomains,
isOs: false,
}
})

View File

@@ -158,19 +158,27 @@ export default class SystemDnsComponent {
switchMap(async ([pkgs, { gateways, dns }]) => {
const spec = await configBuilderToSpec(this.dnsSpec)
const selection = dns.static ? 'custom' : 'defaults'
const current = dns.staticServers
? {
selection: 'custom',
value: dns.staticServers,
}
: { selection: 'defaults', value: dns.dhcpServers }
const form = this.formService.createForm(spec, {
strategy: { selection, value: dns.servers },
})
const form = this.formService.createForm(spec, current)
return {
spec,
form,
warn:
(Object.values(pkgs).some(p => p) || []) &&
(Object.values(pkgs).some(p =>
Object.values(p.hosts).some(h => h?.privateDomains.length),
) ||
[]) &&
Object.values(gateways)
.filter(g => dns.servers.includes(g.ipInfo?.lanIp))
.filter(g =>
dns.dhcpServers.some(d => g.ipInfo?.lanIp.includes(d)),
)
.map(g => g.ipInfo?.name),
}
}),

View File

@@ -89,7 +89,6 @@ export default class StartOsUiComponent {
addresses: this.interfaceService.getAddresses(
this.iface,
network.host,
network.domains,
gateways,
),
gateways: gateways.map(g => ({
@@ -97,8 +96,8 @@ export default class StartOsUiComponent {
...g,
})),
torDomains: network.host.onions.map(o => `${o}.onion`),
publicDomains: getPublicDomains(network.host.domains.public),
privateDomains: network.host.domains.private,
publicDomains: getPublicDomains(network.host.publicDomains, gateways),
privateDomains: network.host.privateDomains,
isOs: true,
}
})

View File

@@ -2069,11 +2069,9 @@ export namespace Mock {
},
},
},
publicDomains: {},
privateDomains: [],
onions: [],
domains: {
public: {},
private: {},
},
hostnameInfo: {
80: [
{
@@ -2172,11 +2170,9 @@ export namespace Mock {
},
},
},
publicDomains: {},
privateDomains: [],
onions: [],
domains: {
public: {},
private: {},
},
hostnameInfo: {
8332: [],
},
@@ -2198,11 +2194,9 @@ export namespace Mock {
},
},
},
publicDomains: {},
privateDomains: [],
onions: [],
domains: {
public: {},
private: {},
},
hostnameInfo: {
8333: [],
},

View File

@@ -582,9 +582,11 @@ export class MockApiService extends ApiService {
name: params.name,
scopeId: 3,
deviceType: 'wireguard',
subnets: [],
wanIp: '1.1.1.1',
subnets: ['192.168.1.10/24'],
wanIp: '203.0.113.45',
ntpServers: [],
lanIp: ['192.168.1.10'],
dnsServers: [],
},
},
},
@@ -1417,7 +1419,7 @@ export class MockApiService extends ApiService {
const patch: Operation<any>[] = [
{
op: PatchOp.ADD,
path: `/serverInfo/host/domains/public`,
path: `/serverInfo/host/publicDomains`,
value: {
[params.fqdn]: { gateway: params.gateway, acme: params.acme },
},
@@ -1452,7 +1454,7 @@ export class MockApiService extends ApiService {
const patch: RemoveOperation[] = [
{
op: PatchOp.REMOVE,
path: `/serverInfo/host/domains/public/${params.fqdn}`,
path: `/serverInfo/host/publicDomains/${params.fqdn}`,
},
{
op: PatchOp.REMOVE,
@@ -1472,7 +1474,7 @@ export class MockApiService extends ApiService {
const patch: Operation<any>[] = [
{
op: PatchOp.REPLACE,
path: `/serverInfo/host/domains/private`,
path: `/serverInfo/host/privateDomains`,
value: [params.fqdn],
},
{
@@ -1505,7 +1507,7 @@ export class MockApiService extends ApiService {
const patch: Operation<any>[] = [
{
op: PatchOp.REPLACE,
path: `/serverInfo/host/domains/private`,
path: `/serverInfo/host/privateDomains`,
value: [],
},
{
@@ -1590,7 +1592,7 @@ export class MockApiService extends ApiService {
const patch: Operation<any>[] = [
{
op: PatchOp.ADD,
path: `/packageData/${params.package}/hosts/${params.host}/domains/public`,
path: `/packageData/${params.package}/hosts/${params.host}/publicDomains`,
value: {
[params.fqdn]: { gateway: params.gateway, acme: params.acme },
},
@@ -1625,7 +1627,7 @@ export class MockApiService extends ApiService {
const patch: RemoveOperation[] = [
{
op: PatchOp.REMOVE,
path: `/packageData/${params.package}/hosts/${params.host}/domains/public/${params.fqdn}`,
path: `/packageData/${params.package}/hosts/${params.host}/publicDomains/${params.fqdn}`,
},
{
op: PatchOp.REMOVE,
@@ -1645,7 +1647,7 @@ export class MockApiService extends ApiService {
const patch: Operation<any>[] = [
{
op: PatchOp.REPLACE,
path: `/packageData/${params.package}/hosts/${params.host}/domains/private`,
path: `/packageData/${params.package}/hosts/${params.host}/privateDomains`,
value: [params.fqdn],
},
{
@@ -1678,7 +1680,7 @@ export class MockApiService extends ApiService {
const patch: Operation<any>[] = [
{
op: PatchOp.REPLACE,
path: `/packageData/${params.package}/hosts/${params.host}/domains/private`,
path: `/packageData/${params.package}/hosts/${params.host}/privateDomains`,
value: [],
},
{

View File

@@ -52,10 +52,8 @@ export const mockPatchData: DataModel = {
},
},
},
domains: {
public: {},
private: {},
},
publicDomains: {},
privateDomains: [],
onions: ['myveryownspecialtoraddress'],
hostnameInfo: {
80: [
@@ -149,6 +147,8 @@ export const mockPatchData: DataModel = {
subnets: ['10.0.0.2/24'],
wanIp: '203.0.113.45',
ntpServers: [],
lanIp: ['10.0.2.12'],
dnsServers: [],
},
},
wlan0: {
@@ -164,6 +164,8 @@ export const mockPatchData: DataModel = {
],
wanIp: '203.0.113.45',
ntpServers: [],
lanIp: ['10.0.90.12'],
dnsServers: ['8.8.8.8'],
},
},
wireguard1: {
@@ -179,9 +181,15 @@ export const mockPatchData: DataModel = {
],
wanIp: '203.0.113.45',
ntpServers: [],
lanIp: ['10.0.90.12'],
dnsServers: ['1.1.1.1'],
},
},
},
dns: {
dhcpServers: ['1.1.1.1', '8.8.8.8'],
staticServers: null,
},
},
unreadNotificationCount: 4,
// password is asdfasdf
@@ -338,11 +346,9 @@ export const mockPatchData: DataModel = {
},
},
},
publicDomains: {},
privateDomains: [],
onions: [],
domains: {
public: {},
private: {},
},
hostnameInfo: {
80: [
{
@@ -441,11 +447,9 @@ export const mockPatchData: DataModel = {
},
},
},
publicDomains: {},
privateDomains: [],
onions: [],
domains: {
public: {},
private: {},
},
hostnameInfo: {
8332: [],
},
@@ -467,11 +471,9 @@ export const mockPatchData: DataModel = {
},
},
},
publicDomains: {},
privateDomains: [],
onions: [],
domains: {
public: {},
private: {},
},
hostnameInfo: {
8333: [],
},