Об этом проекте
Wappie представляет собой многопользовательский сервер WhatsApp API с запечатанным архивом и веб-клиентом, использующим тот же API. Он соединяет бизнес-системы с WhatsApp через HTTP и WebSocket, предлагая общие рабочие пространства, разрешения на уровне номеров и клиент для обмена сообщениями. Сервер, CLI, веб-клиент и базовое администрирование распространяются по лицензии Apache-2.0; управляемый хостинг и коммерческий биллинг поддерживаются отдельно, пилотный хостинг доступен только по приглашениям и бесплатен, а платежи там имитируются.
Функционально сервер сопрягает устройство WhatsApp через терминал с помощью восьмизначного кода (вводится в разделе «Связанные устройства») или QR-кода, отображаемого в терминале, после чего запечатывает входящий трафик этого устройства. Система обрабатывает синхронизацию истории, правки проектов, отзывы и реакции, фиксирует квитанции и отслеживает версию сообщения на экране каждого читателя. Входящие медиафайлы хранятся в том виде, в котором их предоставляет Meta CDN; поддерживаются загрузка и отправка исходящих медиа, а также режим «просмотра один раз». Реализованы структурированный контент (геолокация, опросы, контакты, события), контакты, имена и фотографии профиля, дозагрузка по требованию, а также слой переписки со счетчиками непрочитанных, галочками, статусом присутствия, группами и опросами. Доступ осуществляется через CLI-инструмент (`wsctl`) и HTTP/WebSocket API с хостинг-эндпоинтом и `/v1/ws` для WebSocket.
Центральным элементом проекта является модель защиты архива. Медиафайлы WhatsApp приходят уже зашифрованными AES-256-CBC с HMAC (encrypt-then-MAC) с использованием 32-байтового ключа медиа; шифротекст хранится в исходном виде, и только ключ медиа запечатывается открытым ключом устройства. Тела сообщений запечатываются с помощью HPKE (RFC 9180, X25519 + HKDF-SHA256 + AES-256-GCM) под ключом контента, охватывающим пакет данных, что в README обосновано стоимостью, а не пропускной способностью. Сервер хранит только открытые ключи: он может запечатывать, но не может открывать данные. Для каждого устройства генерируется пара ключей архива тем клиентом, который выполнил сопряжение; закрытая часть запечатывается открытым ключом каждого аккаунта, имеющего право чтения этого устройства (предоставление ключа), и затем удаляется. Закрытые ключи аккаунтов генерируются в браузере при регистрации, оборачиваются ключом, производным от Argon2id и привязанным к адресу аккаунта, и никогда не передаются; код восстановления оборачивает тот же ключ второй раз. Браузер выполняет HPKE, обработку ключей контента, расшифровку тел сообщений, имен контактов, фотографий профиля и вложений внутри страницы.
Разрешения многоуровневы: API-ключи имеют область действия `read`, `send` или `full`; участник имеет доступ только к предоставленным ему устройствам; владелец или администратор имеет доступ к конверту каждого устройства и может сопрягать их, предоставлять права, создавать ключи и переключать устройство между режимами «скрытого» и «громкого»; ни одна область действия не дает доступа к конфигурации тенанта. Сторонним организациям предоставляется сервисный аккаунт — пара ключей без пароля, которой предоставляются устройства, как обычному человеку, и доступ к которой осуществляется через API-ключ. Хранение данных по умолчанию отключено; тенант может установить окно хранения, которое сервер ежечасно применяет к сообщениям, квитанциям, событиям групп и вложениям, в то время как чаты и контакты сохраняются. Человека можно стереть из архива на всех устройствах, а удаление устройства или сброс архива удаляет соответствующие объекты вложений из хранилища. Логи маскируют идентификаторы на всех уровнях.
Для локального запуска требуется PostgreSQL 18 или новее для `uuidv7()` и роль не-суперпользователя, так как суперпользователи обходят безопасность на уровне строк (RLS). Объектное хранилище опционально: если оно не настроено, вложения ставятся в очередь в базе данных до появления хранилища. Цель `make dev-up` запускает Postgres и MinIO в Docker. Тестовые цели охватывают форматирование, проверку, макет, тесты с проверкой состояний гонки (race-enabled), проверку типов и сборку браузерного клиента, покрытие и фаззинг; каждый тест запускается в собственной схеме Postgres. Веб-клиент собирается с помощью Vite в `web/dist` и раздается через `WS_WEB_DIR`; ничего не встраивается в бинарный файл Go, и при отсутствии сборки сервер предоставляет только API. Во время разработки сервер Vite проксирует `/v1` на порт Go, так как обработчик websocket принимает соединения только с того же источника (same-origin).
В README четко указаны ограничения. Злоумышленник, запустивший код на живом сервере, видит открытый текст в промежутке между расшифровкой Signal, запечатыванием и сохранением, поэтому запечатывание при хранении защищает от кражи диска, утечки бэкапа или дампа базы данных, но не от компрометации процесса. Хранилище сессий whatsmeow должно оставаться доступным для процесса; тот, кто украдет его, может выдать себя за устройство и читать новые сообщения, но не архив. Исходящий текст и медиа проходят в открытом виде, так как загрузка WhatsApp принимает только открытый текст; входящие медиа никогда не расшифровываются на стороне сервера. Метаданные вложений (тип, размер, размеры, длительность, хеши) и метаданные маршрутизации, включая квитанции, доступны для чтения, поэтому дамп базы данных раскрывает социальный граф и информацию о том, кто, что и когда читал, но не само содержимое. Отзыв прав доступа прекращает возможность повторного получения ключа, но не может отозвать уже разблокированную копию, так как ключ находился в браузере. Потеря всех путей доступа приводит к безвозвратной потере архива для всех. Материалы сессии браузера хранятся в IndexedDB в виде шифротекста под неэкстрагируемыми ключами WebCrypto, а клиент поставляется с политикой безопасности контента (CSP) и не загружает сторонний JavaScript.
Таблица статуса перечисляет завершенные этапы: от скелета, миграций и криптографии медиа до сопряжения, приема данных, проекции правок/отзывов/реакций, входящих и исходящих медиа, синхронизации истории, повторных попыток медиа, контактов, дозагрузки по требованию, веб-клиента, ключей устройств и аккаунтов, слоя переписки, режима инкогнито и квот, а также прохода аудита безопасности; консоль администратора указана как следующий этап. Векторы перекрестных тестов генерируются в Go и открываются обеими реализациями, включая негативные случаи (например, перенос блоба в другую строку или представление его под другим типом), чтобы браузерный клиент не мог молча соглашаться только с самим собой. Инструмент `seeddemo` записывает небольшой фейковый разговор через реальный конвейер приема данных для разработки клиента без необходимости сопряжения телефона.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.