Skip to content

Whatsapp channel - DB Auth state#162

Open
leandrogavidia wants to merge 11 commits into
HCF-STUDIOS:mainfrom
leandrogavidia:whatsapp-channel
Open

Whatsapp channel - DB Auth state#162
leandrogavidia wants to merge 11 commits into
HCF-STUDIOS:mainfrom
leandrogavidia:whatsapp-channel

Conversation

@leandrogavidia
Copy link
Copy Markdown
Contributor

@leandrogavidia leandrogavidia commented May 28, 2026

This change moves WhatsApp Web auth state out of the local ~/.openhermit/credentials/whatsapp/... folder and into encrypted PostgreSQL-backed channel credentials.

What changed:

  • Added a DB-backed credential store for channel-owned auth material.
  • Wired channel manifests so WhatsApp can read/write scoped credentials through the gateway.
  • Replaced Baileys useMultiFileAuthState() with a DB auth adapter.
  • WhatsApp setup now stores a durable auth_profile on the channel row instead of an auth_dir path.
  • Legacy auth_dir configs are no longer supported; if one is present, the adapter best-effort deletes the old folder and requires setup again.

Why:

  • This matches OpenHermit’s storage model: durable internal state belongs in the database, not on a host-local folder.
  • It makes WhatsApp credentials portable across gateway restarts and avoids depending on filesystem state.

I also updated the WhatsApp docs and storage docs to reflect the new model.

image

Summary by CodeRabbit

  • New Features

    • WhatsApp channel now uses encrypted, database-backed channel credentials and an auth profile (replacing filesystem auth dirs); gateway can provide scoped credential stores for channels.
  • Documentation

    • Updated architecture, storage model, channel docs, and WhatsApp setup docs to describe channel credential storage, encryption behavior, and migration notes.
  • Tests

    • Added/updated tests covering DB-backed credential store, WhatsApp auth-state, setup flow, and manifest/startup behavior.

Review Change Stack

…g, and setup process

- Added message formatting functions for WhatsApp, including markdown conversion and message splitting.
- Implemented JID normalization and validation functions to handle WhatsApp user and group identifiers.
- Created a manifest for the WhatsApp channel plugin, defining configuration fields and startup logic.
- Developed a setup process for linking WhatsApp accounts, including QR code handling and session management.
- Introduced a WhatsApp API class for sending messages and managing socket connections.
- Added tests for bot functionality, bridge message acceptance, JID utilities, manifest validation, and setup processes.
- Configured TypeScript build and type-checking settings for the WhatsApp channel.
- Introduced `ChannelCredentialStore` interface for managing channel-owned credentials.
- Added `DbChannelCredentialStore` implementation for persistent storage of channel credentials in PostgreSQL.
- Updated WhatsApp API to utilize the new credential store instead of the legacy `auth_dir`.
- Created tests for the new credential store functionality and updated existing tests to reflect changes.
- Modified documentation to describe the new storage model for channel credentials.
- Removed references to `auth_dir` in favor of `auth_profile` for WhatsApp integration.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cf9da489-ee02-4551-87fd-82d90e320ace

📥 Commits

Reviewing files that changed from the base of the PR and between 52cb370 and ef53dd5.

📒 Files selected for processing (1)
  • packages/store/src/impl/channel-credential-store.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/store/src/impl/channel-credential-store.ts

📝 Walkthrough

Walkthrough

Adds an encrypted, scoped channel credential store (protocol + schema + migration), a Postgres-backed encrypted implementation, WhatsApp auth-state and setup refactor to use credential profiles instead of filesystem auth_dir, gateway wiring to expose scoped credential stores, tests, and documentation updates.

Changes

Database-Backed Channel Credentials

Layer / File(s) Summary
Protocol & Database Foundation
packages/protocol/src/index.ts, packages/store/src/schema.ts, packages/store/drizzle/0032_channel_credentials.sql, packages/store/drizzle/meta/_journal.json
ChannelCredentialStore interface added to ChannelContext and ChannelSetupContext; agent_channel_credentials Postgres table and migration added with composite primary key on (agent_id, channel_type, profile, key) and index.
Credential Store Implementation
packages/store/src/impl/channel-credential-store.ts, packages/store/src/impl/index.ts, packages/store/src/index.ts, apps/agent/test/channel-credential-store.test.ts
DbChannelCredentialStore implemented: encryption/decryption, open/close, scoped adapter, CRUD, transactional replace/clear; tests validate encryption round-trip, scoping, replace behavior, and scoped interface.
WhatsApp Auth State
apps/channels/whatsapp/src/db-auth-state.ts, apps/channels/whatsapp/test/db-auth-state.test.ts
useDbAuthState loads/persists Baileys auth via ChannelCredentialStore, provides async keys API with proto handling for app-state-sync-key, and saveCreds; tests verify serialization, keys, and proto rehydration.
WhatsApp Setup Refactor
apps/channels/whatsapp/src/setup.ts, apps/channels/whatsapp/test/setup.test.ts
Setup flows changed from filesystem authDir to authProfile + credential store; adds removeLegacyAuthDir, manages temp profiles, promotes linked creds to DEFAULT_AUTH_PROFILE, and updates lifecycle tests (QR flow, promotion, cleanup, abandoned sessions).
WhatsApp Manifest & API
apps/channels/whatsapp/src/manifest.ts, apps/channels/whatsapp/src/whatsapp-api.ts, apps/channels/whatsapp/src/index.ts, apps/channels/whatsapp/test/manifest.test.ts
Manifest requires a credential store at startup, defaults auth_profile: 'default', removes auth_dir from UI, validates linked auth, and instantiates WhatsAppApi using credentialStore + authProfile; public exports updated. Tests assert missing-store failures and legacy auth_dir rejection.
Gateway Integration
apps/gateway/src/app.ts, apps/gateway/src/channel-pool.ts, apps/gateway/src/index.ts
Gateway conditionally opens DbChannelCredentialStore when DATABASE_URL and OPENHERMIT_SECRETS_KEY are set and threads a scoped credentialStore into setupContext and channel startup paths.
Documentation
README.md, docs/architecture.md, docs/storage-model.md, docs/channel-adapter.md, docs/manual/17-channels.md, apps/channels/whatsapp/README.md
Docs updated to describe agent_channel_credentials, encryption using OPENHERMIT_SECRETS_KEY, local-dev fallback behavior, WhatsApp auth_profile usage, and QR pairing persistence/migration guidance.

Sequence Diagram

sequenceDiagram
  participant User
  participant Setup as Setup Flow
  participant Store as ChannelCredentialStore
  participant API as WhatsApp API
  participant Baileys
  
  User->>Setup: Begin QR linking
  Setup->>Store: Create temp auth profile
  Setup->>Baileys: Initialize with useDbAuthState
  Baileys->>Store: Load/init credentials
  Baileys->>User: Display QR code
  User->>User: Scan with WhatsApp
  Setup->>Setup: Poll for completion
  Baileys->>Store: Save linked creds
  Setup->>Store: Promote to DEFAULT_AUTH_PROFILE
  Setup->>User: Linking complete
  
  Note over API: Runtime Boot
  API->>Store: Load credentials for auth_profile
  Store->>API: Decrypt & return creds
  API->>Baileys: Initialize auth state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • HCF-STUDIOS/openhermit#88: Overlaps gateway ChannelPool/startup wiring changes and context propagation at the channel startup integration points.

Poem

🐰 Secrets tucked in rows so deep,
Encrypted keys the database keeps,
QR scanned, profiles take their place,
No folders roam, no stray auth trace,
The rabbit hops—secure, with grace.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Whatsapp channel - DB Auth state' directly describes the main change: migrating WhatsApp authentication state from local filesystem to database-backed storage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@leandrogavidia leandrogavidia changed the title Whatsapp channel Whatsapp channel - DB Auth state May 28, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/store/src/impl/channel-credential-store.ts`:
- Around line 23-31: The open method may leak the pg.Pool if initialization
fails; wrap creation/initialization (the new pg.Pool, await pool.query('SELECT
1'), drizzle(...), and new DbChannelCredentialStore(...)) in a try/catch and
call pool.end() (or pool.close) in the catch before rethrowing the error; only
set store.pool after all initialization succeeds (i.e., after drizzle and
DbChannelCredentialStore are created) so failures trigger pool cleanup,
referencing the open function, the pool variable, drizzle(...), and
DbChannelCredentialStore/ secretsKeyFromEnv() in your changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 85ec97c8-ec52-4818-9814-0294c9622140

📥 Commits

Reviewing files that changed from the base of the PR and between 5b43484 and 52cb370.

📒 Files selected for processing (25)
  • README.md
  • apps/agent/test/channel-credential-store.test.ts
  • apps/channels/whatsapp/README.md
  • apps/channels/whatsapp/src/db-auth-state.ts
  • apps/channels/whatsapp/src/index.ts
  • apps/channels/whatsapp/src/manifest.ts
  • apps/channels/whatsapp/src/setup.ts
  • apps/channels/whatsapp/src/whatsapp-api.ts
  • apps/channels/whatsapp/test/db-auth-state.test.ts
  • apps/channels/whatsapp/test/manifest.test.ts
  • apps/channels/whatsapp/test/setup.test.ts
  • apps/gateway/src/app.ts
  • apps/gateway/src/channel-pool.ts
  • apps/gateway/src/index.ts
  • docs/architecture.md
  • docs/channel-adapter.md
  • docs/manual/17-channels.md
  • docs/storage-model.md
  • packages/protocol/src/index.ts
  • packages/store/drizzle/0032_channel_credentials.sql
  • packages/store/drizzle/meta/_journal.json
  • packages/store/src/impl/channel-credential-store.ts
  • packages/store/src/impl/index.ts
  • packages/store/src/index.ts
  • packages/store/src/schema.ts

Comment thread packages/store/src/impl/channel-credential-store.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant