Главная / Статьи

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

KitDev Space хранит хэши, JWT и архивы в браузере, использует Bun только тогда, когда требуется работа с нативными компонентами или между разными хостами, а также отмечает место выполнения каждого инструмента.

Издатель: REACTAPP.TOP6 мин чтения1438 слов

Источники: How I built KitDev Space, an open source hub of developer tools that never has to ask you to trust it

Подключение производственного JWT в первый декодер, который предлагает поисковик, — это распространённая практика. Цель состоит лишь в просмотре содержимого токена, но он всё равно покидает устройство. Та же ситуация наблюдается при работе с файлами .env в конвертерах и фотографиями в инструментах для извлечения данных EXIF: в политике конфиденциальности говорится, что сервер ничего не хранит, и этому утверждению верят без сомнений.

KitDev Space создан для того, чтобы уменьшить необходимость в такой доверчивости. Инструменты, используемые разработчиками каждый день, не должны требовать доверия к оператору — включая того, кто написал сайт. Формат продукта соответствует одному раннему правилу, которое было зафиксировано и с тех пор считается непреложным.

Правило

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

Первая часть не вызывает споров. Второй части требуется строгое определение, иначе все удобные решения будут переноситься на сторону сервера. Ситуации, которые действительно подходят, описаны кратко:

  1. Для выполнения задачи необходима нативная библиотека. Для кодирования формата AVIF или растеризации SVG требуется настоящий кодек. Для установления соединения TLS нужен сокет.
  2. Задача требует взаимодействия с другим хостом. DNS, заголовки ответа, RDAP и предварительные просмотры OpenGraph не смогут работать или должны не сработать на странице из-за ограничений CORS.
  3. Для выполнения задачи требуется API во время выполнения без соответствующей версии в браузере, такой как Bun.dns или Bun.Archive.
  4. Объем входных данных слишком велик, чтобы его удобно было отобразить в табе.

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

Браузер делает больше, чем ожидалось

Изначальные оценки предполагали наличие тяжелого серверного кода. Большая часть инструментов для разработчиков уже встроена в API платформы или представлена небольшими зависимостями, которые работают без покидания страницы.

  • Инструменты для обработки хэшей от SHA-1 до SHA-512 с использованием crypto.subtle.digest
  • Генерация энтропии и идентификаторов с помощью crypto.getRandomValues
  • Симметричные алгоритмы шифрования — AES-256-GCM, PBKDF2, HMAC — через crypto.subtle
  • Редактирование геометрии изображений (изменение размера, поворот, обрезка) с использованием OffscreenCanvas и createImageBitmap
  • Экспорт статичных изображений в форматах JPEG, PNG или WebP с помощью OffscreenCanvas.convertToBlob
  • Чтение данных EXIF и GPS путем просмотра байтов файла с использованием DataView
  • Компрессия и архивация данных (gzip, deflate, tar) с помощью библиотеки fflate
  • Работа с форматами конфигураций YAML, TOML, JSONC и JSON5 через confbox
  • SQL в памяти с использованием sql.js, работающего как WebAssembly
  • Панель JWT проверяет подписи HS256 с помощью Web Crypto и полностью игнорирует HTTP. На вкладке AES генерируются ключи с использованием алгоритма PBKDF2. Браузер для архивов открывает файлы формата tar без необходимости их загрузки. Студия SQLite хранит базу данных в памяти. Паттерн прост: сначала изучаются возможности платформы, а маршруты добавляются только в том случае, если чего-то не хватает.

    У Web Crypto всё ещё есть недостатки: отсутствуют поддержка MD5, CRC32 и xxHash. Библиотека MD5 на чистом JavaScript могла бы выполнять хеширование полностью локально, но инструмент для хеширования также предлагает алгоритмы xxhash64 и wyhash, и отправка этих редко используемых алгоритмов каждому посетителю казалась неправильной. Эти опции требуют обращения к серверу, и интерфейс чётко сообщает об этом при выборе соответствующего режима. Указание режима, при котором обработка происходит на устройстве, лучше, чем притворяться, что ничего не происходит.

    Один модуль, два пути

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

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

    // shared/utils/crypto/hash.ts
    const SUBTLE_NAMES = {
     sha1: 'SHA-1',
     sha256: 'SHA-256',
     sha384: 'SHA-384',
     sha512: 'SHA-512'
    }
    
    export function canHashInBrowser(algorithm: HashAlgorithm): boolean {
     return algorithm in SUBTLE_NAMES
    }
    
    // simplified page logic
    const result = canHashInBrowser(algorithm)
     ? await hashInBrowser(input, algorithm)
     : await $fetch('/api/hash', { method: 'POST', body: { input, algorithm } })
    

    Хэширование, конвертация форматов, форматирование кода и использование версионных схем semver также следуют этой структуре. Новые инструменты с двумя путями обработки наследуют ту же структуру, вместо того чтобы создавать новую разделенную архитектуру.

    Для чего на самом деле предназначен сервер

    Утилиты, работающие на бэкенде, размещены в Bun. Каждая из них существует из-за одного серьезного исключения:

    • Проверка сертификатов требует открытия реального сокета для чтения цепочек сертификатов, дополнительных информаций и согласованных шифров.
  • Инструменты для анализа имён и адресов электронной почты требуют поддержки форматов A/MX/TXT, а также спецификаций SPF, DKIM и DMARC.
  • Проверка заголовков, превью в формате OpenGraph и функция RDAP требуют запросов к сторонним сервисам.
  • Инструменты для обработки изображений и создания фавиконов вызывают Bun.Image при необходимости генерации файлов форматов AVIF или ICO.
  • Процессы транспиляции кода TS/JSX и рабочие среды для работы с AST зависят от встроенной реализации OXC.
  • Маршруты сервера рассматриваются как источники рисков и используют один и тот же список проверок перед отправкой запроса. URL должны проходить верификацию и могут использовать только протоколы http или https. Отклоняются адреса localhost, приватные диапазоны, локальные адреса типа link-local, конечные точки метаданных облачных сервисов, а также формы перехода на IPv6, скрывающие IPv4 (NAT64 и Teredo входят в этот список запрещенных адресов). Целевые порты ограничены, чтобы проверка TLS не могла сканировать сеть. Проверяется длина содержимого, данные передаются в потоковом режиме, а чтение прекращается при достижении фиксированного лимита, вместо того чтобы происходить бесконечное буферизование. Для ограничения скорости использовается ключ клиента, не связанный с x-forwarded-for, который легко можно подделать. Файлы, загружаемые на сервер, остаются в памяти и никогда не сохраняются на диске. Введенные данные и полученные результаты не хранятся.

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

    Показ правил

    Правило, которое никто не может увидеть, — это маркетинговый инструмент, а не средство контроля приватности. Поэтому в навигации указывается место выполнения операций.

    Каждая запись сопровождается специальным знаком. Обозначение «Client» означает, что страница никогда не отправляет запросы на сервер. Обозначение «Bun» означает, что каждое действие направляется на бэкенд. Инструменты, поддерживающие оба варианта, не показывают такого знака и не указывают, какое действие приводит к закрытию вкладки. Эти метки генерируются на основе двух флагов реестра — того же реестра, который управляет заголовками и поиском, — поэтому описание не может противоречить фактической реализации.

    Исходный код распространяется по лицензии MIT, ссылка на него приведена в футере. Обозначение «Client» можно проверить, открыв модуль и убедившись, что он никогда не вызывает соответствующий маршрут. Окончательным элементом дизайна является не доверие, а проверка.

    Что там содержится

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

    Работа с данными: красивое отображение JSON, поддержка форматов JSON5/JSONC, генерация типов TypeScript из JSON, свободное взаимодействие с форматами YAML, TOML, XML и CSV (включая преобразование строк CSV в запросы к базе данных SQL), просмотр больших таблиц CSV и запуск студии SQLite прямо в браузере.

    Инструменты для разработчиков: планшет для регулярных выражений с пояснениями к каждому токену, календарь cron с указанием времени следующих выполнений задач, конвертеры из cURL в fetch, Axios, Python или Go, конвертеры HTML/SVG для использования с JSX или Vue, инструмент для работы с шаблонами glob и локальный браузер архивов tar.

    Проверка сети: анализ цепочки сертификатов, запросы DNS, проверка состояния аутентификации почтовых ящиков, просмотр сырых заголовков HTTP, вычисления в формате CIDR, декодирование куки и поиск в RDAP.

    Инструменты для работы с криптографией: функции хеширования, HMAC, анализ JWT, генерация кодов TOTP, шифрование/дешифрование с использованием AES, а также генераторы UUID и паролей.

    Инструменты для работы с цветами: преобразование в формат OKLCH, оценка контрастности согласно стандарту WCAG, создание градиентов в стиле Tailwind, формирование CSS-градиентов и извлечение палитры из изображения.

    Инструменты для работы с изображениями: комбинированные операции обрезки/изменения размера/поворота/преобразования, просмотр или удаление данных EXIF, растеризация SVG в форматы PNG/WebP с увеличением 1x/2x/4x, а также инструмент для сборки фавиконов в формате ZIP.

    Учетные записи и платные барьеры отсутствуют. Тема автоматически подстраивается под настройки операционной системы, поэтому не требуется отдельного управления режимом светлого/темного интерфейса.

    Внутренняя структура

    Список используемых технологий намеренно остается простым: Nuxt 4 с библиотекой Nuxt UI 4 в браузере, композаблы VueUse, редакторы CodeMirror, маршруты на основе Bun, тестирование с использованием Vitest и Playwright, а также развертывание на платформе Vercel.

    Мне нужна ваша помощь

    Попробуйте https://kitdev.space — два отчета особенно полезны: информация о том, какой инструмент отсутствует, и данные о том, отправлял ли какой-либо инструмент информацию на сервер вместо того, чтобы оставить ее локально. Наличие второго отчета указывает на наличие ошибки в правилах.

    Репозиторий находится в одном клике от футера. Приветствуются заявки на создание новых инструментов, исправления или корректировку значков. Такой центр становится лучше с участием большего числа людей — именно поэтому код является открытым.

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