Fix: только cookie auth (без Authorization) — все запросы без preflight
- api.js: убрал Authorization header для всех методов (cookie достаточно)
- убрал refresh block (cookie живёт дольше)
- profile.save: явный feedback ("⏳ Сохраняю..." → "✓ Сохранено") + try/catch вокруг TG_APP.haptic
This commit is contained in:
parent
ce3c863e66
commit
d44eb2be8d
@ -42,32 +42,13 @@ const Store = {
|
|||||||
|
|
||||||
async function api(path, opts = {}) {
|
async function api(path, opts = {}) {
|
||||||
opts.headers = opts.headers || {};
|
opts.headers = opts.headers || {};
|
||||||
// для GET используем cookie (без CORS preflight), для мутаций — Authorization
|
// НЕ шлём Authorization — используем HttpOnly cookie (без CORS preflight)
|
||||||
const isGet = !opts.method || opts.method === 'GET' || opts.method === 'HEAD';
|
// Middleware читает cookie buhapp_at
|
||||||
if (Store.access && !opts.headers.Authorization && !isGet) {
|
|
||||||
opts.headers.Authorization = `Bearer ${Store.access}`;
|
|
||||||
}
|
|
||||||
if (opts.body && typeof opts.body === 'object' && !(opts.body instanceof FormData)) {
|
if (opts.body && typeof opts.body === 'object' && !(opts.body instanceof FormData)) {
|
||||||
opts.headers['Content-Type'] = 'application/json';
|
opts.headers['Content-Type'] = 'application/json';
|
||||||
opts.body = JSON.stringify(opts.body);
|
opts.body = JSON.stringify(opts.body);
|
||||||
}
|
}
|
||||||
let r = await fetch(API_BASE + path, { ...opts, credentials: 'include' });
|
let r = await fetch(API_BASE + path, { ...opts, credentials: 'include' });
|
||||||
if (r.status === 401 && Store.refresh) {
|
|
||||||
// refresh
|
|
||||||
const r2 = await fetch(API_BASE + '/api/v1/auth/refresh', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ Refresh: Store.refresh }),
|
|
||||||
});
|
|
||||||
if (r2.ok) {
|
|
||||||
const tokens = await r2.json();
|
|
||||||
Store.save(tokens);
|
|
||||||
opts.headers.Authorization = `Bearer ${Store.access}`;
|
|
||||||
r = await fetch(API_BASE + path, opts);
|
|
||||||
} else {
|
|
||||||
Store.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const text = await r.text();
|
const text = await r.text();
|
||||||
let data = null;
|
let data = null;
|
||||||
try { data = text ? JSON.parse(text) : null; } catch { data = text; }
|
try { data = text ? JSON.parse(text) : null; } catch { data = text; }
|
||||||
|
|||||||
@ -95,6 +95,9 @@ const ProfileView = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async save() {
|
async save() {
|
||||||
|
const btn = document.getElementById('p-save');
|
||||||
|
const orig = btn ? btn.textContent : null;
|
||||||
|
if (btn) { btn.disabled = true; btn.textContent = '⏳ Сохраняю…'; }
|
||||||
try {
|
try {
|
||||||
await API.Auth.updateMe({
|
await API.Auth.updateMe({
|
||||||
name: document.getElementById('p-name').value.trim(),
|
name: document.getElementById('p-name').value.trim(),
|
||||||
@ -107,10 +110,14 @@ const ProfileView = {
|
|||||||
activities: [...this.activities],
|
activities: [...this.activities],
|
||||||
purposes: [...this.purposes],
|
purposes: [...this.purposes],
|
||||||
});
|
});
|
||||||
TG_APP.haptic('notification');
|
try { TG_APP.haptic('notification'); } catch {}
|
||||||
App.toast('Сохранено ✓');
|
App.toast('✓ Сохранено');
|
||||||
|
if (btn) { btn.textContent = '✓ Сохранено'; setTimeout(() => { btn.textContent = orig || 'Сохранить'; btn.disabled = false; }, 1500); }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
TG_APP.showAlert('Ошибка: ' + e.message);
|
console.error('save profile:', e);
|
||||||
|
App.toast('⚠️ ' + e.message);
|
||||||
|
TG_APP.showAlert('Ошибка сохранения: ' + e.message);
|
||||||
|
if (btn) { btn.disabled = false; btn.textContent = orig || 'Сохранить'; }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user