Сайт пароля сброса SupabaseJavascript

Форум по Javascript
Ответить
Anonymous
 Сайт пароля сброса Supabase

Сообщение Anonymous »

Я хочу сделать файлы HTML и JS для создания пароля сброса с помощью Supabase. Я загрузил файл index.html и script.js и css в github и добавил страницу URL Github в Supaabse и внутри моего приложения, когда пользователь входит в свою электронную почту и нажмите ссылку «Сбросить сброс», ссылка отправляется им по электронной почте, и когда он нажимает, он открывает правильный сайт. Итак, это нормально. < /P>
Проблема в том, что я получаю ошибку: < /p>

uncaught referenceerror: supabase не определяется.const supabase = Supabase.createClient(supabaseUrl, supabaseAnonKey);
< /code>
index.html




Reset Password






Set New Password



🔒


🔒


Save Password










< /code>
style.css
font-family: sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #f0f2f5;
}

.container {
background-color: #ffffff;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
max-width: 400px;
width: 90%;
overflow: hidden;
display: flex;
flex-direction: column;
}

.app-bar {
background-color: #2c92ff; /* Corresponds to your Flutter primary color */
color: white;
padding: 20px;
text-align: center;
font-weight: bold;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}

.app-bar h1 {
margin: 0;
font-size: 24px;
}

.content {
padding: 20px;
display: flex;
flex-direction: column;
gap: 16px; /* Spacing between input fields and button */
}

.input-group {
position: relative;
width: 100%;
}

.input-group input {
width: calc(100% - 40px); /* Adjust for icon */
padding: 15px 15px 15px 45px; /* Left padding for icon */
border: none;
border-radius: 10px;
background-color: #e0e0e0; /* Corresponds to Colors.grey[200] */
font-size: 16px;
box-sizing: border-box; /* Include padding in width */
}

.input-group input::placeholder {
color: #888;
}

.input-group .icon {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
color: #666;
}

.button-container {
margin-top: 20px; /* Spacing above the button */
display: flex;
justify-content: center;
align-items: center;
min-height: 58px; /* To prevent layout shift when loading spinner appears */
}

.custom-button {
width: 100%;
padding: 16px 0;
background-color: #2c92ff; /* Your button background color */
color: white;
border: none;
border-radius: 10px;
font-size: 20px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 5px 0 #0067d6; /* Your button shadow color */
transition: all 0.05s ease;
box-sizing: border-box;
}

.custom-button:active {
transform: translateY(2px);
box-shadow: 0 3px 0 #0067d6; /* Smaller shadow when pressed */
}

.loading-spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #2c92ff;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

.message {
margin-top: 10px;
padding: 10px;
border-radius: 5px;
text-align: center;
font-weight: bold;
display: none; /* Initially hidden */
}

.message.error {
background-color: #ffe0e0;
color: #d32f2f;
}

.message.success {
background-color: #e8f5e9;
color: #388e3c;
}
< /code>
script.js

// Initialize Supabase client
// ENSURE these URL and ANON KEY are correct for YOUR Supabase project.
const supabaseUrl = 'i have my actual project url here';
const supabaseAnonKey = 'i have my actual annon key here';

// This event listener ensures that the DOM is fully loaded and parsed
// before any of your JavaScript code that interacts with it is executed.
document.addEventListener('DOMContentLoaded', () => {
// This line will now only execute AFTER the Supabase CDN script has loaded and defined 'Supabase'.
const supabase = Supabase.createClient(supabaseUrl, supabaseAnonKey);

// Get references to all HTML elements
const newPasswordInput = document.getElementById('newPassword');
const confirmPasswordInput = document.getElementById('confirmPassword');
const savePasswordBtn = document.getElementById('savePasswordBtn');
const loadingIndicator = document.getElementById('loadingIndicator');
const messageDisplay = document.getElementById('message');

// Helper function to show messages
function showMessage(message, isError = true) {
messageDisplay.textContent = message;
messageDisplay.className = 'message'; // Reset classes
if (isError) {
messageDisplay.classList.add('error');
} else {
messageDisplay.classList.add('success');
}
messageDisplay.style.display = 'block'; // Make sure it's visible
}

// Function to handle password reset
async function handleResetPassword() {
const newPassword = newPasswordInput.value;
const confirmPassword = confirmPasswordInput.value;

// Clear previous messages
messageDisplay.style.display = 'none';
messageDisplay.textContent = '';

// Basic validation
if (!newPassword || !confirmPassword) {
showMessage('Please fill in both password fields.', true);
return;
}

if (newPassword !== confirmPassword) {
showMessage('Passwords do not match.', true);
return;
}

if (newPassword.length < 6) {
showMessage('Password must be at least 6 characters long.', true);
return;
}

// Show loading indicator and hide button
savePasswordBtn.style.display = 'none';
loadingIndicator.style.display = 'block';

try {
// The `updateUser` method automatically uses the access_token from the URL.
const { data, error } = await supabase.auth.updateUser({
password: newPassword
});

if (error) {
console.error('Supabase update error:', error); // Log full error for debugging
showMessage(`Error updating password: ${error.message}`, true);
} else if (data.user) {
showMessage('Password updated successfully! You can now log in.', false);
console.log('Password updated successfully for user:', data.user); // Log success
// Optionally, redirect to a login page after success
// setTimeout(() => {
// window.location.href = '/login.html'; // Adjust to your login page path
// }, 3000);
} else {
// This is a fallback for an unexpected API response
showMessage('Failed to update password. Please try again.', true);
console.warn('Supabase update failed, but no specific error and no user data.', data);
}
} catch (e) {
console.error('An unexpected error occurred:', e); // Catch any other unexpected errors
showMessage(`An unexpected error occurred: ${e.message}`, true);
} finally {
// Hide loading indicator, show button
savePasswordBtn.style.display = 'block';
loadingIndicator.style.display = 'none';
// Clear password fields for security
newPasswordInput.value = '';
confirmPasswordInput.value = '';
}
}

// Attach event listener to the button
savePasswordBtn.addEventListener('click', handleResetPassword);

// Initial check for hash fragment (access token) when page loads.
const urlParams = new URLSearchParams(window.location.hash.substring(1));
const accessToken = urlParams.get('access_token');
const refreshToken = urlParams.get('refresh_token');

if (accessToken && refreshToken) {
console.log('Access token and refresh token found in URL hash. Supabase will use this to update the user.');
} else {
console.warn('No access_token or refresh_token found in URL hash. Please use the link from your password reset email to access this page.');
// Optionally show a message to guide the user
// showMessage('Please use the link from your password reset email to set a new password.', true);
}
});


Подробнее здесь: https://stackoverflow.com/questions/796 ... sword-site
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»