fix(config): signal gate is useless since needs admin work to activate anyway

Lewis: May this revision serve well! <lu5a@proton.me>
This commit is contained in:
Lewis
2026-05-24 20:05:59 +03:00
parent 036c317fd6
commit 86c5995568
8 changed files with 42 additions and 74 deletions

View File

@@ -9,7 +9,6 @@ use tranquil_pds::state::AppState;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SignalStatusOutput {
pub enabled: bool,
pub linked: bool,
}
@@ -23,13 +22,12 @@ pub async fn get_signal_status(
State(state): State<AppState>,
_auth: Auth<Admin>,
) -> Result<Json<SignalStatusOutput>, ApiError> {
let enabled = tranquil_config::get().signal.enabled;
let linked = match &state.signal_sender {
Some(slot) => slot.is_linked().await,
None => false,
};
Ok(Json(SignalStatusOutput { enabled, linked }))
Ok(Json(SignalStatusOutput { linked }))
}
pub async fn link_signal_device(

View File

@@ -5,7 +5,7 @@ use tranquil_pds::BUILD_VERSION;
use tranquil_pds::state::AppState;
use tranquil_pds::util::{discord_app_id, discord_bot_username, telegram_bot_username};
fn get_available_comms_channels() -> Vec<CommsChannel> {
async fn get_available_comms_channels(state: &AppState) -> Vec<CommsChannel> {
let cfg = tranquil_config::get();
let mut channels = vec![CommsChannel::Email];
if cfg.discord.bot_token.is_some() {
@@ -14,7 +14,9 @@ fn get_available_comms_channels() -> Vec<CommsChannel> {
if cfg.telegram.bot_token.is_some() {
channels.push(CommsChannel::Telegram);
}
if cfg.signal.enabled {
if let Some(slot) = &state.signal_sender
&& slot.is_linked().await
{
channels.push(CommsChannel::Signal);
}
channels
@@ -66,7 +68,7 @@ pub struct DescribeServerOutput {
pub telegram_bot_username: Option<String>,
}
pub async fn describe_server() -> Json<DescribeServerOutput> {
pub async fn describe_server(State(state): State<AppState>) -> Json<DescribeServerOutput> {
let cfg = tranquil_config::get();
let pds_hostname = &cfg.server.hostname;
@@ -82,7 +84,7 @@ pub async fn describe_server() -> Json<DescribeServerOutput> {
email: cfg.server.contact_email.clone(),
},
version: BUILD_VERSION,
available_comms_channels: get_available_comms_channels(),
available_comms_channels: get_available_comms_channels(&state).await,
self_hosted_did_web_enabled: is_self_hosted_did_web_enabled(),
discord_bot_username: discord_bot_username().map(String::from),
discord_app_id: discord_app_id().map(String::from),

View File

@@ -141,9 +141,6 @@ pub struct TranquilConfig {
#[config(nested)]
pub telegram: TelegramConfig,
#[config(nested)]
pub signal: SignalConfig,
#[config(nested)]
pub notifications: NotificationConfig,
@@ -1071,14 +1068,6 @@ pub struct TelegramConfig {
pub webhook_secret: Option<String>,
}
#[derive(Debug, Config)]
pub struct SignalConfig {
/// Protocol state is stored in postgres' signal_* tables.
/// Link a device via the admin API before enabling.
#[config(env = "SIGNAL_ENABLED", default = false)]
pub enabled: bool,
}
#[derive(Debug, Config)]
pub struct NotificationConfig {
/// Polling interval in milliseconds for the comms queue.

View File

@@ -106,19 +106,15 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
let mut state = AppState::new(shutdown.clone()).await?;
let signal_sender = if tranquil_config::get().signal.enabled {
let slot = Arc::new(tranquil_signal::SignalSlot::default());
state = state.with_signal_sender(slot.clone());
if let Some(provider) = &state.signal_store_provider
&& let Some(client) = provider.load_signal_client(shutdown.clone()).await
{
slot.set_client(client).await;
info!("Signal device already linked");
}
Some(SignalSender::new(slot))
} else {
None
};
let signal_slot = Arc::new(tranquil_signal::SignalSlot::default());
state = state.with_signal_sender(signal_slot.clone());
if let Some(provider) = &state.signal_store_provider
&& let Some(client) = provider.load_signal_client(shutdown.clone()).await
{
signal_slot.set_client(client).await;
info!("Signal device linked");
}
let signal_sender = SignalSender::new(signal_slot);
tranquil_sync::listener::start_sequencer_listener(state.clone()).await;
@@ -223,10 +219,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
comms_service = comms_service.register_sender(telegram_sender);
}
if let Some(sender) = signal_sender {
info!("Signal comms enabled");
comms_service = comms_service.register_sender(sender);
}
comms_service = comms_service.register_sender(signal_sender);
let comms_handle = tokio::spawn(comms_service.run(shutdown.clone()));

View File

@@ -352,7 +352,7 @@ impl SignalClient {
let manager = init_rx
.await
.ok()?
.map_err(|e| tracing::error!(error = %e, "failed to load registered signal manager"))
.map_err(|e| tracing::debug!(error = %e, "no linked signal device"))
.ok()?;
Self::from_manager(manager, shutdown)

View File

@@ -510,15 +510,6 @@
# Can also be specified via environment variable `TELEGRAM_WEBHOOK_SECRET`.
#webhook_secret =
[signal]
# Protocol state is stored in postgres' signal_* tables.
# Link a device via the admin API before enabling.
#
# Can also be specified via environment variable `SIGNAL_ENABLED`.
#
# Default value: false
#enabled = false
[notifications]
# Polling interval in milliseconds for the comms queue.
#

View File

@@ -65,7 +65,6 @@
let logoPreview = $state<string | null>(null)
let serverConfigLoading = $state(false)
let signalEnabled = $state(false)
let signalLinked = $state(false)
let signalQr = $state<string | null>(null)
let signalLoading = $state(false)
@@ -236,7 +235,6 @@
if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return
try {
const status = await api.getSignalStatus(session.accessJwt)
signalEnabled = status.enabled
signalLinked = status.linked
signalPollErrors = 0
if (signalLinked && signalQr) {
@@ -401,33 +399,31 @@
</form>
</section>
{#if signalEnabled}
<section class="config-section">
<div class="section-header-row">
<h3>{$_('admin.signalIntegration')}</h3>
{#if signalLinked}
<span class="badge verified">{$_('admin.signalLinked')}</span>
{:else if !signalQr}
<span class="badge unverified">{$_('admin.signalNotLinked')}</span>
{/if}
</div>
{#if signalQr}
<div class="qr-container">
<p>{$_('admin.signalLinking')}</p>
<img src="data:image/png;base64,{signalQr}" alt="Signal QR" class="qr-code" />
</div>
{:else if signalLinked}
<button type="button" class="danger sm" onclick={unlinkSignal} disabled={signalLoading}>
{$_('admin.signalUnlinkDevice')}
</button>
{:else}
<button type="button" onclick={linkSignal} disabled={signalLoading}>
{signalLoading ? $_('common.loading') : $_('admin.signalLinkDevice')}
</button>
<section class="config-section">
<div class="section-header-row">
<h3>{$_('admin.signalIntegration')}</h3>
{#if signalLinked}
<span class="badge verified">{$_('admin.signalLinked')}</span>
{:else if !signalQr}
<span class="badge unverified">{$_('admin.signalNotLinked')}</span>
{/if}
</section>
{/if}
</div>
{#if signalQr}
<div class="qr-container">
<p>{$_('admin.signalLinking')}</p>
<img src="data:image/png;base64,{signalQr}" alt="Signal QR" class="qr-code" />
</div>
{:else if signalLinked}
<button type="button" class="danger sm" onclick={unlinkSignal} disabled={signalLoading}>
{$_('admin.signalUnlinkDevice')}
</button>
{:else}
<button type="button" onclick={linkSignal} disabled={signalLoading}>
{signalLoading ? $_('common.loading') : $_('admin.signalLinkDevice')}
</button>
{/if}
</section>
<section class="stats-section">
<div class="section-header-row">

View File

@@ -255,7 +255,6 @@ export interface ServerStats {
}
export interface SignalStatus {
enabled: boolean;
linked: boolean;
}