Главная страница в мобильном и веб приложении
Главная страница в мобильном и веб приложении

Я открываю ленту и ищу что-то живое среди рекламы и хлама. Потом комментарии, где непонятно, сколько аккаунтов вообще люди. Потом чат, который может прочитать кто-то третий, а я об этом не узнаю: разработчик, который продаёт базу, старший брат или алгоритм, которому переписку отдали "для безопасности".

Я устал. И я собираю то, чего мне в этом не хватает: соцсеть, в которой спокойно находиться, свободно говорить и которую нельзя забрать, оставив людей ни с чем. Дальше не обещания, а то, что уже лежит в открытом репозитории.

Веб: https://social.flora-s.net/

Мобильное приложение: https://social.flora-s.net/download

Гитхаб: https://github.com/effka11/Flora.Ecosystem
⠀

Что уже можно открыть

Flora – открытая некоммерческая социальная экосистема. Код сообщества под AGPL-3.0-only, стек – Rust и TypeScript: HTTP-хост flora-api, веб на Next.js 16, мобильный клиент на Expo, данные в PostgreSQL. Это модульный монолит и отдельные продукты рядом: соцсеть, шифрование, лента, поиск, кодеки. Социальная сеть их собирает, они от неё не зависят.

Сейчас альфа, и ей уже можно пользоваться. После входа есть лента, посты, комментарии, сообщества, подписки, сообщения, музыка и поиск. Рекламы, платного продвижения и платной косметики статуса нет. Брендовые посты, если появляются, идут по правилам обычных и помечаются. Выключатель "убрать брендированное" я ещё разрабатываю, в настройках его пока нет.

Я выпускаю версии, читаю обратную связь и помогаю тем, кто заходит. Помощь с разработкой тоже принимаю.

Поднять локально: Node.js 20.19 или новее, Rust, Docker, PostgreSQL. Дальше npm install и скрипты из репозитория: база, API на порту 5290, веб на порту 3000.
⠀

Сквозное шифрование

Основа переписки – свой протокол FSCP, версия v1. Сообщение закрывается на устройстве. Сервер хранит шифртекст, публичные ключи, запечатанный бэкап ключей, параметры KDF, список устройств и служебное: кто, когда, в каком диалоге, какого размера. Plaintext, приватных ключей и ключа "для поддержки" у него нет. Чужой человек с дампом базы текст не прочитает.

На каждое сообщение генерируется свой 32-байтовый messageKey. Тело (текст или описание вложений) шифруется XChaCha20-Poly1305. Для каждого получателя, включая ваши собственные устройства, делается отдельный конверт: эфемерный X25519, HKDF-SHA-256, затем тем же XChaCha20-Poly1305 заворачивается только messageKey. Конверт подписывается Ed25519. На этом слое AES-GCM запрещён. Байты файла – отдельный объект AES-GCM, а ключ файла лежит внутри уже закрытого тела.

Второе устройство в таких мессенджерах обычно ломает схему: либо сидишь на одном, либо таскаешь ключи руками. Во Flora вы входите в аккаунт. Бэкап ключей скачивается и открывается паролем прямо на этом устройстве. Это отдельный Argon2id, не хеш пароля, которым вы логинитесь. На десктопе параметры такие: 64 МиБ памяти, 3 прохода, parallelism 1. Соль и параметры лежат рядом с шифртекстом и секретом не являются. Само устройство становится доверенным после открытия бэкапа и отдельного подтверждения.

Сброс почты старый бэкап не открывает. Историю после смены пароля поднимает фраза восстановления из 12 слов (проверяльщика фразы на сервере нет) или другое доверенное устройство. Если пропали пароль, фраза и все доверенные устройства, эпоха остаётся закрытой. Так и задумано.

Группа в текущей версии – тот же конверт, разосланный каждому участнику, до 128 человек, включая отправителя. Общего группового секрета нет. Сервер видит название и состав и не видит текст.

Дальше границы v1, без них описание было бы рекламой.

Подпись сервер проверяет публичным ключом из того же конверта. Она держит пассивную подмену шифртекста. Активный сервер может подменить и ключ, и подпись. Защита от этого сейчас – первое доверие к ключу и число безопасности, отпечаток идентификационных ключей двух сторон. Прозрачности ключей нет.

Каждое сообщение получает новый эфемерный ключ, и это ещё не Double Ratchet. Долгосрочный ключ соглашения устройства переиспользуется: кто его украл, раскроет messageKey конвертов, завёрнутых на этот ключ. Post-compromise security, одноразовых pre-key и X3DH в v1 нет. Гибрид X25519 с ML-KEM-768 есть в черновике v2 и на провод не вышел.

Криптографические жалобы (franking) в коде есть: можно доказать содержимое одного сообщения, не открывая серверу весь чат. В проде тег не выпускается.

Обзор угроз и параметры бэкапа – в e2e-security.md.
⠀

Живучесть

Дальше то, из-за чего проект переживает давление.

Код сообщества можно читать, проверять, запускать у себя и улучшать вкладом. Если вы отдаёте изменённый сервис по сети, исходники этой версии обязаны остаться открытыми. Поэтому открытую редакцию нельзя тихо закрыть и унести. Я включу рекламу, забью или пропаду – люди поднимут ту же соцсеть под другим именем и останутся там. Чем живее проект, тем труднее забрать его насовсем. Уничтожить проект целиком можно только уничтожив все его копии, по сути как книгу. А рукописи, как говорится, не горят.

Коммерческая лицензия на тот же код есть, у того же правообладателя: закрытая встройка, OEM, SLA. Она не отменяет AGPL для пользовательской сети и не продаёт внимание людей внутри Flora. Она нужна для тех, кто хочет встроить код Flora в закрытый продукт.
⠀

Рекомендации

Рекомендации –  FIRA. Алгоритм открыт, его можно прочитать и настроить. Хронологическая вкладка "Подписки" идёт мимо формулы. Свои посты закрепляются сверху и не участвуют в скоре.

Живой скор ленты сейчас такой. Коэффициент тематического сходства равен нулю, поэтому интересы профиля на ранг не влияют. Остаются популярность и то, что сделали люди, на которых вы подписаны:

Score = 0.70 × GlobalRelevance + 0.30 × SocialProximity

GlobalRelevance = viral × exp(−λ × ageHours) viral = engagement / ln(followers + 2)

engagement = ln(likes48h + 1) × 1.0 + ln(comments48h + 1) × 2.0 + ln(reposts48h + 1) × 2.5 + ln(views48h + 1) × 0.01

SocialProximity = ln(followedLikers + 1) × 3 + repostBoost repostBoost = 1.5 × min(ln(followedReposters + 1), 3)


repostBoost равен нулю, если среди ваших подписок репост никто не сделал. При настройках по умолчанию скор совпадает с эталонными векторами. Код скорера –  products/FIRA/crates/fira-core.

Пул, из которого это считается: ваши подписки, авторы второй степени (на кого подписаны ваши подписки), тренды, сообщества, в которых вы состоите, и примесь случайных публичных постов. Коллаборативной фильтрации "похожие на вас люди" в ленте нет, это v3.

В настройках ленты уже крутятся живые ручки:

  • свежесть – λ 0.10 / 0.05 / 0.025 (свежее, баланс, популярное);

  • сколько впускать нового –  0 / 8% / 15% / 25%;

  • один автор подряд – не больше 1, не больше 2, или без лимита;

  • репосты и посты сообществ можно выключить;

  • уже виденное можно оставить, опустить (множитель 0.3) или убрать;

  • "не интересно" убирает пост и умножает автора на 0.5, не больше трёх раз.

Скрытый человек пропадает из рекомендаций. На вкладке подписок его посты остаются: она хронологическая и от скора не зависит.

Свои направления интересов я ещё довожу. Кнопки, которой брендированный контент отключается целиком, опять же, пока нет. Алгоритм слушает те настройки, которые перечислены выше.
⠀

Свой медиакодек

Я написал фотокодек FRC-I на Rust. Формат заморожен, bitstream v12, ядро без unsafe, один код собирается и на сервер, и в браузер, и в мобильное приложение.

С JPEG спека сравнивает версию v8, Kodak, PSNR: около −29% BD-rate, то есть меньше бит при той же PSNR, кодирование 11,8 Мп/с против примерно 9,2 у JPEG. Сравнение текущего v12 с JPEG XL на том же Kodak по SSIMULACRA2 другое: у FRC-I ещё примерно на 33,6% больше бит, чем у cjxl -e 7. Кодирование при этом быстрее: 13,8 Мп/с против примерно 7,9. Плотнее обычного JPEG на опубликованном PSNR-бенче – да. Обгонять JPEG XL я не заявляю.

В постах картинка пишется парой. Основной файл – FRC-I (для постов качество 75, для аватаров 85), рядом lossless WebP. Браузер по умолчанию получает WebP. FRC-I отдаётся, когда клиент просит image/x-flora-frc-i. В чате клиент кодирует FRC-I и запасной JPEG, PNG или WebP, шифрует каждый вариант и уходит на сервер уже шифртекст

Аудиокодек FRC-A и видеокодек FRC-V лежат в том же семействе и остаются черновиками. В пользовательской сети звук пока AAC, видео пока AV1. Свой аудиопрогон я не выигрывал у Opus, AAC, Vorbis и MP3. Это в спеке написано прямо.
⠀

Кого я жду

Людей внутри почти нет. Работы много, она продолжается, и мне нужны те, кто зайдёт. Напишите, сделайте пост, почитайте, поругайтесь по делу. Предметную критику я люблю, в т.ч. там, где текст выше расходится с тем, что вы увидите в спеке или в клиенте. Буду рад каждому живому человеку.

Комментарии (17)


  1. arhixnik
    15.10.2026 13:22

    прикольно, попробую зайти


  1. Olegun
    15.10.2026 13:22

    С учётом целей это наивно. Стоило начать со спутниковой группировки для доставки контента. Остальное само прорастает.


    1. effka11 Автор
      15.10.2026 13:22

      скоро будет


  1. ArtemSTP
    15.10.2026 13:22

    Зашел в веб версию и зарегался. В целом дизайн и механики вполне удобные и мне даже зашли. Но судя по всему, при тестировании для веба, в dev tools не осуществлялся прогон под мобильные устройства (у меня iphone 14), по этому часть интерфейса порезана и блоки навигации остались где то за пределами видимой области на body. Попробую дома зайти с десктопа.


    1. effka11 Автор
      15.10.2026 13:22

      Привет! Да, это действительно так. Мобильная веб-версия пока находится в разработке. Завел задачу на ее создание. В следующем обновлении будет рабочая веб-версия для телефона. За обновлениями можете следить на GitHub, в группе Flora Studio (https://social.flora-s.net/communities/flora), там будет описано следующее обновление, а также в группе Telegram (https://t.me/flora_social).
      Также признаю, что версия приложения для IOS пока тоже отсуствует. Это довольно сложная тема из-за специфики их экосистемы, но в будущем она также будет реализована.


      1. ArtemSTP
        15.10.2026 13:22

        Для ios можно в принципе на test flight запускать. Но для пользователя это будет не удобно. Есть еще ярлыки pwa, но они требуют действий пользователя. По хорошему, если инфраструктура и бюджет ограничены, можно попробовать на стороне seo реализовать решение в виде онбординга. Но в этом случае нужно решить не тривиальную задачу, чтобы с порога дать пользователю такую ценность, благодаря которой, увидев онбординг - он выполнит целевые действия по нему - добавит pwa ярлык на экран смартфона.

        В общем любопытный проект. Подпишусь в тг и буду следить за успехами)


        1. effka11 Автор
          15.10.2026 13:22

          Спасибо, разложили точно. Согласен, и думаю, что сейчас PWA ярлык будет приемлимым вариантом, пока бюджета на дистрибуцию IOS-приложения нет. Сначала доделаем веб-версию для телефона тогда, затем придумаем как лучше реализовать для пользователя PWA.
          Спасибо за поддержку)


  1. rmasemargl
    15.10.2026 13:22

    Какой лимит у текстового поста? Попытался сделать копию своей статьи ВК, текст целиком не поместился. Там чуть больше 3700 символов.

    И про регистрацию, не знаю, у Вас проблема или у гугла: в хроме при регистрации согласился создать пароль, но запись логин-пароль в менеджере паролей гугла не создалась, хром не предложил пароль сохранить. Только после восстановления пароля создалась, уже с новым паролем.

    Ещё по переходу по ссылке на Вашу соц.сеть каждый раз требуется авторизация, словно сессия не хранится нисколько. Не понял, баг это или фича.


    1. effka11 Автор
      15.10.2026 13:22

      Привет, спасибо за обратную связь.
      Лимит у текстового поста увеличу, проблема с сессиями в веб-приложении действительно есть, задачу завел. На счет пароля изучу вопрос


  1. Angle_Tightener
    15.10.2026 13:22

    Главная проблема всех (абсолютно всех!) новых (после ФБ и ВК) соцсетей - отсутствие пользователей. Чтобы ваш проект получил шансы на масштабную реализацию - важно наличие шлюзов с уже существующими соцсетями. Пользователи традиционных соцсетей должны увидеть новое и заинтересоваться.

    Без этого - шансы на успех близки к нулю, увы. Максимум, что может получиться - очень нишевый продукт.


    1. rimashi
      15.10.2026 13:22

      Не, ну почему же. Если у тебя есть медийность, то пользователи не проблема)

      Как пример соц сеть от блогера новки (nowkie). Я не помню название, но успех у нее есть. А, вроде "итд" что ли. Но стоит отдать должное, блогер не просто решил тупо сделать "свою соц сеть", а попытался пересмотреть концепт немного. В целом интересно наблюдать, сожрёт ли Мейл групп, что по законодательству и прочее


  1. IvanKlut
    15.10.2026 13:22

    Автор, вы не могли бы изложить суть проекта иными словами -- попроще? Хочется разобраться, но я теряюсь среди множества доказательств надёжности шифрования. Мне кажется в современное время принципиально неразрешимы вопросы безопасности, а приватность для многих означает вседозволенность. Допустим я завёл свой блог в соцсети и там всё шифруется, но открыв пост данные становятся доступными. Пусть пост будет о свастике как о символе славян. На вас наедет роскомпозор и заставит удалить. Или в зашифрованных сообщениях с кем-то начну обсуждать торговлю наркотиками и людьми -- вам оно надо? И про архитектуру не понял, типа если вы как владелец начнёте страдать херней, то можно взять открытый код и переразвернуть сеть? В общем, если вас не затруднит, раскройте общие идеи и принципиальные механизмы как этим можно будет пользоваться.


    1. effka11 Автор
      15.10.2026 13:22

      Flora - открытая соцсеть без рекламы: лента, сообщества, музыка, поиск и личка. Рекомендации можно прочитать и настроить. Сообщения шифруются сквозным шифрованием.

      Да, в современное время приходится довольно глубоко проектировать и реализовывать безопасность, но принципиально неразрешимых вопросов, я считаю, нет.

      Приватность не означает вседозволенность. У нас есть правила проекта - https://social.flora-s.net/rules
      Правила продиктованы в том числе базовым законодательством большинства стран.

      Мы не можем прочитать переписку, но один из ее участников может пожаловаться на сообщения, которые отправляются на модерацию с собственной технической системой подтверждения, что эти сообщения реальны. В таком случае мы можем применить санкции в отношении пользователя, нарушающего правила сообщества. То же самое касается и постов, комментариев, музыки и т.д..

      Мы считаем, что вероятность использования шифрования нелегальным образом не должна приводить к репрессиям всех пользователей и нарушать право на тайну переписки. Последствия отсутствия этой тайны, как правило, более катастрофичны, чем использование его злоумышленниками. В любом случае, злоумышленник может использовать иные инструменты обмена информацией. Запрещать людям тайну переписки то же самое, что запрещать лопату, так как ей можно кого-то убить.

      Сами посты не шифруются, их текст виден серверу. Просто закрытые посты могут видеть только те, кому они доступны. А так на сервере они сейчас лежат в открытом виде. К ним также могут быть применены санкции в случае нарушения правил.

      Роскомнадзор и так через какое-то время проект будет блокировать из-за сквозного шифрования. Мы к этому готовимся, это не будет касаться отдельных постов, к ним так и так, без требований РКН, будут применены санкции, если они нарушают правила сообщества. РКН может просить удаление неудобных им постов, (например дискредитация армии). Такие посты мы удалять не будем, если они не нарушают правила площадки.

      Да, любой человек может развернуть ту же соцсеть со своей базой данных и под своим брендом. Это гарантия того, что проект будет жить.


  1. rimashi
    15.10.2026 13:22

    Звучит интересно, конечно вызывает вопросы создание своего протокола. Это ведь ещё одна штука, которую надо проверять, проводить аудиты и чинить в случае чего. Но если с безопасностью и отсутствием рекламы реально всё будет супер, то думаю гики к вам точно сбегут)

    Мне скорее интересно, как вы думаете решать юридические вопросики. Да, пока Пэт проект не разросся, находится в ветке и прочее, вопросов нет. Но если проект начнет обретать популярность? Что там по пдн, по ключам (все равно ведь могут прогнуть, возможно как с сигналом)?


    1. effka11 Автор
      15.10.2026 13:22

      Да, понимаю, у текущей версии шифрования есть ограничения и проблемы. Те, что уже зафиксированы, лежат тут: https://github.com/effka11/Flora.Ecosystem/blob/main/documents/known/security.md

      Юридические вопросы тема интересная. Думаю сделать отдельно пост об этом


  1. seryozha_na_dache
    15.10.2026 13:22

    В текущей формуле настройка freshness меняет только затухание GlobalRelevance. Правильно понимаю, что социальный сигнал намеренно может возвращать более старые посты? При followedLikers = 1 вклад этого слагаемого в итоговый Score — примерно 0,62, и в самой формуле он не убывает со временем, пока лайк учитывается в счётчике.

    В FIRA-F видел окна кандидатов и настройку seenPosts, но последняя не затрагивает ещё не просмотренные записи. Планируете ли учитывать в SocialProximity время самого лайка, или это часть задумки — давать второй шанс публикациям, которые нашли люди из подписок?


    1. effka11 Автор
      15.10.2026 13:22

      Да, сейчас так: freshness меняет только затухание GlobalRelevance. При одном лайке подписки SocialProximity даёт около 0,62 и само не стареет, пока лайк в счётчике. seenPosts трогает только уже просмотренные посты

      Это не задуманный второй шанс. SocialProximity будет убывать тем же exp(−λ * возраст поста), λ по-прежнему берётся из freshness. Время самого лайка не учитываем - возраст считается от публикации.