mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
support http2 alpn handshake (#2354)
* support http2 alpn handshake * fix protocol name * switch to https for tor * update setup wizard and main ui to accommodate https (#2356) * update setup wizard and main ui to accommodate https * update wording in download doc * fix accidential conversion of tor https for services and allow ws still * redirect to https if available * fix replaces to only search at beginning and ignore localhost when checking for https --------- Co-authored-by: Lucy <12953208+elvece@users.noreply.github.com>
This commit is contained in:
@@ -49,7 +49,7 @@ impl Database {
|
|||||||
last_wifi_region: None,
|
last_wifi_region: None,
|
||||||
eos_version_compat: Current::new().compat().clone(),
|
eos_version_compat: Current::new().compat().clone(),
|
||||||
lan_address,
|
lan_address,
|
||||||
tor_address: format!("http://{}", account.key.tor_address())
|
tor_address: format!("https://{}", account.key.tor_address())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
ip_info: BTreeMap::new(),
|
ip_info: BTreeMap::new(),
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use tracing::instrument;
|
|||||||
use crate::context::RpcContext;
|
use crate::context::RpcContext;
|
||||||
use crate::manager::sync::synchronizer;
|
use crate::manager::sync::synchronizer;
|
||||||
use crate::net::net_controller::NetService;
|
use crate::net::net_controller::NetService;
|
||||||
|
use crate::net::vhost::AlpnInfo;
|
||||||
use crate::procedure::docker::{DockerContainer, DockerProcedure, LongRunning};
|
use crate::procedure::docker::{DockerContainer, DockerProcedure, LongRunning};
|
||||||
#[cfg(feature = "js_engine")]
|
#[cfg(feature = "js_engine")]
|
||||||
use crate::procedure::js_scripts::JsProcedure;
|
use crate::procedure::js_scripts::JsProcedure;
|
||||||
@@ -573,8 +574,14 @@ async fn add_network_for_main(
|
|||||||
let mut tx = secrets.begin().await?;
|
let mut tx = secrets.begin().await?;
|
||||||
for (id, interface) in &seed.manifest.interfaces.0 {
|
for (id, interface) in &seed.manifest.interfaces.0 {
|
||||||
for (external, internal) in interface.lan_config.iter().flatten() {
|
for (external, internal) in interface.lan_config.iter().flatten() {
|
||||||
svc.add_lan(&mut tx, id.clone(), external.0, internal.internal, false)
|
svc.add_lan(
|
||||||
.await?;
|
&mut tx,
|
||||||
|
id.clone(),
|
||||||
|
external.0,
|
||||||
|
internal.internal,
|
||||||
|
Err(AlpnInfo::Specified(vec![])),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
for (external, internal) in interface.tor_config.iter().flat_map(|t| &t.port_mapping) {
|
for (external, internal) in interface.tor_config.iter().flat_map(|t| &t.port_mapping) {
|
||||||
svc.add_tor(&mut tx, id.clone(), external.0, internal.0)
|
svc.add_tor(&mut tx, id.clone(), external.0, internal.0)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use crate::net::keys::Key;
|
|||||||
use crate::net::mdns::MdnsController;
|
use crate::net::mdns::MdnsController;
|
||||||
use crate::net::ssl::{export_cert, export_key, SslManager};
|
use crate::net::ssl::{export_cert, export_key, SslManager};
|
||||||
use crate::net::tor::TorController;
|
use crate::net::tor::TorController;
|
||||||
use crate::net::vhost::VHostController;
|
use crate::net::vhost::{AlpnInfo, VHostController};
|
||||||
use crate::s9pk::manifest::PackageId;
|
use crate::s9pk::manifest::PackageId;
|
||||||
use crate::volume::cert_dir;
|
use crate::volume::cert_dir;
|
||||||
use crate::{Error, HOST_IP};
|
use crate::{Error, HOST_IP};
|
||||||
@@ -55,6 +55,8 @@ impl NetController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn add_os_bindings(&mut self, hostname: &Hostname, key: &Key) -> Result<(), Error> {
|
async fn add_os_bindings(&mut self, hostname: &Hostname, key: &Key) -> Result<(), Error> {
|
||||||
|
let alpn = Err(AlpnInfo::Specified(vec!["http/1.1".into(), "h2".into()]));
|
||||||
|
|
||||||
// Internal DNS
|
// Internal DNS
|
||||||
self.vhost
|
self.vhost
|
||||||
.add(
|
.add(
|
||||||
@@ -62,7 +64,7 @@ impl NetController {
|
|||||||
Some("embassy".into()),
|
Some("embassy".into()),
|
||||||
443,
|
443,
|
||||||
([127, 0, 0, 1], 80).into(),
|
([127, 0, 0, 1], 80).into(),
|
||||||
false,
|
alpn.clone(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
self.os_bindings
|
self.os_bindings
|
||||||
@@ -71,7 +73,13 @@ impl NetController {
|
|||||||
// LAN IP
|
// LAN IP
|
||||||
self.os_bindings.push(
|
self.os_bindings.push(
|
||||||
self.vhost
|
self.vhost
|
||||||
.add(key.clone(), None, 443, ([127, 0, 0, 1], 80).into(), false)
|
.add(
|
||||||
|
key.clone(),
|
||||||
|
None,
|
||||||
|
443,
|
||||||
|
([127, 0, 0, 1], 80).into(),
|
||||||
|
alpn.clone(),
|
||||||
|
)
|
||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -83,7 +91,7 @@ impl NetController {
|
|||||||
Some("localhost".into()),
|
Some("localhost".into()),
|
||||||
443,
|
443,
|
||||||
([127, 0, 0, 1], 80).into(),
|
([127, 0, 0, 1], 80).into(),
|
||||||
false,
|
alpn.clone(),
|
||||||
)
|
)
|
||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
@@ -94,7 +102,7 @@ impl NetController {
|
|||||||
Some(hostname.no_dot_host_name()),
|
Some(hostname.no_dot_host_name()),
|
||||||
443,
|
443,
|
||||||
([127, 0, 0, 1], 80).into(),
|
([127, 0, 0, 1], 80).into(),
|
||||||
false,
|
alpn.clone(),
|
||||||
)
|
)
|
||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
@@ -107,7 +115,7 @@ impl NetController {
|
|||||||
Some(hostname.local_domain_name()),
|
Some(hostname.local_domain_name()),
|
||||||
443,
|
443,
|
||||||
([127, 0, 0, 1], 80).into(),
|
([127, 0, 0, 1], 80).into(),
|
||||||
false,
|
alpn.clone(),
|
||||||
)
|
)
|
||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
@@ -127,7 +135,7 @@ impl NetController {
|
|||||||
Some(key.tor_address().to_string()),
|
Some(key.tor_address().to_string()),
|
||||||
443,
|
443,
|
||||||
([127, 0, 0, 1], 80).into(),
|
([127, 0, 0, 1], 80).into(),
|
||||||
false,
|
alpn.clone(),
|
||||||
)
|
)
|
||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
@@ -179,7 +187,7 @@ impl NetController {
|
|||||||
key: Key,
|
key: Key,
|
||||||
external: u16,
|
external: u16,
|
||||||
target: SocketAddr,
|
target: SocketAddr,
|
||||||
connect_ssl: bool,
|
connect_ssl: Result<(), AlpnInfo>,
|
||||||
) -> Result<Vec<Arc<()>>, Error> {
|
) -> Result<Vec<Arc<()>>, Error> {
|
||||||
let mut rcs = Vec::with_capacity(2);
|
let mut rcs = Vec::with_capacity(2);
|
||||||
rcs.push(
|
rcs.push(
|
||||||
@@ -261,7 +269,7 @@ impl NetService {
|
|||||||
id: InterfaceId,
|
id: InterfaceId,
|
||||||
external: u16,
|
external: u16,
|
||||||
internal: u16,
|
internal: u16,
|
||||||
connect_ssl: bool,
|
connect_ssl: Result<(), AlpnInfo>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
for<'a> &'a mut Ex: PgExecutor<'a>,
|
for<'a> &'a mut Ex: PgExecutor<'a>,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ impl VHostController {
|
|||||||
hostname: Option<String>,
|
hostname: Option<String>,
|
||||||
external: u16,
|
external: u16,
|
||||||
target: SocketAddr,
|
target: SocketAddr,
|
||||||
connect_ssl: bool,
|
connect_ssl: Result<(), AlpnInfo>,
|
||||||
) -> Result<Arc<()>, Error> {
|
) -> Result<Arc<()>, Error> {
|
||||||
let mut writable = self.servers.lock().await;
|
let mut writable = self.servers.lock().await;
|
||||||
let server = if let Some(server) = writable.remove(&external) {
|
let server = if let Some(server) = writable.remove(&external) {
|
||||||
@@ -77,10 +77,16 @@ impl VHostController {
|
|||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
struct TargetInfo {
|
struct TargetInfo {
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
connect_ssl: bool,
|
connect_ssl: Result<(), AlpnInfo>,
|
||||||
key: Key,
|
key: Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum AlpnInfo {
|
||||||
|
Reflect,
|
||||||
|
Specified(Vec<Vec<u8>>),
|
||||||
|
}
|
||||||
|
|
||||||
struct VHostServer {
|
struct VHostServer {
|
||||||
mapping: Weak<RwLock<BTreeMap<Option<String>, BTreeMap<TargetInfo, Weak<()>>>>>,
|
mapping: Weak<RwLock<BTreeMap<Option<String>, BTreeMap<TargetInfo, Weak<()>>>>>,
|
||||||
_thread: NonDetachingJoinHandle<()>,
|
_thread: NonDetachingJoinHandle<()>,
|
||||||
@@ -178,7 +184,7 @@ impl VHostServer {
|
|||||||
let cfg = ServerConfig::builder()
|
let cfg = ServerConfig::builder()
|
||||||
.with_safe_defaults()
|
.with_safe_defaults()
|
||||||
.with_no_client_auth();
|
.with_no_client_auth();
|
||||||
let cfg =
|
let mut cfg =
|
||||||
if mid.client_hello().signature_schemes().contains(
|
if mid.client_hello().signature_schemes().contains(
|
||||||
&tokio_rustls::rustls::SignatureScheme::ED25519,
|
&tokio_rustls::rustls::SignatureScheme::ED25519,
|
||||||
) {
|
) {
|
||||||
@@ -213,48 +219,86 @@ impl VHostServer {
|
|||||||
.private_key_to_der()?,
|
.private_key_to_der()?,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
};
|
}
|
||||||
let mut tls_stream = mid
|
.with_kind(crate::ErrorKind::OpenSsl)?;
|
||||||
.into_stream(Arc::new(
|
match target.connect_ssl {
|
||||||
cfg.with_kind(crate::ErrorKind::OpenSsl)?,
|
Ok(()) => {
|
||||||
))
|
let mut client_cfg =
|
||||||
.await?;
|
|
||||||
tls_stream.get_mut().0.stop_buffering();
|
|
||||||
if target.connect_ssl {
|
|
||||||
tokio::io::copy_bidirectional(
|
|
||||||
&mut tls_stream,
|
|
||||||
&mut TlsConnector::from(Arc::new(
|
|
||||||
tokio_rustls::rustls::ClientConfig::builder()
|
tokio_rustls::rustls::ClientConfig::builder()
|
||||||
.with_safe_defaults()
|
.with_safe_defaults()
|
||||||
.with_root_certificates({
|
.with_root_certificates({
|
||||||
let mut store = RootCertStore::empty();
|
let mut store = RootCertStore::empty();
|
||||||
store.add(
|
store.add(
|
||||||
&tokio_rustls::rustls::Certificate(
|
&tokio_rustls::rustls::Certificate(
|
||||||
key.root_ca().to_der()?,
|
key.root_ca().to_der()?,
|
||||||
),
|
),
|
||||||
).with_kind(crate::ErrorKind::OpenSsl)?;
|
).with_kind(crate::ErrorKind::OpenSsl)?;
|
||||||
store
|
store
|
||||||
})
|
})
|
||||||
.with_no_client_auth(),
|
.with_no_client_auth();
|
||||||
))
|
client_cfg.alpn_protocols = mid
|
||||||
.connect(
|
.client_hello()
|
||||||
key.key()
|
.alpn()
|
||||||
.internal_address()
|
.into_iter()
|
||||||
.as_str()
|
.flatten()
|
||||||
.try_into()
|
.map(|x| x.to_vec())
|
||||||
.with_kind(crate::ErrorKind::OpenSsl)?,
|
.collect();
|
||||||
tcp_stream,
|
let mut target_stream =
|
||||||
|
TlsConnector::from(Arc::new(client_cfg))
|
||||||
|
.connect_with(
|
||||||
|
key.key()
|
||||||
|
.internal_address()
|
||||||
|
.as_str()
|
||||||
|
.try_into()
|
||||||
|
.with_kind(
|
||||||
|
crate::ErrorKind::OpenSsl,
|
||||||
|
)?,
|
||||||
|
tcp_stream,
|
||||||
|
|conn| {
|
||||||
|
cfg.alpn_protocols.extend(
|
||||||
|
conn.alpn_protocol()
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| p.to_vec()),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_kind(crate::ErrorKind::OpenSsl)?;
|
||||||
|
let mut tls_stream =
|
||||||
|
mid.into_stream(Arc::new(cfg)).await?;
|
||||||
|
tls_stream.get_mut().0.stop_buffering();
|
||||||
|
tokio::io::copy_bidirectional(
|
||||||
|
&mut tls_stream,
|
||||||
|
&mut target_stream,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
.with_kind(crate::ErrorKind::OpenSsl)?,
|
}
|
||||||
)
|
Err(AlpnInfo::Reflect) => {
|
||||||
.await?;
|
for proto in
|
||||||
} else {
|
mid.client_hello().alpn().into_iter().flatten()
|
||||||
tokio::io::copy_bidirectional(
|
{
|
||||||
&mut tls_stream,
|
cfg.alpn_protocols.push(proto.into());
|
||||||
&mut tcp_stream,
|
}
|
||||||
)
|
let mut tls_stream =
|
||||||
.await?;
|
mid.into_stream(Arc::new(cfg)).await?;
|
||||||
|
tls_stream.get_mut().0.stop_buffering();
|
||||||
|
tokio::io::copy_bidirectional(
|
||||||
|
&mut tls_stream,
|
||||||
|
&mut tcp_stream,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
Err(AlpnInfo::Specified(alpn)) => {
|
||||||
|
cfg.alpn_protocols = alpn;
|
||||||
|
let mut tls_stream =
|
||||||
|
mid.into_stream(Arc::new(cfg)).await?;
|
||||||
|
tls_stream.get_mut().0.stop_buffering();
|
||||||
|
tokio::io::copy_bidirectional(
|
||||||
|
&mut tls_stream,
|
||||||
|
&mut tcp_stream,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 503
|
// 503
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ pub async fn attach(
|
|||||||
}
|
}
|
||||||
let (hostname, tor_addr, root_ca) = setup_init(&ctx, password).await?;
|
let (hostname, tor_addr, root_ca) = setup_init(&ctx, password).await?;
|
||||||
*ctx.setup_result.write().await = Some((guid, SetupResult {
|
*ctx.setup_result.write().await = Some((guid, SetupResult {
|
||||||
tor_address: format!("http://{}", tor_addr),
|
tor_address: format!("https://{}", tor_addr),
|
||||||
lan_address: hostname.lan_address(),
|
lan_address: hostname.lan_address(),
|
||||||
root_ca: String::from_utf8(root_ca.to_pem()?)?,
|
root_ca: String::from_utf8(root_ca.to_pem()?)?,
|
||||||
}));
|
}));
|
||||||
@@ -281,7 +281,7 @@ pub async fn execute(
|
|||||||
*ctx.setup_result.write().await = Some((
|
*ctx.setup_result.write().await = Some((
|
||||||
guid,
|
guid,
|
||||||
SetupResult {
|
SetupResult {
|
||||||
tor_address: format!("http://{}", tor_addr),
|
tor_address: format!("https://{}", tor_addr),
|
||||||
lan_address: hostname.lan_address(),
|
lan_address: hostname.lan_address(),
|
||||||
root_ca: String::from_utf8(
|
root_ca: String::from_utf8(
|
||||||
root_ca.to_pem().expect("failed to serialize root ca"),
|
root_ca.to_pem().expect("failed to serialize root ca"),
|
||||||
|
|||||||
@@ -27,31 +27,15 @@
|
|||||||
<section
|
<section
|
||||||
style="
|
style="
|
||||||
padding: 1rem 3rem 2rem 3rem;
|
padding: 1rem 3rem 2rem 3rem;
|
||||||
border: solid #c4c4c5 3px;
|
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
|
border: solid #c4c4c5 3px;
|
||||||
|
border-radius: 20px;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<h2 style="font-variant-caps: all-small-caps">
|
|
||||||
Access from home (LAN)
|
|
||||||
</h2>
|
|
||||||
<p>
|
|
||||||
Visit the address below when you are connected to the same WiFi or
|
|
||||||
Local Area Network (LAN) as your server:
|
|
||||||
</p>
|
|
||||||
<p
|
|
||||||
style="
|
|
||||||
padding: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
overflow: auto;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<code id="lan-addr"></code>
|
|
||||||
</p>
|
|
||||||
<div>
|
<div>
|
||||||
<h3 style="color: #f8546a; font-weight: bold">Important!</h3>
|
<h3 style="color: #f8546a; font-weight: bold">Important!</h3>
|
||||||
<p>
|
<p>
|
||||||
Be sure to
|
Download your server's Root CA and
|
||||||
<a
|
<a
|
||||||
href="https://docs.start9.com/latest/user-manual/connecting/connecting-lan"
|
href="https://docs.start9.com/latest/user-manual/connecting/connecting-lan"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -60,12 +44,10 @@
|
|||||||
>
|
>
|
||||||
follow the instructions
|
follow the instructions
|
||||||
</a>
|
</a>
|
||||||
to establish a secure connection by installing your server's root
|
to establish a secure connection with your server.
|
||||||
certificate authority.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="text-align: center">
|
||||||
<div style="padding: 2rem; text-align: center">
|
|
||||||
<a
|
<a
|
||||||
id="cert"
|
id="cert"
|
||||||
[download]="crtName"
|
[download]="crtName"
|
||||||
@@ -88,12 +70,49 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<section
|
||||||
|
style="
|
||||||
|
padding: 1rem 3rem 2rem 3rem;
|
||||||
|
border: solid #c4c4c5 3px;
|
||||||
|
border-radius: 20px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h2 style="font-variant-caps: all-small-caps">
|
||||||
|
Access from home (LAN)
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
Visit the address below when you are connected to the same WiFi or
|
||||||
|
Local Area Network (LAN) as your server.
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
style="
|
||||||
|
padding: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
overflow: auto;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<code id="lan-addr"></code>
|
||||||
|
</p>
|
||||||
|
|
||||||
<section style="padding: 1rem 3rem 2rem 3rem; border: solid #c4c4c5 3px">
|
|
||||||
<h2 style="font-variant-caps: all-small-caps">
|
<h2 style="font-variant-caps: all-small-caps">
|
||||||
Access on the go (Tor)
|
Access on the go (Tor)
|
||||||
</h2>
|
</h2>
|
||||||
<p>Visit the address below when you are away from home:</p>
|
<p>Visit the address below when you are away from home.</p>
|
||||||
|
<p>
|
||||||
|
<span style="font-weight: bold">Note:</span>
|
||||||
|
This address will only work from a Tor-enabled browser.
|
||||||
|
<a
|
||||||
|
href="https://docs.start9.com/latest/user-manual/connecting/connecting-tor"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
style="color: #6866cc; font-weight: bold; text-decoration: none"
|
||||||
|
>
|
||||||
|
Follow the instructions
|
||||||
|
</a>
|
||||||
|
to get setup.
|
||||||
|
</p>
|
||||||
<p
|
<p
|
||||||
style="
|
style="
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
@@ -104,21 +123,6 @@
|
|||||||
>
|
>
|
||||||
<code id="tor-addr"></code>
|
<code id="tor-addr"></code>
|
||||||
</p>
|
</p>
|
||||||
<div>
|
|
||||||
<h3 style="color: #f8546a; font-weight: bold">Important!</h3>
|
|
||||||
<p>
|
|
||||||
This address will only work from a Tor-enabled browser.
|
|
||||||
<a
|
|
||||||
href="https://docs.start9.com/latest/user-manual/connecting/connecting-tor"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
style="color: #6866cc; font-weight: bold; text-decoration: none"
|
|
||||||
>
|
|
||||||
Follow the instructions
|
|
||||||
</a>
|
|
||||||
to get setup.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export class SuccessPage {
|
|||||||
const ret = await this.api.complete()
|
const ret = await this.api.complete()
|
||||||
if (!this.isKiosk) {
|
if (!this.isKiosk) {
|
||||||
this.torAddress = ret['tor-address']
|
this.torAddress = ret['tor-address']
|
||||||
this.lanAddress = ret['lan-address'].replace('https', 'http')
|
this.lanAddress = ret['lan-address'].replace(/^https:/, 'http:')
|
||||||
this.cert = ret['root-ca']
|
this.cert = ret['root-ca']
|
||||||
|
|
||||||
await this.api.exit()
|
await this.api.exit()
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { Injectable } from '@angular/core'
|
|||||||
import { encodeBase64, pauseFor } from '@start9labs/shared'
|
import { encodeBase64, pauseFor } from '@start9labs/shared'
|
||||||
import {
|
import {
|
||||||
ApiService,
|
ApiService,
|
||||||
CifsRecoverySource,
|
|
||||||
AttachReq,
|
AttachReq,
|
||||||
ExecuteReq,
|
CifsRecoverySource,
|
||||||
CompleteRes,
|
CompleteRes,
|
||||||
|
ExecuteReq,
|
||||||
} from './api.service'
|
} from './api.service'
|
||||||
import * as jose from 'node-jose'
|
import * as jose from 'node-jose'
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ export class MockApiService extends ApiService {
|
|||||||
async complete(): Promise<CompleteRes> {
|
async complete(): Promise<CompleteRes> {
|
||||||
await pauseFor(1000)
|
await pauseFor(1000)
|
||||||
return {
|
return {
|
||||||
'tor-address': 'http://asdafsadasdasasdasdfasdfasdf.onion',
|
'tor-address': 'https://asdafsadasdasasdasdfasdfasdf.onion',
|
||||||
'lan-address': 'https://adjective-noun.local',
|
'lan-address': 'https://adjective-noun.local',
|
||||||
'root-ca': encodeBase64(rootCA),
|
'root-ca': encodeBase64(rootCA),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,15 @@ export class AppComponent implements OnDestroy {
|
|||||||
readonly themeSwitcher: ThemeSwitcherService,
|
readonly themeSwitcher: ThemeSwitcherService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
async ngOnInit() {
|
||||||
|
if (location.hostname !== 'localhost' && location.protocol === 'http:') {
|
||||||
|
// see if site is available securely
|
||||||
|
const res = await fetch(window.location.href.replace(/^http:/, 'https:'))
|
||||||
|
if (res && res.status === 200) {
|
||||||
|
// redirect
|
||||||
|
window.location.protocol = 'https:'
|
||||||
|
}
|
||||||
|
}
|
||||||
this.patch
|
this.patch
|
||||||
.watch$('ui', 'name')
|
.watch$('ui', 'name')
|
||||||
.subscribe(name => this.titleService.setTitle(name || 'StartOS'))
|
.subscribe(name => this.titleService.setTitle(name || 'StartOS'))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
import { Component, Input } from '@angular/core'
|
||||||
import { ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute } from '@angular/router'
|
||||||
import { ModalController, ToastController } from '@ionic/angular'
|
import { ModalController, ToastController } from '@ionic/angular'
|
||||||
import { getPkgId, copyToClipboard } from '@start9labs/shared'
|
import { copyToClipboard, getPkgId } from '@start9labs/shared'
|
||||||
import { getUiInterfaceKey } from 'src/app/services/config.service'
|
import { getUiInterfaceKey } from 'src/app/services/config.service'
|
||||||
import {
|
import {
|
||||||
DataModel,
|
DataModel,
|
||||||
@@ -51,6 +51,7 @@ export class AppInterfacesPage {
|
|||||||
'lan-address': uiAddresses['lan-address']
|
'lan-address': uiAddresses['lan-address']
|
||||||
? 'https://' + uiAddresses['lan-address']
|
? 'https://' + uiAddresses['lan-address']
|
||||||
: '',
|
: '',
|
||||||
|
// leave http for services
|
||||||
'tor-address': uiAddresses['tor-address']
|
'tor-address': uiAddresses['tor-address']
|
||||||
? 'http://' + uiAddresses['tor-address']
|
? 'http://' + uiAddresses['tor-address']
|
||||||
: '',
|
: '',
|
||||||
@@ -69,7 +70,8 @@ export class AppInterfacesPage {
|
|||||||
? 'https://' + addresses['lan-address']
|
? 'https://' + addresses['lan-address']
|
||||||
: '',
|
: '',
|
||||||
'tor-address': addresses['tor-address']
|
'tor-address': addresses['tor-address']
|
||||||
? 'http://' + addresses['tor-address']
|
? // leave http for services
|
||||||
|
'http://' + addresses['tor-address']
|
||||||
: '',
|
: '',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,9 @@ export class AppShowPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async launchHttps() {
|
async launchHttps() {
|
||||||
const { 'lan-address': lanAddress } = await getServerInfo(this.patch)
|
const onTor = this.config.isTor()
|
||||||
window.open(lanAddress)
|
const { 'lan-address': lanAddress, 'tor-address': torAddress } =
|
||||||
|
await getServerInfo(this.patch)
|
||||||
|
onTor ? window.open(torAddress) : window.open(lanAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { Component, Inject } from '@angular/core'
|
|||||||
import {
|
import {
|
||||||
AlertController,
|
AlertController,
|
||||||
LoadingController,
|
LoadingController,
|
||||||
NavController,
|
|
||||||
ModalController,
|
ModalController,
|
||||||
|
NavController,
|
||||||
ToastController,
|
ToastController,
|
||||||
} from '@ionic/angular'
|
} from '@ionic/angular'
|
||||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||||
@@ -306,8 +306,10 @@ export class ServerShowPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async launchHttps() {
|
async launchHttps() {
|
||||||
const { 'lan-address': lanAddress } = await getServerInfo(this.patch)
|
const onTor = this.config.isTor()
|
||||||
window.open(lanAddress)
|
const { 'lan-address': lanAddress, 'tor-address': torAddress } =
|
||||||
|
await getServerInfo(this.patch)
|
||||||
|
onTor ? window.open(torAddress) : window.open(lanAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
addClick(title: string) {
|
addClick(title: string) {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export const mockPatchData: DataModel = {
|
|||||||
version: '0.3.4.3',
|
version: '0.3.4.3',
|
||||||
'last-backup': new Date(new Date().valueOf() - 604800001).toISOString(),
|
'last-backup': new Date(new Date().valueOf() - 604800001).toISOString(),
|
||||||
'lan-address': 'https://adjective-noun.local',
|
'lan-address': 'https://adjective-noun.local',
|
||||||
'tor-address': 'http://myveryownspecialtoraddress.onion',
|
'tor-address': 'https://myveryownspecialtoraddress.onion',
|
||||||
'ip-info': {
|
'ip-info': {
|
||||||
eth0: {
|
eth0: {
|
||||||
ipv4: '10.0.0.1',
|
ipv4: '10.0.0.1',
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export class ConfigService {
|
|||||||
if (this.isLan() && hasLanUi(pkg.manifest.interfaces)) {
|
if (this.isLan() && hasLanUi(pkg.manifest.interfaces)) {
|
||||||
return `https://${lanUiAddress(pkg)}`
|
return `https://${lanUiAddress(pkg)}`
|
||||||
} else {
|
} else {
|
||||||
|
// leave http for services
|
||||||
return `http://${torUiAddress(pkg)}`
|
return `http://${torUiAddress(pkg)}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user