[{"data":1,"prerenderedAt":1090},["ShallowReactive",2],{"blog-uk-database-error-saving-new-user":3,"blog-index-uk":564},{"id":4,"title":5,"body":6,"category":521,"cover":522,"coverAlt":523,"description":524,"draft":525,"extension":526,"faq":527,"image":543,"keywords":544,"meta":552,"navigation":553,"ogTitle":554,"path":555,"published":556,"seo":557,"stem":558,"tldr":559,"updated":556,"__hash__":563},"blog_uk\u002Fblog\u002Fdatabase-error-saving-new-user.md","\"Database error saving new user\" у Supabase: де шукати",{"type":7,"value":8,"toc":508},"minimark",[9,13,24,27,35,40,43,57,60,63,76,82,86,89,92,95,120,132,138,142,149,159,162,165,169,175,182,196,201,207,211,217,220,226,237,244,257,261,264,273,285,310,316,326,337,348,367,371,374,380,399,402,406,412,421,436,446,463,467,495],[10,11,12],"p",{},"Хтось намагається створити обліковий запис у вашому застосунку й отримує у\nвідповідь щось, що взагалі не про нього:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","Database error saving new user\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26],{},"Ніхто не може зареєструватися. Форма працювала, коли ви її будували, ваш проєкт\nпіднятий, і єдине, що у вас є, це речення без жодної таблиці, без стовпця і без\nпричини.",[10,28,29,30,34],{},"Ось те, що гайд за гайдом розуміє неправильно: ",[31,32,33],"strong",{},"це повідомлення зробили так, щоб\nвоно вам нічого не казало, а ваша справжня помилка вже записана в іншому місці.","\nПошукайте цей рядок, і вам простягнуть блок SQL, щоб вставити, зазвичай чиюсь\nверсію функції, яка пише в таблицю з чужими назвами стовпців. Вставити це або\nспрацює, або додасть другу проблему до першої. Рядок, який каже, що саме впало,\nлежить у логах вашого власного проєкту, і він називає таблицю.",[36,37,39],"h2",{"id":38},"що-означає-database-error-saving-new-user","Що означає \"Database error saving new user\"",[10,41,42],{},"Supabase прийняв новий обліковий запис і потім скасував його, бо щось причеплене\nдо реєстрації впало.",[10,44,45,46,49,50,53,54,56],{},"Реєстрація пише один рядок, у таблицю ",[21,47,48],{},"auth.users",", якою Supabase керує за вас.\nБільшість проєктів чіпляють до цього запису ще щось: тригер, який копіює нову\nлюдину у вашу власну таблицю ",[21,51,52],{},"profiles",", обмеження, зовнішній ключ. Коли ця\nпричеплена річ видає помилку, база скасовує всю операцію, а це включає й рядок у\n",[21,55,48],{},". Жодного напівзробленого запису не лишається. І у відповіді теж\nнемає нічого, що сказало б, яка саме з причеплених речей це була.",[10,58,59],{},"Уявіть стійку з підсобкою позаду. Хтось розписується в журналі на стійці, а\nпрацівник несе нове імʼя назад, щоб переписати його в другу книгу. Якщо працівник\nне може зайти в кімнату, де та книга лежить, запис не рахується: рядок на стійці\nперекреслюють, а людині кажуть, що сталася проблема. Чого їй ніхто не каже, так\nце того, що проблемою були замкнені двері за дванадцять метрів.",[10,61,62],{},"Невиразність тут навмисна, і це правильне рішення. Ваша форма реєстрації\nвідкрита в інтернет. Повідомлення, яке називало б ваші таблиці, описувало б вашу\nбазу кожному, хто готовий ввести туди адресу пошти.",[10,64,65,66,69,70,75],{},"Якщо натомість у відповіді ",[21,67,68],{},"email rate limit exceeded",", ваша база тут ні до\nчого: Supabase відмовився надсилати лист підтвердження, і\n",[71,72,74],"a",{"href":73},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","ця помилка має окрему сторінку",".",[77,78],"diagram",{"alt":79,"caption":80,"src":81},"Ліворуч журнал із кількома рядками, найсвіжіший із них перекреслений, стрілка праворуч веде до фігури, а шлях цієї фігури до другої книги перетятий бурштиновою перепоною. Окрема панель збоку показує три записані рядки, один із яких виділено.","Рядок в auth.users записують і виймають назад, тож від невдачі не лишається нічого, крім рядка в лозі, який відповідь жодного разу не згадує.","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fthe-rollback-1600x660.png",[36,83,85],{"id":84},"де-лежить-справжня-помилка","Де лежить справжня помилка?",[10,87,88],{},"У логах вашого проєкту, у два кроки, і власна сторінка з розвʼязанням у Supabase\nзадає порядок.",[10,90,91],{},"Відтворіть її один раз, перш ніж шукати, щоб мати час, за яким звіряти. Спробуйте\nзареєструватися у вашому живому застосунку, дайте цьому впасти й запишіть\nхвилину.",[10,93,94],{},"Далі, у панелі Supabase:",[96,97,98,110],"ol",{},[99,100,101,102,105,106,109],"li",{},"Відкрийте ",[31,103,104],{},"Logs"," і прочитайте логи ",[31,107,108],{},"Auth",". Знайдіть запис за той час. Він\nнесе помилку, яку Auth записав від себе, і вона конкретніша за речення, що\nдісталося вашому застосунку.",[99,111,112,113,115,116,119],{},"Якщо цей запис показує на базу, поверніться в ",[31,114,104],{}," і відкрийте логи\n",[31,117,118],{},"Postgres",". Рядок за ту саму хвилину це ваша справжня помилка, написана\nзвичайним словником Postgres: стовпець, відношення, тип, дозвіл.",[10,121,122,123,125,126,128,129,131],{},"Нотатка Supabase з розвʼязанням для цього повідомлення перелічує три причини. У\nвас є тригер або функція тригера на таблиці ",[21,124,48],{},", у якій є помилка. Ви\nдодали на ",[21,127,48],{}," обмеження, яке не виконується. Або ви користуєтеся Prisma,\nі вона зламала дозволи на ",[21,130,48],{},". З тієї ж нотатки походить і дворівневий\nшлях логами вище.",[10,133,134,135,137],{},"Для застосунку, зробленого в Lovable, Bolt, Replit чи v0, перша причина покриває\nбільшість випадків, бо копіювати нову реєстрацію в таблицю ",[21,136,52],{}," це взірець,\nдо якого тягнеться кожен білдер, а тригер це те, як воно робиться.",[36,139,141],{"id":140},"причина-1-тригер-не-дістає-до-вашої-таблиці","Причина 1: тригер не дістає до вашої таблиці",[10,143,144,145,148],{},"Роль бази, яка виконує ваш тригер, не має права виходити зі схеми ",[21,146,147],{},"auth",", а ваш\nтригер пише саме назовні.",[10,150,151,152,155,156,158],{},"Supabase пояснює це на власній дошці обговорень, і формулювання варто мати\nточним. Роль бази, яка керує автентифікацією, ",[21,153,154],{},"supabase_auth_admin",", має лише ті\nдозволи, що потрібні їй для власних обовʼязків, тож коли тригер, яким керує\n",[21,157,154],{},", взаємодіє поза схемою auth, це спричиняє помилку дозволу.",[10,160,161],{},"Це перепустка працівника. Вона відчиняє передній офіс, бо саме там його робота.\nДруга книга лежить у кімнаті, на яку цю перепустку ніколи не виписували, а\nзамкнені двері нічого не повідомляють про те, чому вони замкнені.",[10,163,164],{},"У лозі Postgres це приходить як помилка дозволу, що називає таблицю, у яку ваш\nтригер писав.",[36,166,168],{"id":167},"відповідь-і-що-вона-віддає","Відповідь, і що вона віддає",[10,170,171,174],{},[21,172,173],{},"security definer"," на функції, яка змушує її працювати з правами того, хто її\nстворив, а не того, хто її викликав.",[10,176,177,178,181],{},"Supabase каже це одним рядком: функція security definer зберігає права\nкористувача бази, який її створив, і доки це роль ",[21,179,180],{},"postgres",", ваші тригери auth\nмають давати раду таблицям назовні. Працівник перестає носити власну перепустку й\nносить перепустку керівника.",[10,183,184,185,188,189,192,193,195],{},"Це справжня передача повноважень, тож варто знати, що ви там написали, перш ніж\nвставляти. Кожна інструкція всередині цієї функції тепер виконується від імені\nвласника. Власний приклад Supabase ставить порожній search_path, через\n",[21,186,187],{},"security definer set search_path = ''",", і саме через це вставка там називає\n",[21,190,191],{},"public.profiles"," повністю, а не просто ",[21,194,52],{},". З порожнім search_path гола\nназва таблиці більше не розвʼязується ні в що. Функції, яка несе права власника,\nпісля цього ніхто не підмінить тихцем ціль на іншу таблицю залежно від того, що\nсаме каже search_path того, хто викликає.",[77,197],{"alt":198,"caption":199,"src":200},"Той самий шлях, намальований двічі. Угорі фігуру з маленькою перепусткою спиняють замкнені двері перед панеллю з книгою. Унизу та сама фігура несе більшу перепустку, двері відчинені, і шлях веде далі всередину панелі.","Яку перепустку несе функція, у цьому вся різниця. security definer це нижня смуга, і це перепустка власника.","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Ftwo-passes-1600x620.png",[10,202,203,204,206],{},"Чого це не дозволяє, так це тягнутися по ",[21,205,173],{}," наступного разу, коли\nщось відмовлять. Лишіть функцію робити одну річ і повертатися, як це робить\nверсія Supabase.",[36,208,210],{"id":209},"причина-2-правило-на-таблиці-у-яку-ви-пишете","Причина 2: правило на таблиці, у яку ви пишете",[10,212,213,214,216],{},"Row Level Security на вашій таблиці ",[21,215,52],{}," може відхилити вставку, і тоді\nреєстрація падає точно так само.",[10,218,219],{},"Посібник Supabase до цього взірця каже ввімкнути Row Level Security для тієї\nтаблиці, і ця вказівка правильна. Для вашого тригера це означає, що вставка має\nбути дозволена: або policy, яка її покриває, або функцією, що працює від імені\nтого, на кого policy не поширюються.",[10,221,222,223,225],{},"Ось тут це перестає бути багом і стає рішенням, яке хтось ухвалює об\nодинадцятій вечора. Ніхто не може зареєструватися, помилка нічого не каже, а в\nпанелі є перемикач, підписаний звичайними словами, від якого помилка зникає:\nвимкнути Row Level Security на ",[21,224,52],{},". Наступна спроба спрацьовує.\nВідбувається й інше: таблиця з вашими користувачами, з усім, що ви тримаєте там\nпоруч із їхніми іменами, починає відповідати кожному, хто попросить.",[10,227,228,229,232,233,236],{},"Цю частину видно ззовні, і саме так ми можемо її порахувати. Наш сканер читає\nживі застосунки так, як це робив би незнайомець. Ми знайшли проєкт Supabase за\n8 435 застосунками з тих, яким він виставив оцінку. На 3 680 із них питання \"чи\nможе хтось без облікового запису прочитати цю таблицю\" отримало придатну\nвідповідь, і ",[31,230,231],{},"2 096 відповіли так",". У ",[31,234,235],{},"394"," з них відкрита таблиця мала назву\nтаблиці з людьми.",[10,238,239,240,75],{},"Частина цього навмисна, бо опубліковане меню й сторінка оголошень лежать у\nтаблицях, які незнайомець і має читати, а наш сканер не відрізнить їх від\nтаблиці клієнтів, яку хтось відкрив, щоб здихатися помилки. Він повідомляє, що\nсаме відповіло. Якщо ви радше побачите власну відповідь, ніж будете про неї\nміркувати, наше безкоштовне сканування читає ваш живий застосунок і каже, які\nтаблиці відповіли. Це триває близько 20 секунд і не потребує облікового запису:\n",[71,241,243],{"href":242},"\u002Fsecurity-scanner","просканувати застосунок",[10,245,246,247,251,252,256],{},"Policy, якої потребує тригер, значно вужча за вимикання правил.\n",[71,248,250],{"href":249},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Увімкнути Row Level Security на кожній таблиці","\nпоказує, як її написати, а\n",[71,253,255],{"href":254},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","\"new row violates row-level security policy\"","\nце повідомлення, яке ви отримуєте, коли policy відхиляє вставку, що ви бачите\nвласними очима.",[36,258,260],{"id":259},"інші-причини-і-як-кожна-читається-в-лозі","Інші причини, і як кожна читається в лозі",[10,262,263],{},"Ще чотири, і рядок у лозі розрізняє їх кількома словами.",[10,265,266,269,270,272],{},[31,267,268],{},"Таблиця, якої немає."," Нотатка Supabase покриває й це: функція тригера, яка\nпоказує на таблицю, що не існує або була видалена. Таблиця ",[21,271,52],{},", видалена й\nвідбудована під іншою назвою, забирає з собою кожну реєстрацію, а лог називає\nвідношення, якого бракує.",[10,274,275,280,281,75],{},[31,276,277,278,75],{},"Обмеження на ",[21,279,48],{}," Перевірка або зовнішній ключ, доданий на ту\nтаблицю, якого новий рядок не задовольняє. Це варто шукати, навіть коли ви\nвпевнені, що не додавали тригера, бо зовнішній ключ між вашою власною таблицею та\nкористувачем auth це найпоширеніший шлях, яким ця причина приходить. З\nповедінкою за замовчуванням той самий зовнішній ключ потім відмовляє й у\nвидаленні цієї людини, і\n",[71,282,284],{"href":283},"\u002Fblog\u002Fdatabase-error-deleting-user","це повідомлення має власну статтю",[10,286,287,290,291,294,295,298,299,301,302,305,306,309],{},[31,288,289],{},"Значення не того типу."," Ця зʼявляється слово в слово. Тригер, який копіює поля\nреєстрації з ",[21,292,293],{},"raw_user_meta_data",", читає їх через ",[21,296,297],{},"->>",", а ",[21,300,297],{}," повертає текст,\nхоч би як значення виглядало на вході. Записати цей текст у стовпець ",[21,303,304],{},"date"," дало,\nв одному описаному випадку,\n",[21,307,308],{},"column \"birth_date\" is of type date but expression is of type text",". Полагодити\nце можна приведенням типу, спершу взявши витягування в дужки:",[14,311,314],{"className":312,"code":313,"language":19},[17],"(new.raw_user_meta_data->>'birthDate')::date,\n(new.raw_user_meta_data->>'height')::integer,\n",[21,315,313],{"__ignoreMap":23},[10,317,318,321,322,325],{},[31,319,320],{},"Рядки, вставлені руками."," Нотатка Supabase покриває й облікові записи,\nстворені напряму через SQL замість API Auth, де обовʼязкові стовпці схеми auth\nлишаються NULL замість порожніх рядків. Якщо хтось засіяв користувачів через\n",[21,323,324],{},"insert",", це інше полагодження, ніж усі вище.",[10,327,328,329,332,333,75],{},"Ще один рядок, який можна там зустріти:\n",[21,330,331],{},"duplicate key value violates unique constraint",". Він означає, що рядок, який\nпише ваш тригер, там уже був, наприклад тому, що ваш застосунок вставляє той самий\nпрофіль після реєстрації, і\n",[71,334,336],{"href":335},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","про цю помилку є окремий допис",[10,338,339,340,343,344,75],{},"І ще одна: ",[21,341,342],{},"null value in column … violates not-null constraint",". Ваш тригер\nзаписав порожнє значення в стовпець, який його вимагає, найчастіше це поле\nреєстрації, яке форма так і не надіслала, і\n",[71,345,347],{"href":346},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","про неї теж є окремий допис",[10,349,350,351,354,355,358,359,362,363,75],{},"Остання, яку ви можете зустріти, це\n",[21,352,353],{},"insert or update on table \"profiles\" violates foreign key constraint",". Зазвичай\nвона означає, що тригер створили з ",[21,356,357],{},"before insert",", тож людину, для якої він\nзаписує профіль, ще не збережено. Шаблон Supabase нижче використовує\n",[21,360,361],{},"after insert",", і\n",[71,364,366],{"href":365},"\u002Fblog\u002Fviolates-foreign-key-constraint","про це повідомлення є окремий допис",[36,368,370],{"id":369},"робоча-версія-повністю","Робоча версія, повністю",[10,372,373],{},"Починайте зі взірця, який публікує Supabase, а не з результату пошуку, бо чотири\nречі в ньому несуть вагу, і переказ зазвичай одну з них губить.",[14,375,378],{"className":376,"code":377,"language":19},[17],"create function public.handle_new_user()\nreturns trigger\nlanguage plpgsql\nsecurity definer set search_path = ''\nas $$\nbegin\n  insert into public.profiles (id, first_name, last_name)\n  values (new.id, new.raw_user_meta_data ->> 'first_name', new.raw_user_meta_data ->> 'last_name');\n  return new;\nend;\n$$;\n\ncreate trigger on_auth_user_created\n  after insert on auth.users\n  for each row execute procedure public.handle_new_user();\n",[21,379,377],{"__ignoreMap":23},[10,381,382,383,385,386,389,390,392,393,396,397,75],{},"Ці чотири: ",[21,384,173],{},", порожній ",[21,387,388],{},"search_path",", повністю написане\n",[21,391,191],{}," і ",[21,394,395],{},"return new",", яке дає реєстрації йти далі. Ваші власні назви\nстовпців ідуть у вставку, і кожен стовпець, який ви там назвете, має існувати й\nмає приймати те, що дає ",[21,398,297],{},[10,400,401],{},"Посібник Supabase додає речення, яке варто повторити: якщо тригер впаде, він може\nзаблокувати реєстрації, тож перевіряйте свій код ретельно. Створюйте справжній\nобліковий запис у живому застосунку після кожної зміни в ньому.",[36,403,405],{"id":404},"як-тримати-реєстрацію-робочою-після-змін","Як тримати реєстрацію робочою після змін",[10,407,408,411],{},[31,409,410],{},"Реєстрація це та частина застосунку, яку ви перестаєте перевіряти того дня,\nколи вона запрацювала."," Ви зареєструвалися один раз, у вас є обліковий запис, а\nдалі ви просто входите. Наступний промпт, що торкнеться ваших таблиць, може\nзламати реєстрацію для всіх інших, доки ваша власна сесія поводиться цілком\nнормально.",[10,413,414],{},[31,415,416,420],{},[71,417,419],{"href":418},"\u002Fwebsite-monitoring","Reeve Monitor"," дивиться за вас:",[422,423,424,427,430,433],"ul",{},[99,425,426],{},"усі девʼять перевірок щогодини, для трьох застосунків",[99,428,429],{},"лист того дня, коли нове сканування оцінить ваш застосунок гірше за попереднє",[99,431,432],{},"чи застосунок доступний, кожні 60 секунд",[99,434,435],{},"щомісячний звіт про те, що він бачив",[10,437,438],{},[31,439,440,441,445],{},"Правило, вимкнене, щоб здихатися помилки, лишає таблицю з людьми читабельною.\n",[71,442,444],{"href":443},"\u002Fsupabase-backups","Reeve Care"," тримає копію вашої бази Supabase там, куди жодна\nзміна ваших правил не дістане.",[422,447,448,451,454,457,460],{},[99,449,450],{},"зашифрована копія щодня, збережена поза вашим обліковим записом Supabase",[99,452,453],{},"кожна копія перевірена, перш ніж її зарахують, підрахунком рядків у кожній таблиці",[99,455,456],{},"відновлення в один клік, яке зберігає те, що є зараз, перш ніж замінити",[99,458,459],{},"ваші завантажені файли теж, щойно ви приєднаєте доступ до Storage",[99,461,462],{},"усе, що робить Monitor",[36,464,466],{"id":465},"що-зробити-сьогодні","Що зробити сьогодні",[468,469,470],"key-takeaways",{},[422,471,472,475,478,489,492],{},[99,473,474],{},"Відтворіть одну невдалу реєстрацію й запишіть час, перш ніж щось міняти.",[99,476,477],{},"Прочитайте запис логу Auth за ту хвилину, а тоді рядок логу Postgres за той самий час, якщо запис Auth показує на базу. Той рядок називає стовпець, відношення або дозвіл, на якому все стало.",[99,479,480,481,483,484,486,487,75],{},"Перевірте, що ваша функція тригера несе ",[21,482,173],{}," і називає ціль повністю, як ",[21,485,191],{},", а не ",[21,488,52],{},[99,490,491],{},"Якщо policy на тій таблиці відхиляє вставку, напишіть policy для неї. Вимкнути Row Level Security прибирає помилку й лишає ту таблицю читабельною для кожного, хто попросить.",[99,493,494],{},"Створюйте справжній обліковий запис у живому застосунку після кожної зміни в тригері реєстрації. Ваша власна сесія повністю ховає від вас зламану реєстрацію.",[10,496,497,498,502,503,507],{},"Почніть із таблиці, у яку пише ваш тригер, а тоді прочитайте policy на кожній\nтаблиці, якої ви торкалися того самого тижня.\n",[71,499,501],{"href":500},"\u002Fchecklist","Десятихвилинний перелік із безпеки"," покриває те, що ще лишається\nвідкритим у щойно запущеному застосунку, а\n",[71,504,506],{"href":505},"\u002Fis-your-supabase-app-safe","посібник із безпеки Supabase"," проходить решту того,\nдо чого може дістатися незнайомець.",{"title":23,"searchDepth":509,"depth":509,"links":510},3,[511,513,514,515,516,517,518,519,520],{"id":38,"depth":512,"text":39},2,{"id":84,"depth":512,"text":85},{"id":140,"depth":512,"text":141},{"id":167,"depth":512,"text":168},{"id":209,"depth":512,"text":210},{"id":259,"depth":512,"text":260},{"id":369,"depth":512,"text":370},{"id":404,"depth":512,"text":405},{"id":465,"depth":512,"text":466},"Основи безпеки","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcover-1200x630.png","Журнал на стійці, найсвіжіший рядок у ньому вже перекреслений, а позаду друга книга в кімнаті із замкненими дверима.","\"Database error saving new user\" означає, що щось причеплене до вашої реєстрації в Supabase впало. Справжня помилка лежить у ваших логах.",false,"md",[528,531,534,537,540],{"q":529,"a":530},"Що означає \"Database error saving new user\"?","Означає, що Supabase записав нову людину у власну таблицю auth.users, щось причеплене до цього запису впало, і база скасувала всю операцію разом із новим рядком. Тобто жодного облікового запису не створено, і нічого недоробленого прибирати не треба. Повідомлення навмисно не називає ні таблиці, ні причини: ваша форма реєстрації відкрита в інтернет, і конкретна помилка описувала б вашу базу кожному, хто введе туди адресу пошти.",{"q":532,"a":533},"Де знайти справжню помилку?","У логах вашого проєкту, і власна сторінка з розвʼязанням у Supabase задає порядок. Спробуйте зареєструватися, дайте цьому впасти й запишіть час. Відкрийте Logs і прочитайте запис Auth за ту хвилину: він несе те, що Auth записав від себе. Якщо цей запис показує на базу, відкрийте логи Postgres за той самий час: той рядок називає стовпець, відношення або дозвіл, на якому все справді стало.",{"q":535,"a":536},"Чи ламає Row Level Security на моїй таблиці profiles реєстрацію?","Може ламати. Якщо ваш тригер вставляє в таблицю з Row Level Security і жодна policy цієї вставки не дозволяє, вставку відхиляють, і реєстрація падає з тим самим невиразним повідомленням. Відповідь це policy для неї або функція, яка працює з правами, на які policy не поширюються. Вимкнути правила на тій таблиці теж прибирає помилку, і лишає таблицю з вашими користувачами читабельною для кожного, хто попросить.",{"q":538,"a":539},"Що таке security definer і чи це безпечно?","Це змушує функцію працювати з правами того, хто її створив, а не того, хто її викликав, і саме це дозволяє тригеру, який виконує роль auth, писати у вашу власну таблицю. Це взірець, який публікує Supabase, і це справжня передача повноважень, тож функція має робити одну вузьку річ. Supabase до того ж ставить порожній search_path у своєму прикладі, і через це вставка там називає public.profiles повністю, а не просто profiles.",{"q":541,"a":542},"Я ніколи не створював тригера. Що це ще може бути?","Ще три речі. Обмеження або зовнішній ключ, доданий на auth.users, якого новий рядок не задовольняє. Функція тригера, яка показує на таблицю, перейменовану чи видалену. І нотатка Supabase називає Prisma поіменно, бо вона може зламати дозволи на auth.users. Яке з них у вас, скаже рядок у лозі Postgres.","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",[545,546,547,548,549,550,551],"database error saving new user","supabase database error saving new user","помилка реєстрації supabase","помилка тригера auth.users","handle_new_user не працює","supabase security definer тригер","supabase помилка 500 реєстрація",{},true,"\"Database error saving new user\" у Supabase","\u002Fblog\u002Fdatabase-error-saving-new-user","2026-10-14",{"title":5,"description":524},"blog\u002Fdatabase-error-saving-new-user",[560,561,562],"\"Database error saving new user\" означає, що Supabase прийняв реєстрацію, щось причеплене до неї впало, і все це скасували. Жодного облікового запису не створено.","Повідомлення навмисно нічого не каже, а справжнє вже десь записане. Власна сторінка з розвʼязанням у Supabase веде спершу в логи Auth, а тоді в логи Postgres по рядок, що лежить під ними.","Майже завжди це тригер на auth.users, який не дістає до таблиці, куди пише. Відповідь це функція security definer, і влучити треба в те, скільки їй дозволено.","zQz_IRvXMGNApa0zHyMcAZHz_9YDp3OfW28OnCYQLoQ",[565,571,577,582,587,593,599,605,611,617,623,629,635,641,647,653,659,664,670,676,682,687,693,699,705,711,717,718,724,730,736,742,748,754,760,766,772,778,784,790,796,802,808,814,820,826,831,837,843,849,855,861,867,873,879,885,891,897,903,909,915,921,926,932,938,944,950,956,962,968,974,980,986,992,998,1004,1009,1015,1021,1027,1033,1039,1045,1051,1056,1062,1068,1074,1079,1085],{"path":566,"title":567,"description":568,"published":569,"category":521,"image":570,"draft":525},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\": пояснення","Supabase \"max client connections reached\": у пулера немає місця ще для одного клієнта. Ліміт визначає порт у вашому рядку підключення.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":572,"title":573,"description":574,"published":575,"category":521,"image":576,"draft":525},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Помилка Supabase: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\": вхід через Google вимкнено у вашому проєкті Supabase. Як увімкнути та виправити redirect_uri_mismatch.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":365,"title":578,"description":579,"published":580,"category":521,"image":581,"draft":525},"Помилка Supabase \"violates foreign key constraint\" під час вставки","Supabase \"insert or update on table violates foreign key constraint\": ваш рядок посилається на рядок, якого немає. Який, чому і як це виправити.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":346,"title":583,"description":584,"published":585,"category":521,"image":586,"draft":525},"Помилка Supabase \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": обовʼязковий стовпець прийшов порожнім. Звідки взявся null і як це виправити.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":588,"title":589,"description":590,"published":591,"category":521,"image":592,"draft":525},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": куди поділася сесія","\"Auth session missing!\" означає, що supabase-js не знайшла жодної сесії й навіть не спитала Supabase. Куди поділася сесія і як це виправити.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":594,"title":595,"description":596,"published":597,"category":521,"image":598,"draft":525},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": ніхто не ввійшов","\"invalid claim: missing sub claim\": Supabase Auth отримав справжній токен без жодного користувача, ключ проєкту замість сесії.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":600,"title":601,"description":602,"published":603,"category":521,"image":604,"draft":525},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": справжня причина","\"Failed to send a request to the Edge Function\": браузер не отримав відповіді, яку можна прочитати. Його консоль каже, чому, і чи ваша функція запускалася.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":606,"title":607,"description":608,"published":609,"category":521,"image":610,"draft":525},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Чому Supabase перенаправляє посилання з листів на localhost:3000","Якщо Supabase перенаправляє на localhost:3000, Site URL так і не змінили або вашої адреси немає в Redirect URLs. Як виправити і якої маски уникати.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":612,"title":613,"description":614,"published":615,"category":521,"image":616,"draft":525},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" на новому посиланні","На посиланні, надісланому хвилину тому, \"Email link is invalid or has expired\" у Supabase зазвичай означає, що поштовий фільтр використав його першим.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":618,"title":619,"description":620,"published":621,"category":521,"image":622,"draft":525},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\": пояснення","Supabase \"canceling statement due to statement timeout\": запит перевищив ліміт своєї ролі, 3 секунди для відвідувача. Спершу перевірте політику RLS.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":283,"title":624,"description":625,"published":626,"category":627,"image":628,"draft":525},"\"Database error deleting user\" у Supabase і що зникає разом","\"Database error deleting user\" у Supabase: ваша база відмовилася видаляти. Причина в логах, а виправлення вирішує, що ще буде видалено.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":630,"title":631,"description":632,"published":633,"category":521,"image":634,"draft":525},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" у Supabase","Вебхук Stripe в Edge Function Supabase пише \"No signatures found matching the expected signature\"? Причин дві. Не вимикайте перевірку.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":636,"title":637,"description":638,"published":639,"category":521,"image":640,"draft":525},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" у Supabase: три причини","Supabase відповідає \"Invalid login credentials\" на неправильний пароль, невідому пошту й акаунт Google. Як зрозуміти, що саме.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":642,"title":643,"description":644,"published":645,"category":521,"image":646,"draft":525},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": справжня помилка","\"Edge Function returned a non-2xx status code\" означає, що ваша функція Supabase відповіла помилкою. Ось де прочитати справжню.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":648,"title":649,"description":650,"published":651,"category":521,"image":652,"draft":525},"\u002Fblog\u002Fcertificate-not-trusted","Сертифікат не довірений: три причини, крім закінчення строку","Сертифікат не довірений, хоча дата в порядку? Він називає іншу адресу, підписав сам себе або в його ланцюжку бракує ланки. Як зрозуміти, що саме.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":654,"title":655,"description":656,"published":657,"category":521,"image":658,"draft":525},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": що в лапках","Supabase \"invalid input syntax for type uuid\" означає, що застосунок надіслав щось, що не є id. Прочитайте лапки, притримайте запит, залиште колонку.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":335,"title":660,"description":661,"published":662,"category":521,"image":663,"draft":525},"Supabase \"duplicate key value violates unique constraint\": пояснення","Supabase \"duplicate key value violates unique constraint\": значення вже зайняте. Знайдіть стовпець, оберіть виправлення й сховайте значення від очей.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":665,"title":666,"description":667,"published":668,"category":521,"image":669,"draft":525},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\", хоча таблиця на місці","Supabase \"relation does not exist\" або PGRST205: жодна таблиця не має такої назви в цій схемі. Чотири перевірки, і на що зважити, відкриваючи схему.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":671,"title":672,"description":673,"published":674,"category":521,"image":675,"draft":525},"\u002Fblog\u002Fsupabase-function-not-found","Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" показує назви аргументів, які надіслав ваш застосунок. Порівняйте їх із функцією.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":677,"title":678,"description":679,"published":680,"category":521,"image":681,"draft":525},"\u002Fblog\u002Fsupabase-schema-cache-column-error","Supabase PGRST204: \"Could not find the column in the schema cache\"","Supabase \"Could not find the column in the schema cache\" зазвичай означає, що назва не збігається. Чотири перевірки і рядок для перезавантаження.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":73,"title":683,"description":684,"published":685,"category":521,"image":686,"draft":525},"Supabase \"Email Rate Limit Exceeded\": два ліміти, один код помилки","Supabase \"Email Rate Limit Exceeded\" обмежує кожен лист вашого проєкту: 2 на годину з вбудованим відправником. Що враховується і як підняти ліміт.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":688,"title":689,"description":690,"published":691,"category":521,"image":692,"draft":525},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 причини","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" виводить ваших користувачів із системи. Три причини і як лог Auth їх розрізняє.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":694,"title":695,"description":696,"published":697,"category":521,"image":698,"draft":525},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": три причини","Supabase \"permission denied for schema public\" означає, що бракує GRANT на схему. Що його прибрало і який рядок його повертає.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":700,"title":701,"description":702,"published":703,"category":521,"image":704,"draft":525},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": три речі, які це може означати","Supabase \"Bucket not found\" означає одне з трьох: публічне посилання на приватний бакет, неточну назву або не той проєкт.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":706,"title":707,"description":708,"published":709,"category":521,"image":710,"draft":525},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: який ключ перестав працювати?","Помилка Supabase invalid JWT — це PGRST301: підписаний токен не пройшов перевірку. У новому проєкті йдеться про сесію, а не про ключ API.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":712,"title":713,"description":714,"published":715,"category":521,"image":716,"draft":525},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" майже завжди означає нуль","Supabase повертає PGRST116, \"JSON object requested, multiple (or no) rows returned\", коли запит нічого не знайшов. Прихований рядок має вигляд відсутнього.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":555,"title":5,"description":524,"published":556,"category":521,"image":543,"draft":525},{"path":719,"title":720,"description":721,"published":722,"category":521,"image":723,"draft":525},"\u002Fblog\u002Fwhat-is-supabase","Що таке Supabase? База даних, яку обрав ваш білдер","Що таке Supabase: база даних, вхід і сховище файлів за вашим застосунком. Supabase тримає сервери, а правила про те, хто читає ваші рядки, ваші.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":725,"title":726,"description":727,"published":728,"category":521,"image":729,"draft":525},"\u002Fblog\u002Faws-access-key-exposed-in-frontend","Відкритий у фронтенді ключ AWS це не те саме, що ключ OpenAI","Ключ доступу AWS, відкритий у вашому фронтенді, читає і пише ваше сховище. Рішення зазвичай presigned URL, а не новий ключ.","2026-10-12","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":731,"title":732,"description":733,"published":734,"category":521,"image":735,"draft":525},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" при вивантаженні","\"New row violates row-level security policy for table objects\" означає, що вашому вивантаженню бракує правила insert. Публічний бакет його не додає.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":737,"title":738,"description":739,"published":740,"category":521,"image":741,"draft":525},"\u002Fblog\u002Fbase44-security-scan","Сканування безпеки Base44: те, що бачить лише воно","Сканування безпеки Base44 перевіряє сім видів проблем зсередини. Ось половина, яку читає тільки воно, і половина, на яку воно ніколи не дивиться.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":743,"title":744,"description":745,"published":746,"category":521,"image":747,"draft":525},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Ваш API-ключ витік. Порядок дій","API-ключ витік, і ви не знаєте, що робити першим. Не кожен ключ у вашому фронтенді є витоком, а порядок важить більше за швидкість.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":749,"title":750,"description":751,"published":752,"category":521,"image":753,"draft":525},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" без вимкнення RLS","\"Infinite recursion detected in policy for relation\" означає, що ваша policy запитала таблицю, яку вона захищає. Ось як розірвати коло.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":755,"title":756,"description":757,"published":758,"category":521,"image":759,"draft":525},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" у Supabase, і хибне виправлення","\"No API key found in request\" означає, що запит дійшов до Supabase без ключа. Більшість відповідей натомість вказують на правила вашої бази.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":761,"title":762,"description":763,"published":764,"category":521,"image":765,"draft":525},"\u002Fblog\u002Fis-base44-safe","Чи безпечний Base44? Дані 5 442 застосунків","Чи безпечний Base44? Ми прогнали дев’ять перевірок на 5 442 робочих застосунках Base44. Майже всі отримали B з причин, яких власник ніколи не обирав.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":767,"title":768,"description":769,"published":770,"category":521,"image":771,"draft":525},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Сховати ключ API: перенесіть його в Supabase Edge Function","Сховати ключ API означає прибрати його з браузера, а Supabase Edge Function це найменше місце, куди його покласти. Два кроки поруч важать більше.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":773,"title":774,"description":775,"published":776,"category":521,"image":777,"draft":525},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Чи відкритий ваш файл .env? Дванадцять шляхів для перевірки","Чи відкритий ваш файл .env на вашому власному вебсервері? Дванадцять адрес скажуть це за хвилину, а влучання означає, що все в ньому вже публічне.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":779,"title":780,"description":781,"published":782,"category":521,"image":783,"draft":525},"\u002Fblog\u002Fis-v0-safe","Безпека v0: усі 1 790 просканованих застосунків v0 отримали A","Безпека v0 на 1 790 живих застосунках v0: усі отримали A. Лише 17 згадували базу даних, і саме це здебільшого вимірює оцінка A.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":785,"title":786,"description":787,"published":788,"category":521,"image":789,"draft":525},"\u002Fblog\u002Fis-bolt-safe","Чи безпечний Bolt? Що показали 1 123 застосунки Bolt","Чи безпечний Bolt? Ми прогнали 1 123 живі застосунки Bolt через дев’ять перевірок. Хостинг був чистим. Знахідки: ключі й відкриті таблиці в самих застосунках.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":521,"image":795,"draft":525},"\u002Fblog\u002Fis-supabase-down-or-your-app","Supabase не працює чи проблема у вашому застосунку? Як розрізнити","Supabase не працює чи зламався ваш застосунок? Пауза, повна база й ваша власна помилка виглядають однаково. Чотири перевірки їх розрізняють.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":797,"title":798,"description":799,"published":800,"category":521,"image":801,"draft":525},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Чи шифрує Supabase мої дані? Так. Ось від чого це захищає","Чи шифрує Supabase дані? Так: AES-256 у стані спокою, TLS під час передавання, SOC 2 та ISO 27001. Що покриває кожне і який витік не зупиняє жодне.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":803,"title":804,"description":805,"published":806,"category":521,"image":807,"draft":525},"\u002Fblog\u002Fsupabase-free-plan-limits","Ліміти безкоштовного тарифу Supabase і що стається на кожному","Ліміти безкоштовного тарифу Supabase: 500 МБ бази, 5 ГБ egress і жодних резервних копій. Що стається на кожній межі і що змінює Pro за $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":809,"title":810,"description":811,"published":812,"category":627,"image":813,"draft":525},"\u002Fblog\u002Ftest-your-supabase-backup","Перевірте резервну копію Supabase до того, як вона знадобиться","Як перевірити резервну копію Supabase: відновити в тестовий проєкт, порахувати рядки, увійти й знайти рядок, якого бракує обрізаному файлу.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":815,"title":816,"description":817,"published":818,"category":627,"image":819,"draft":525},"\u002Fblog\u002Fsupabase-backup-github-action","Безкоштовна резервна копія Supabase через GitHub Action і підступ","Резервна копія Supabase через GitHub Action безкоштовна й годиться багатьом застосункам. Робочий процес, потрібний рядок підключення та egress.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":821,"title":822,"description":823,"published":824,"category":627,"image":825,"draft":525},"\u002Fblog\u002Fdownload-your-supabase-backup","Чому ви не можете завантажити резервну копію Supabase","Завантажити резервну копію Supabase на сучасному проєкті не вийде: щоденна копія там фізична. Як це перевірити і як тримати власну копію.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":827,"title":828,"description":829,"published":824,"category":521,"image":830,"draft":525},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": бракує GRANT","З 30 жовтня нова таблиця в Supabase відповідає \"permission denied for table\", доки ви не дасте доступ. Лист показує лише половину виправлення.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":832,"title":833,"description":834,"published":835,"category":521,"image":836,"draft":525},"\u002Fblog\u002Fopen-api-endpoint-exposed","Чи є відкритий API-ендпоінт проблемою безпеки? Читайте JSON","Ваше сканування позначило відкритий API-ендпоінт. Чи це важливо, залежить від того, що повернулося, і більшість знайдених належали платформі.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":838,"title":839,"description":840,"published":841,"category":521,"image":842,"draft":525},"\u002Fblog\u002Flovable-security-scan","Сканування безпеки Lovable: чого воно не доведе","Сканування безпеки Lovable: що перевіряють Quick scan і Deep scan, коли запускається кожне, і єдине, чого не доведе жодне сканування зсередини.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":844,"title":845,"description":846,"published":847,"category":627,"image":848,"draft":525},"\u002Fblog\u002Fsupabase-backup-auth-users","Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":850,"title":851,"description":852,"published":853,"category":521,"image":854,"draft":525},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":856,"title":857,"description":858,"published":859,"category":521,"image":860,"draft":525},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":862,"title":863,"description":864,"published":865,"category":521,"image":866,"draft":525},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":868,"title":869,"description":870,"published":871,"category":521,"image":872,"draft":525},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":874,"title":875,"description":876,"published":877,"category":521,"image":878,"draft":525},"\u002Fblog\u002Fvite-and-next-public-env-vars","Змінні оточення Vite відкриті: префікс означає опублікувати це","Змінні оточення Vite відкриті у вашому застосунку, бо так просив префікс. VITE_ і NEXT_PUBLIC_ означають опублікувати це, а ШІ, який їх додав, не знав ціни.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":880,"title":881,"description":882,"published":883,"category":521,"image":884,"draft":525},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":886,"title":887,"description":888,"published":889,"category":521,"image":890,"draft":525},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":892,"title":893,"description":894,"published":895,"category":521,"image":896,"draft":525},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":898,"title":899,"description":900,"published":901,"category":627,"image":902,"draft":525},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":904,"title":905,"description":906,"published":907,"category":627,"image":908,"draft":525},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery у Supabase: ціна та межі","Point-in-time recovery у Supabase відмотує базу на будь-яку секунду за останній тиждень. Коштує $100 на місяць понад Pro і покриває лише базу даних.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":910,"title":911,"description":912,"published":913,"category":627,"image":914,"draft":525},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":916,"title":917,"description":918,"published":919,"category":521,"image":920,"draft":525},"\u002Fblog\u002Fsafest-ai-app-builder","Який білдер застосунків з ШІ найбезпечніший? 30 998 тестів","Який білдер застосунків з ШІ найбезпечніший? Ми просканували 30 998 живих застосунків з Lovable, Base44, Replit, v0 і Bolt. Оцінку вирішує не білдер.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":249,"title":922,"description":923,"published":924,"category":521,"image":925,"draft":525},"Увімкніть Row Level Security на кожній таблиці Supabase і перевірте","Row Level Security у Supabase без політики закриває таблицю повністю. Політика без увімкненого перемикача не робить нічого. Ось SQL, і ось перевірка.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":927,"title":928,"description":929,"published":930,"category":521,"image":931,"draft":525},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": чого не бачить попередження","Supabase позначає \"RLS disabled in public\" як помилку. Про політику читання, яка лишає вашу таблицю так само відкритою, він не каже нічого.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":933,"title":934,"description":935,"published":936,"category":521,"image":937,"draft":525},"\u002Fblog\u002Frotate-supabase-service-role-key","Як замінити злитий ключ service_role у Supabase","Supabase каже спершу закрити витік. Інші посібники кажуть міняти негайно. Що правильно, залежить від того, куди саме потрапив ваш ключ service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":939,"title":940,"description":941,"published":942,"category":521,"image":943,"draft":525},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Вісім інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":945,"title":946,"description":947,"published":948,"category":521,"image":949,"draft":525},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":951,"title":952,"description":953,"published":954,"category":521,"image":955,"draft":525},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":957,"title":958,"description":959,"published":960,"category":521,"image":961,"draft":525},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":963,"title":964,"description":965,"published":966,"category":521,"image":967,"draft":525},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Ваш ключ API OpenAI відкритий у фронтенді. Замініть його.","Ключ API OpenAI, відкритий у фронтенді, не можна прив'язати до домену. Замініть його сьогодні, перенесіть виклик на свій сервер і обмежте витрати.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":969,"title":970,"description":971,"published":972,"category":521,"image":973,"draft":525},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Ключ API у фронтенді: що насправді віддають 30 998 застосунків","Ключ API, відкритий у вашому фронтенді, зазвичай є ключем Google Maps. Ми просканували 30 998 vibe-coded застосунків і порахували, що витікає насправді.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":975,"title":976,"description":977,"published":978,"category":627,"image":979,"draft":525},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":981,"title":982,"description":983,"published":984,"category":521,"image":985,"draft":525},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":987,"title":988,"description":989,"published":990,"category":627,"image":991,"draft":525},"\u002Fblog\u002Fback-up-supabase-free-tier","Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":993,"title":994,"description":995,"published":996,"category":521,"image":997,"draft":525},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":999,"title":1000,"description":1001,"published":1002,"category":521,"image":1003,"draft":525},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":254,"title":1005,"description":1006,"published":1007,"category":521,"image":1008,"draft":525},"New row violates row-level security policy в Supabase. Що далі?","\"New row violates row-level security policy\" означає, що Supabase відмовив у записі. Швидке виправлення знову відкриває таблицю для всіх.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":1010,"title":1011,"description":1012,"published":1013,"category":521,"image":1014,"draft":525},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":1016,"title":1017,"description":1018,"published":1019,"category":627,"image":1020,"draft":525},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching у Supabase це не бекап. Він іде тільки вперед.","Чому branching у Supabase це не бекап: гілка стартує без ваших даних, а мердж переносить саму лише схему. Для чого він потрібен і що брати замість нього.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":1022,"title":1023,"description":1024,"published":1025,"category":627,"image":1026,"draft":525},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":1028,"title":1029,"description":1030,"published":1031,"category":521,"image":1032,"draft":525},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":1034,"title":1035,"description":1036,"published":1037,"category":521,"image":1038,"draft":525},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Чи є проблемою ключ API Google у вашому браузері?","Ключ API Google у відкритому коді сторінки наш сканер знаходить найчастіше, і зазвичай усе гаразд. Вирішує це одне безкоштовне налаштування.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1040,"title":1041,"description":1042,"published":1043,"category":627,"image":1044,"draft":525},"\u002Fblog\u002Fai-agent-deleted-my-database","ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":1046,"title":1047,"description":1048,"published":1049,"category":521,"image":1050,"draft":525},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Чи може будь-хто прочитати вашу базу Supabase? 3 680 застосунків","Чи може будь-хто прочитати вашу базу даних Supabase без входу? Ми просканували 30 998 живих застосунків, зроблених ШІ-білдерами, і виміряли, як часто так.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":1052,"title":1053,"description":1054,"published":1049,"category":521,"image":1055,"draft":525},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":1057,"title":1058,"description":1059,"published":1060,"category":521,"image":1061,"draft":525},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: це той самий anon key?","Supabase замінив anon і service_role публічними та секретними ключами. Який із них має бути у вашому застосунку, а який не має бути ніколи?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":1063,"title":1064,"description":1065,"published":1066,"category":627,"image":1067,"draft":525},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":1069,"title":1070,"description":1071,"published":1072,"category":521,"image":1073,"draft":525},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security увімкнено. Таблиця досі публічна.","Увімкнути Supabase Row Level Security не означає захистити таблицю. Захищають політики, а та, що полагодила застосунок, часто впускає всіх.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":1075,"title":1076,"description":1077,"published":1072,"category":627,"image":1078,"draft":525},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":1080,"title":1081,"description":1082,"published":1083,"category":627,"image":1084,"draft":525},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Три способи зробити резервну копію бази Supabase, і чого бракує","Панель, pg_dump і керований сервіс. Що насправді зберігає кожен спосіб, що тихо лишає осторонь і який із них переживе втрату акаунта.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":1086,"title":1087,"description":1088,"published":1083,"category":521,"image":1089,"draft":525},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Які API-ключі безпечні у браузері, а які ні","Ваш ключ anon у Supabase створений, щоб бути публічним. Ключ service_role для цього не створений, і він ігнорує всі правила, які ви задали. Як їх розрізнити.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1794213654457]