Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ts/background.preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,16 @@ export async function startApp(): Promise<void> {
log.info('Observer Vault: Setting universal expire timer to 30 seconds');
await universalExpireTimer.set(durations.DurationInSeconds.fromSeconds(30));

// Observer Vault: Initialize settings (stories off, camera/mic disabled)
drop(
(async () => {
const { initializeObserverVaultSettings } = await import(
'./observervault/initializeSettings.preload.js'
);
await initializeObserverVaultSettings();
})()
);

restoreRemoteConfigFromStorage({
storage: itemStorage,
});
Expand Down
72 changes: 72 additions & 0 deletions ts/observervault/initializeSettings.preload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2026 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only

/**
* Observer Vault Settings Initialization
*
* This module ensures Observer Vault-specific settings are configured on launch.
*/

import { createLogger } from '../logging/log.std.js';
import { setStoriesDisabled } from '../util/stories.preload.js';

const log = createLogger('observervault/initializeSettings');

/**
* Initializes Observer Vault settings on application launch.
* This ensures:
* 1. Stories are disabled
* 2. Microphone access is disabled
* 3. Camera access is disabled
*/
export async function initializeObserverVaultSettings(): Promise<void> {
log.info('Initializing Observer Vault settings...');

// 1. Disable stories if not already disabled
try {
const { getStoriesDisabled } = await import('../util/stories.preload.js');
const storiesDisabled = getStoriesDisabled();

if (!storiesDisabled) {
log.info('Stories not disabled, disabling now...');
await setStoriesDisabled(true);
log.info('Stories disabled successfully');
} else {
log.info('Stories already disabled');
}
} catch (error) {
log.error('Failed to disable stories:', error);
}

// 2. Disable microphone access
try {
const hasMediaPermissions = await window.Events.getMediaPermissions();

if (hasMediaPermissions !== false) {
log.info('Microphone access not disabled, disabling now...');
await window.IPC.setMediaPermissions(false);
log.info('Microphone access disabled successfully');
} else {
log.info('Microphone access already disabled');
}
} catch (error) {
log.error('Failed to disable microphone access:', error);
}

// 3. Disable camera access
try {
const hasMediaCameraPermissions = await window.Events.getMediaCameraPermissions();

if (hasMediaCameraPermissions !== false) {
log.info('Camera access not disabled, disabling now...');
await window.IPC.setMediaCameraPermissions(false);
log.info('Camera access disabled successfully');
} else {
log.info('Camera access already disabled');
}
} catch (error) {
log.error('Failed to disable camera access:', error);
}

log.info('Observer Vault settings initialization complete');
}
52 changes: 2 additions & 50 deletions ts/observervault/messageHandler.preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ import { getMessageById } from '../messages/getMessageById.preload.js';

const log = createLogger('observervault/messageHandler');

// The auto-reply message for text messages
const AUTO_REPLY_MESSAGE = "sorry I'm busy";

// The desired disappearing messages timer (30 seconds)
const DESIRED_EXPIRE_TIMER = DurationInSeconds.fromSeconds(30);

Expand Down Expand Up @@ -315,35 +312,6 @@ export async function ensureDisappearingMessagesTimer(
}
}

/**
* Sends an auto-reply message to the conversation.
*/
export async function sendAutoReply(
conversation: ConversationModel
): Promise<void> {
const logId = `sendAutoReply/${conversation.idForLogging()}`;

log.info(`${logId}: Sending auto-reply message`);

try {
await conversation.enqueueMessageForSend(
{
attachments: [],
body: AUTO_REPLY_MESSAGE,
},
{
timestamp: Date.now(),
}
);
log.info(`${logId}: Auto-reply message sent successfully`);
} catch (error) {
log.error(
`${logId}: Failed to send auto-reply:`,
error instanceof Error ? error.message : String(error)
);
}
}

/**
* Handles an incoming message for Observer Vault.
* This is called from handleDataMessage for incoming messages.
Expand Down Expand Up @@ -384,24 +352,8 @@ export async function handleObserverVaultIncomingMessage(
`[Observer Vault] ${logId}: Message has ${attachments.length} attachment(s), starting download`
);
drop(downloadAllAttachments(message, conversation));
// Don't send auto-reply for attachment messages
return true;
}

// Get the message body
const body = message.get('body');

// If the message has a text body, send an auto-reply
if (body && body.trim().length > 0) {
log.info(`${logId}: Received text message, sending auto-reply`);
drop(sendAutoReply(conversation));
return true;
}

// For messages without text or attachments (e.g., reactions), we still process them
// but don't send an auto-reply
log.info(
`${logId}: Received non-text/non-attachment message, no auto-reply needed`
);
return false;
// Message processed (no auto-reply sent)
return true;
}
Loading