301 lines
9.8 KiB
HTML
301 lines
9.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title>Farm Auth Tester</title>
|
|
<style>
|
|
body { font-family: sans-serif; max-width: 600px; margin: 20px auto; }
|
|
h2 { margin-top: 24px; }
|
|
label { display: block; margin-top: 8px; }
|
|
input, select { width: 100%; padding: 6px; margin-top: 4px; }
|
|
button { margin-top: 10px; padding: 8px 12px; cursor: pointer; }
|
|
.section { border: 1px solid #ddd; padding: 12px; border-radius: 6px; margin-top: 16px; }
|
|
pre { background: #f7f7f7; padding: 8px; overflow-x: auto; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Farm Auth Service Tester</h1>
|
|
|
|
<div class="section">
|
|
<h2>1. Request OTP</h2>
|
|
<label>Phone Number (E.164, e.g. +91XXXXXXXXXX)</label>
|
|
<input id="phone" type="text" placeholder="+91..." />
|
|
|
|
<button id="requestOtpBtn">Request OTP</button>
|
|
|
|
<pre id="requestOtpResult"></pre>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h2>2. Verify OTP</h2>
|
|
<label>OTP Code</label>
|
|
<input id="otp" type="text" placeholder="123456" />
|
|
|
|
<label>Device ID</label>
|
|
<input id="deviceId" type="text" value="web-test-device" />
|
|
|
|
<button id="verifyOtpBtn">Verify OTP</button>
|
|
|
|
<pre id="verifyOtpResult"></pre>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h2>3. Complete Profile (name + user_type)</h2>
|
|
<p>Uses the <code>access_token</code> from step 2</p>
|
|
|
|
<label>Name</label>
|
|
<input id="name" type="text" placeholder="Your name" />
|
|
|
|
<label>User Type</label>
|
|
<select id="userType">
|
|
<option value="seller">Seller</option>
|
|
<option value="buyer">Buyer</option>
|
|
<option value="service_provider">Service Provider</option>
|
|
</select>
|
|
|
|
<button id="updateProfileBtn">Update Profile</button>
|
|
|
|
<pre id="updateProfileResult"></pre>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h2>4. Get User Details</h2>
|
|
<p>Authenticated GET request to fetch user profile with JWT token</p>
|
|
<p>Shows: phone number, name, profile type, location, last login, and all saved locations</p>
|
|
|
|
<button id="getUserDetailsBtn">Get User Details</button>
|
|
|
|
<pre id="getUserDetailsResult"></pre>
|
|
</div>
|
|
|
|
<script>
|
|
let accessToken = null;
|
|
let refreshToken = null;
|
|
|
|
// Add error handler for uncaught errors
|
|
window.addEventListener('error', (e) => {
|
|
console.error('Global error:', e);
|
|
alert('JavaScript error: ' + e.message);
|
|
});
|
|
|
|
async function requestOtp() {
|
|
const phone = document.getElementById('phone').value.trim();
|
|
const out = document.getElementById('requestOtpResult');
|
|
|
|
if (!phone) {
|
|
out.textContent = 'Error: Please enter a phone number';
|
|
alert('Please enter a phone number');
|
|
return;
|
|
}
|
|
|
|
out.textContent = 'Sending...';
|
|
console.log('Requesting OTP for:', phone);
|
|
|
|
try {
|
|
const res = await fetch('/auth/request-otp', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ phone_number: phone })
|
|
});
|
|
|
|
console.log('Response status:', res.status);
|
|
const data = await res.json();
|
|
console.log('Response data:', data);
|
|
out.textContent = JSON.stringify(data, null, 2);
|
|
|
|
if (res.ok) {
|
|
alert('OTP sent successfully! Check your phone or server logs.');
|
|
} else {
|
|
alert('Error: ' + (data.error || data.message || 'Failed to send OTP'));
|
|
}
|
|
} catch (err) {
|
|
console.error('Request OTP error:', err);
|
|
out.textContent = 'Error: ' + err.message;
|
|
alert('Error: ' + err.message);
|
|
}
|
|
}
|
|
|
|
async function verifyOtp() {
|
|
const phone = document.getElementById('phone').value.trim();
|
|
const otp = document.getElementById('otp').value.trim();
|
|
const deviceId = document.getElementById('deviceId').value.trim() || 'web-test-device';
|
|
const out = document.getElementById('verifyOtpResult');
|
|
|
|
if (!phone) {
|
|
out.textContent = 'Error: Please enter a phone number';
|
|
alert('Please enter a phone number');
|
|
return;
|
|
}
|
|
|
|
if (!otp) {
|
|
out.textContent = 'Error: Please enter an OTP code';
|
|
alert('Please enter an OTP code');
|
|
return;
|
|
}
|
|
|
|
out.textContent = 'Verifying...';
|
|
console.log('Verifying OTP for:', phone, 'code:', otp);
|
|
|
|
try {
|
|
const res = await fetch('/auth/verify-otp', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
phone_number: phone,
|
|
code: otp,
|
|
device_id: deviceId,
|
|
device_info: {
|
|
platform: 'web',
|
|
model: 'browser',
|
|
os_version: navigator.userAgent,
|
|
app_version: 'web-test',
|
|
language_code: navigator.language,
|
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
}
|
|
})
|
|
});
|
|
|
|
console.log('Response status:', res.status);
|
|
const data = await res.json();
|
|
console.log('Response data:', data);
|
|
out.textContent = JSON.stringify(data, null, 2);
|
|
|
|
if (res.ok) {
|
|
accessToken = data.access_token;
|
|
refreshToken = data.refresh_token;
|
|
console.log('Access token set:', accessToken);
|
|
console.log('Refresh token set:', refreshToken);
|
|
alert('OTP verified successfully! needs_profile = ' + data.needs_profile);
|
|
} else {
|
|
alert('Error: ' + (data.error || data.message || 'OTP verification failed'));
|
|
}
|
|
} catch (err) {
|
|
console.error('Verify OTP error:', err);
|
|
out.textContent = 'Error: ' + err.message;
|
|
alert('Error: ' + err.message);
|
|
}
|
|
}
|
|
|
|
async function updateProfile() {
|
|
const name = document.getElementById('name').value.trim();
|
|
const userType = document.getElementById('userType').value;
|
|
const out = document.getElementById('updateProfileResult');
|
|
|
|
if (!accessToken) {
|
|
alert('No access_token. Verify OTP first.');
|
|
out.textContent = 'Error: No access token. Please verify OTP first.';
|
|
return;
|
|
}
|
|
|
|
if (!name) {
|
|
alert('Please enter a name');
|
|
out.textContent = 'Error: Please enter a name';
|
|
return;
|
|
}
|
|
|
|
out.textContent = 'Updating profile...';
|
|
console.log('Updating profile:', { name, user_type: userType });
|
|
|
|
try {
|
|
const res = await fetch('/users/me', {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Bearer ' + accessToken,
|
|
},
|
|
body: JSON.stringify({ name, user_type: userType })
|
|
});
|
|
|
|
console.log('Response status:', res.status);
|
|
const data = await res.json();
|
|
console.log('Response data:', data);
|
|
out.textContent = JSON.stringify(data, null, 2);
|
|
|
|
if (res.ok) {
|
|
alert('Profile updated successfully!');
|
|
} else {
|
|
alert('Error: ' + (data.error || data.message || 'Failed to update profile'));
|
|
}
|
|
} catch (err) {
|
|
console.error('Update profile error:', err);
|
|
out.textContent = 'Error: ' + err.message;
|
|
alert('Error: ' + err.message);
|
|
}
|
|
}
|
|
|
|
async function getUserDetails() {
|
|
const out = document.getElementById('getUserDetailsResult');
|
|
|
|
if (!accessToken) {
|
|
alert('No access_token. Verify OTP first.');
|
|
out.textContent = 'Error: No access token. Please verify OTP first.';
|
|
return;
|
|
}
|
|
|
|
out.textContent = 'Fetching user details...';
|
|
console.log('Fetching user details with token:', accessToken.substring(0, 20) + '...');
|
|
|
|
try {
|
|
const res = await fetch('/users/me', {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Bearer ' + accessToken,
|
|
}
|
|
});
|
|
|
|
console.log('Response status:', res.status);
|
|
const data = await res.json();
|
|
console.log('Response data:', data);
|
|
|
|
if (res.ok) {
|
|
out.textContent = JSON.stringify(data, null, 2);
|
|
alert('User details fetched successfully!');
|
|
} else {
|
|
out.textContent = `Error ${res.status}: ${JSON.stringify(data, null, 2)}`;
|
|
|
|
// If token expired, try to refresh
|
|
if (res.status === 401) {
|
|
alert('Access token expired. Try refreshing the token or verify OTP again.');
|
|
} else {
|
|
alert('Error: ' + (data.error || data.message || 'Failed to fetch user details'));
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('Get user details error:', err);
|
|
out.textContent = 'Error: ' + err.message;
|
|
alert('Error: ' + err.message);
|
|
}
|
|
}
|
|
|
|
// Attach event listeners to buttons (replaces inline onclick handlers)
|
|
// Since script is at end of body, DOM is already loaded
|
|
(function() {
|
|
const requestOtpBtn = document.getElementById('requestOtpBtn');
|
|
const verifyOtpBtn = document.getElementById('verifyOtpBtn');
|
|
const updateProfileBtn = document.getElementById('updateProfileBtn');
|
|
const getUserDetailsBtn = document.getElementById('getUserDetailsBtn');
|
|
|
|
if (requestOtpBtn) {
|
|
requestOtpBtn.addEventListener('click', requestOtp);
|
|
console.log('Request OTP button listener attached');
|
|
}
|
|
if (verifyOtpBtn) {
|
|
verifyOtpBtn.addEventListener('click', verifyOtp);
|
|
console.log('Verify OTP button listener attached');
|
|
}
|
|
if (updateProfileBtn) {
|
|
updateProfileBtn.addEventListener('click', updateProfile);
|
|
console.log('Update Profile button listener attached');
|
|
}
|
|
if (getUserDetailsBtn) {
|
|
getUserDetailsBtn.addEventListener('click', getUserDetails);
|
|
console.log('Get User Details button listener attached');
|
|
}
|
|
|
|
console.log('Test page loaded. All event listeners attached.');
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|