fix: use apiClient instead of httponly cookie in merchant stores/profile pages
The merchant_token cookie is httponly, so JS cannot read it via document.cookie. This caused getToken() to return null, redirecting users to login, which then bounced back to dashboard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -151,28 +151,9 @@ function merchantProfile() {
|
|||||||
this.loadProfile();
|
this.loadProfile();
|
||||||
},
|
},
|
||||||
|
|
||||||
getToken() {
|
|
||||||
const match = document.cookie.match(/(?:^|;\s*)merchant_token=([^;]*)/);
|
|
||||||
return match ? decodeURIComponent(match[1]) : null;
|
|
||||||
},
|
|
||||||
|
|
||||||
async loadProfile() {
|
async loadProfile() {
|
||||||
const token = this.getToken();
|
|
||||||
if (!token) {
|
|
||||||
window.location.href = '/merchants/login';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/api/v1/merchants/account/profile', {
|
const data = await apiClient.get('/merchants/account/profile');
|
||||||
headers: { 'Authorization': `Bearer ${token}` }
|
|
||||||
});
|
|
||||||
if (resp.status === 401) {
|
|
||||||
window.location.href = '/merchants/login';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!resp.ok) throw new Error('Failed to load profile');
|
|
||||||
const data = await resp.json();
|
|
||||||
|
|
||||||
this.form.name = data.name || '';
|
this.form.name = data.name || '';
|
||||||
this.form.contact_email = data.contact_email || data.email || '';
|
this.form.contact_email = data.contact_email || data.email || '';
|
||||||
@@ -193,22 +174,9 @@ function merchantProfile() {
|
|||||||
this.error = null;
|
this.error = null;
|
||||||
this.successMessage = null;
|
this.successMessage = null;
|
||||||
|
|
||||||
const token = this.getToken();
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/api/v1/merchants/account/profile', {
|
await apiClient.put('/merchants/account/profile', this.form);
|
||||||
method: 'PUT',
|
|
||||||
headers: {
|
|
||||||
'Authorization': `Bearer ${token}`,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(this.form)
|
|
||||||
});
|
|
||||||
if (!resp.ok) {
|
|
||||||
const data = await resp.json();
|
|
||||||
throw new Error(data.detail || 'Failed to save profile');
|
|
||||||
}
|
|
||||||
this.successMessage = 'Profile updated successfully.';
|
this.successMessage = 'Profile updated successfully.';
|
||||||
// Auto-hide success message after 3 seconds
|
|
||||||
setTimeout(() => { this.successMessage = null; }, 3000);
|
setTimeout(() => { this.successMessage = null; }, 3000);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.error = err.message;
|
this.error = err.message;
|
||||||
|
|||||||
@@ -92,28 +92,9 @@ function merchantStores() {
|
|||||||
this.loadStores();
|
this.loadStores();
|
||||||
},
|
},
|
||||||
|
|
||||||
getToken() {
|
|
||||||
const match = document.cookie.match(/(?:^|;\s*)merchant_token=([^;]*)/);
|
|
||||||
return match ? decodeURIComponent(match[1]) : null;
|
|
||||||
},
|
|
||||||
|
|
||||||
async loadStores() {
|
async loadStores() {
|
||||||
const token = this.getToken();
|
|
||||||
if (!token) {
|
|
||||||
window.location.href = '/merchants/login';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/api/v1/merchants/account/stores', {
|
const data = await apiClient.get('/merchants/account/stores');
|
||||||
headers: { 'Authorization': `Bearer ${token}` }
|
|
||||||
});
|
|
||||||
if (resp.status === 401) {
|
|
||||||
window.location.href = '/merchants/login';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!resp.ok) throw new Error('Failed to load stores');
|
|
||||||
const data = await resp.json();
|
|
||||||
this.stores = data.stores || data.items || [];
|
this.stores = data.stores || data.items || [];
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error loading stores:', err);
|
console.error('Error loading stores:', err);
|
||||||
|
|||||||
Reference in New Issue
Block a user