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