Головна / Статті

Створюйте інструменти для розробників, орієнтовані на клієнта, які не вимагають сліпої довіри

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 потребують запитів до сторонніх сервісів.
  • Функції Image Studio та створення фавіконів використовують Bun.Image для генерації форматів AVIF чи ICO.
  • Процес транспіляції TS/JSX та інструменти для роботи з AST залежать від вбудованої реалізації OXC.
  • Шляхи сервера розглядаються як обов’язки та мають спільний перелік перевірок перед використанням. URL-адреси повинні бути перевірені та можуть використовувати лише http або https. Адреси localhost, приватні діапазони, локальні адреси, кінцеві точки метаданих хмар та форми переходу на 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; інструмент для роботи з глоб-шаблонами та локальний браузер 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 — два звіти найбільше допомагають: який інструмент бракує та чи надсилав якийсь інструмент дані на сервер, коли вони мали залишитися локально. Другий звіт означає, що в правилі є проблема.

    Репозиторій знаходиться за один клік від футера. Будемо раді заявкам на нові інструменти, виправлення чи корекцію бейджів. Такий хаб покращується завдяки участі більшої кількості людей — саме тому код є відкритим.

    При створенні подібних інструментів в інших місцях тримайтеся того самого короткого списку випадків, коли браузер справді не може виконати завдання. Усе інше має залишатися на комп’ютері користувача.