mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-01 21:13:09 +00:00
161 lines
5.0 KiB
TypeScript
161 lines
5.0 KiB
TypeScript
import { DOCUMENT } from '@angular/common'
|
|
import { Inject, Injectable } from '@angular/core'
|
|
import { WorkspaceConfig } from '@start9labs/shared'
|
|
import { T } from '@start9labs/start-sdk'
|
|
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
|
|
|
const {
|
|
gitHash,
|
|
useMocks,
|
|
ui: { api, marketplace, mocks },
|
|
} = require('../../../../../config.json') as WorkspaceConfig
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class ConfigService {
|
|
constructor(@Inject(DOCUMENT) private readonly document: Document) {}
|
|
|
|
hostname = this.document.location.hostname
|
|
// includes port
|
|
host = this.document.location.host
|
|
// includes ":" (e.g. "http:")
|
|
protocol = this.document.location.protocol
|
|
version = require('../../../../../package.json').version as string
|
|
useMocks = useMocks
|
|
mocks = mocks
|
|
gitHash = gitHash
|
|
api = api
|
|
marketplace = marketplace
|
|
skipStartupAlerts = useMocks && mocks.skipStartupAlerts
|
|
|
|
isTor(): boolean {
|
|
return useMocks ? mocks.maskAs === 'tor' : this.hostname.endsWith('.onion')
|
|
}
|
|
|
|
isLocal(): boolean {
|
|
return (
|
|
this.hostname.endsWith('.local') || (useMocks && mocks.maskAs === 'local')
|
|
)
|
|
}
|
|
|
|
isLocalhost(): boolean {
|
|
return (
|
|
this.hostname === 'localhost' ||
|
|
(useMocks && mocks.maskAs === 'localhost')
|
|
)
|
|
}
|
|
|
|
isIpv4(): boolean {
|
|
return isValidIpv4(this.hostname) || (useMocks && mocks.maskAs === 'ipv4')
|
|
}
|
|
|
|
isIpv6(): boolean {
|
|
return isValidIpv6(this.hostname) || (useMocks && mocks.maskAs === 'ipv6')
|
|
}
|
|
|
|
isClearnet(): boolean {
|
|
return (
|
|
(useMocks && mocks.maskAs === 'clearnet') ||
|
|
(!this.isTor() &&
|
|
!this.isLocal() &&
|
|
!this.isLocalhost() &&
|
|
!this.isIpv4() &&
|
|
!this.isIpv6())
|
|
)
|
|
}
|
|
|
|
isLanHttp(): boolean {
|
|
return !this.isTor() && !this.isLocalhost() && !this.isHttps()
|
|
}
|
|
|
|
isSecure(): boolean {
|
|
return window.isSecureContext || this.isTor()
|
|
}
|
|
|
|
isLaunchable(
|
|
state: T.PackageState['state'],
|
|
status: T.MainStatus['status'],
|
|
): boolean {
|
|
return state === 'installed' && status === 'running'
|
|
}
|
|
|
|
/** ${scheme}://${username}@${host}:${externalPort}${suffix} */
|
|
launchableAddress(ui: T.ServiceInterfaceWithHostInfo): string {
|
|
if (ui.type !== 'ui') return ''
|
|
|
|
const host = ui.hostInfo
|
|
const addressInfo = ui.addressInfo
|
|
const scheme = this.isHttps() ? 'https' : 'http'
|
|
const username = addressInfo.username ? addressInfo.username + '@' : ''
|
|
const suffix = addressInfo.suffix || ''
|
|
const url = new URL(`${scheme}://${username}placeholder${suffix}`)
|
|
|
|
if (host.kind === 'multi') {
|
|
const onionHostname = host.hostnames.find(h => h.kind === 'onion')
|
|
?.hostname as T.ExportedOnionHostname
|
|
|
|
if (this.isTor() && onionHostname) {
|
|
url.hostname = onionHostname.value
|
|
} else {
|
|
const ipHostname = host.hostnames.find(h => h.kind === 'ip')
|
|
?.hostname as T.ExportedIpHostname
|
|
|
|
if (!ipHostname) return ''
|
|
|
|
url.hostname = this.hostname
|
|
url.port = String(ipHostname.sslPort || ipHostname.port)
|
|
}
|
|
} else {
|
|
const hostname = {} as T.ExportedHostnameInfo // host.hostname
|
|
|
|
if (!hostname) return ''
|
|
|
|
if (this.isTor() && hostname.kind === 'onion') {
|
|
url.hostname = (hostname.hostname as T.ExportedOnionHostname).value
|
|
} else {
|
|
url.hostname = this.hostname
|
|
url.port = String(hostname.hostname.sslPort || hostname.hostname.port)
|
|
}
|
|
}
|
|
|
|
return url.href
|
|
}
|
|
|
|
getHost(): string {
|
|
return this.host
|
|
}
|
|
|
|
private isHttps(): boolean {
|
|
return useMocks ? mocks.maskAsHttps : this.protocol === 'https:'
|
|
}
|
|
}
|
|
|
|
export function isValidIpv4(address: string): boolean {
|
|
const regexExp =
|
|
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
|
|
return regexExp.test(address)
|
|
}
|
|
|
|
export function isValidIpv6(address: string): boolean {
|
|
const regexExp =
|
|
/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/gi
|
|
return regexExp.test(address)
|
|
}
|
|
|
|
export function removeProtocol(str: string): string {
|
|
if (str.startsWith('http://')) return str.slice(7)
|
|
if (str.startsWith('https://')) return str.slice(8)
|
|
return str
|
|
}
|
|
|
|
export function removePort(str: string): string {
|
|
return str.split(':')[0]
|
|
}
|
|
|
|
export function hasUi(
|
|
interfaces: PackageDataEntry['serviceInterfaces'],
|
|
): boolean {
|
|
return Object.values(interfaces).some(iface => iface.type === 'ui')
|
|
}
|