* help ios downlaod .crt and add begin add masked for addresses

* only require and show CA for public domain if addSsl

* fix type and revert i18n const

* feat: add address masking and adjust design (#3088)

* feat: add address masking and adjust design

* update lockfile

* chore: move eye button to actions

* chore: refresh notifications and handle action error

* static width for health check name

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* hide certificate authorities tab

* alpha.17

* add waiting health check status

* remove "on" from waiting message

* reject on abort in `.watch`

* id migration: nostr -> nostr-rs-relay

* health check waiting state

* use interface type for launch button

* better wording for masked

* cleaner

* sdk improvements

* fix type error

* fix notification badge issue

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
Matt Hill
2025-12-31 11:30:57 -07:00
committed by GitHub
parent 96ae532879
commit c9a7f519b9
99 changed files with 1535 additions and 1120 deletions

View File

@@ -94,7 +94,23 @@ impl Public {
..Default::default()
},
gateways: OrdMap::new(),
acme: BTreeMap::new(),
acme: {
let mut acme: BTreeMap<AcmeProvider, AcmeSettings> = Default::default();
acme.insert(
"letsencrypt".parse()?,
AcmeSettings {
contact: Vec::new(),
},
);
#[cfg(feature = "dev")]
acme.insert(
"letsencrypt-staging".parse()?,
AcmeSettings {
contact: Vec::new(),
},
);
acme
},
dns: Default::default(),
},
status_info: ServerStatus {

View File

@@ -472,7 +472,7 @@ fn cert_send(cert: &X509, hostname: &Hostname) -> Result<Response, Error> {
)
.to_lowercase(),
)
.header(http::header::CONTENT_TYPE, "application/x-x509-ca-cert")
.header(http::header::CONTENT_TYPE, "application/octet-stream")
.header(http::header::CONTENT_LENGTH, pem.len())
.header(
http::header::CONTENT_DISPOSITION,

View File

@@ -241,7 +241,7 @@ pub async fn mark_seen_before(
ctx.db
.mutate(|db| {
let n = db.as_private_mut().as_notifications_mut();
for id in n.keys()?.range(..before) {
for id in n.keys()?.range(..=before) {
n.as_idx_mut(&id)
.or_not_found(lazy_format!("Notification #{id}"))?
.as_seen_mut()

View File

@@ -176,7 +176,7 @@ impl S9pk<TmpSource<PackSource>> {
impl TryFrom<ManifestV1> for Manifest {
type Error = Error;
fn try_from(value: ManifestV1) -> Result<Self, Self::Error> {
fn try_from(mut value: ManifestV1) -> Result<Self, Self::Error> {
let default_url = value.upstream_repo.clone();
let mut version = ExtendedVersion::from(
exver::emver::Version::from_str(&value.version)
@@ -190,6 +190,9 @@ impl TryFrom<ManifestV1> for Manifest {
} else if &*value.id == "lightning-terminal" || &*value.id == "robosats" {
version = version.map_upstream(|v| v.with_prerelease(["alpha".into()]));
}
if &*value.id == "nostr" {
value.id = "nostr-rs-relay".parse()?;
}
Ok(Self {
id: value.id,
title: format!("{} (Legacy)", value.title).into(),

View File

@@ -113,7 +113,7 @@ impl Manifest {
if let Some(emulate_as) = &config.emulate_missing_as {
expected.check_file(
Path::new("images")
.join(arch)
.join(emulate_as)
.join(image_id)
.with_extension("squashfs"),
)?;

View File

@@ -24,6 +24,7 @@ impl FromStr for NamedHealthCheckResult {
"success" => NamedHealthCheckResultKind::Success { message },
"disabled" => NamedHealthCheckResultKind::Disabled { message },
"starting" => NamedHealthCheckResultKind::Starting { message },
"waiting" => NamedHealthCheckResultKind::Waiting { message },
"loading" => NamedHealthCheckResultKind::Loading {
message: message.unwrap_or_default(),
},
@@ -61,6 +62,7 @@ pub enum NamedHealthCheckResultKind {
Success { message: Option<String> },
Disabled { message: Option<String> },
Starting { message: Option<String> },
Waiting { message: Option<String> },
Loading { message: String },
Failure { message: String },
}
@@ -89,6 +91,13 @@ impl std::fmt::Display for NamedHealthCheckResult {
write!(f, "{name}: Starting")
}
}
NamedHealthCheckResultKind::Waiting { message } => {
if let Some(message) = message {
write!(f, "{name}: Waiting ({message})")
} else {
write!(f, "{name}: Waiting")
}
}
NamedHealthCheckResultKind::Loading { message } => {
write!(f, "{name}: Loading ({message})")
}

View File

@@ -56,8 +56,9 @@ mod v0_4_0_alpha_13;
mod v0_4_0_alpha_14;
mod v0_4_0_alpha_15;
mod v0_4_0_alpha_16;
mod v0_4_0_alpha_17;
pub type Current = v0_4_0_alpha_16::Version; // VERSION_BUMP
pub type Current = v0_4_0_alpha_17::Version; // VERSION_BUMP
impl Current {
#[instrument(skip(self, db))]
@@ -175,7 +176,8 @@ enum Version {
V0_4_0_alpha_13(Wrapper<v0_4_0_alpha_13::Version>),
V0_4_0_alpha_14(Wrapper<v0_4_0_alpha_14::Version>),
V0_4_0_alpha_15(Wrapper<v0_4_0_alpha_15::Version>),
V0_4_0_alpha_16(Wrapper<v0_4_0_alpha_16::Version>), // VERSION_BUMP
V0_4_0_alpha_16(Wrapper<v0_4_0_alpha_16::Version>),
V0_4_0_alpha_17(Wrapper<v0_4_0_alpha_17::Version>), // VERSION_BUMP
Other(exver::Version),
}
@@ -234,7 +236,8 @@ impl Version {
Self::V0_4_0_alpha_13(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_14(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_15(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_16(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP
Self::V0_4_0_alpha_16(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_17(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP
Self::Other(v) => {
return Err(Error::new(
eyre!("unknown version {v}"),
@@ -285,7 +288,8 @@ impl Version {
Version::V0_4_0_alpha_13(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_14(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_15(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_16(Wrapper(x)) => x.semver(), // VERSION_BUMP
Version::V0_4_0_alpha_16(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_17(Wrapper(x)) => x.semver(), // VERSION_BUMP
Version::Other(x) => x.clone(),
}
}

View File

@@ -286,6 +286,18 @@ impl VersionT for Version {
ErrorKind::Filesystem,
));
}
if tokio::fs::metadata("/media/startos/data/package-data/volumes/nostr")
.await
.is_ok()
{
tokio::fs::rename(
"/media/startos/data/package-data/volumes/nostr",
"/media/startos/data/package-data/volumes/nostr-rs-relay",
)
.await?;
}
// Should be the name of the package
let mut paths = tokio::fs::read_dir(path).await?;
while let Some(path) = paths.next_entry().await? {

View File

@@ -0,0 +1,53 @@
use exver::{PreReleaseSegment, VersionRange};
use super::v0_3_5::V0_3_0_COMPAT;
use super::{VersionT, v0_4_0_alpha_16};
use crate::db::model::public::AcmeSettings;
use crate::net::acme::AcmeProvider;
use crate::prelude::*;
lazy_static::lazy_static! {
static ref V0_4_0_alpha_17: exver::Version = exver::Version::new(
[0, 4, 0],
[PreReleaseSegment::String("alpha".into()), 17.into()]
);
}
#[derive(Clone, Copy, Debug, Default)]
pub struct Version;
impl VersionT for Version {
type Previous = v0_4_0_alpha_16::Version;
type PreUpRes = ();
async fn pre_up(self) -> Result<Self::PreUpRes, Error> {
Ok(())
}
fn semver(self) -> exver::Version {
V0_4_0_alpha_17.clone()
}
fn compat(self) -> &'static VersionRange {
&V0_3_0_COMPAT
}
#[instrument(skip_all)]
fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result<Value, Error> {
let acme = db["public"]["serverInfo"]["network"]["acme"]
.as_object_mut()
.or_not_found("public.serverInfo.network.acme")?;
let letsencrypt =
InternedString::intern::<&str>("letsencrypt".parse::<AcmeProvider>()?.as_ref());
if !acme.contains_key(&letsencrypt) {
acme.insert(
letsencrypt,
to_value(&AcmeSettings {
contact: Vec::new(),
})?,
);
}
Ok(Value::Null)
}
fn down(self, _db: &mut Value) -> Result<(), Error> {
Ok(())
}
}