parent
b3242b84ff
commit
1ec1ba0028
4 changed files with 192 additions and 30 deletions
|
|
@ -110,15 +110,53 @@ const el = {
|
|||
// --- API Helpers ---
|
||||
|
||||
async function api(path, options = {}) {
|
||||
const res = await fetch(path, {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
...(options.headers || {}),
|
||||
};
|
||||
|
||||
const token = localStorage.getItem("chattz_token");
|
||||
if (token) {
|
||||
headers["Authorization"] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
let res = await fetch(path, {
|
||||
...options,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
...(options.headers || {}),
|
||||
},
|
||||
credentials: "same-origin",
|
||||
headers,
|
||||
});
|
||||
|
||||
// Handle 401 Unauthorized via Refresh Token
|
||||
if (res.status === 401 && !path.includes('/auth/refresh')) {
|
||||
const refreshToken = localStorage.getItem("chattz_refresh_token");
|
||||
if (refreshToken) {
|
||||
try {
|
||||
const refreshRes = await fetch('/auth/refresh', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify({ refresh_token: refreshToken })
|
||||
});
|
||||
|
||||
if (refreshRes.ok) {
|
||||
const newTokens = await refreshRes.json();
|
||||
localStorage.setItem("chattz_token", newTokens.access_token);
|
||||
localStorage.setItem("chattz_refresh_token", newTokens.refresh_token);
|
||||
|
||||
// Retry original request with new token
|
||||
headers["Authorization"] = `Bearer ${newTokens.access_token}`;
|
||||
res = await fetch(path, { ...options, headers });
|
||||
} else {
|
||||
// Both tokens invalid/expired
|
||||
throw new Error("Refresh token expired or invalid");
|
||||
}
|
||||
} catch (err) {
|
||||
localStorage.removeItem("chattz_token");
|
||||
localStorage.removeItem("chattz_refresh_token");
|
||||
location.href = "/auth/login";
|
||||
throw new Error("Session expired, please log in again");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
let detail = "request failed";
|
||||
try {
|
||||
|
|
@ -523,7 +561,11 @@ function startVoicePresencePolling() {
|
|||
function initChatWs() {
|
||||
if (state.chatWs) state.chatWs.close();
|
||||
const protocol = location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const wsUrl = `${protocol}//${location.host}/ws`;
|
||||
let wsUrl = `${protocol}//${location.host}/ws`;
|
||||
const token = localStorage.getItem("chattz_token");
|
||||
if (token) {
|
||||
wsUrl += (wsUrl.includes('?') ? '&' : '?') + `token=${token}`;
|
||||
}
|
||||
const ws = new WebSocket(wsUrl);
|
||||
state.chatWs = ws;
|
||||
|
||||
|
|
@ -567,7 +609,12 @@ function initChatWs() {
|
|||
|
||||
function getVoiceWsUrl(channelId) {
|
||||
const proto = location.protocol === "https:" ? "wss" : "ws";
|
||||
return `${proto}://${location.host}/channels/${channelId}/voice/ws`;
|
||||
let urlStr = `${proto}://${location.host}/channels/${channelId}/voice/ws`;
|
||||
const token = localStorage.getItem("chattz_token");
|
||||
if (token) {
|
||||
urlStr += (urlStr.includes('?') ? '&' : '?') + `token=${token}`;
|
||||
}
|
||||
return urlStr;
|
||||
}
|
||||
|
||||
function shouldInitiateOffer(peerId) {
|
||||
|
|
@ -1159,9 +1206,14 @@ async function init() {
|
|||
try {
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
const jwtToken = searchParams.get("token");
|
||||
if (jwtToken) {
|
||||
localStorage.setItem("chattz_token", jwtToken);
|
||||
const refreshToken = searchParams.get("refresh_token");
|
||||
|
||||
if (jwtToken || refreshToken) {
|
||||
if (jwtToken) localStorage.setItem("chattz_token", jwtToken);
|
||||
if (refreshToken) localStorage.setItem("chattz_refresh_token", refreshToken);
|
||||
|
||||
searchParams.delete("token");
|
||||
searchParams.delete("refresh_token");
|
||||
const nextQuery = searchParams.toString();
|
||||
const nextUrl = `${location.pathname}${nextQuery ? `?${nextQuery}` : ""}`;
|
||||
history.replaceState(null, "", nextUrl);
|
||||
|
|
@ -1175,6 +1227,7 @@ async function init() {
|
|||
el.logoutBtn.onclick = async () => {
|
||||
await leaveVoice();
|
||||
localStorage.removeItem("chattz_token");
|
||||
localStorage.removeItem("chattz_refresh_token");
|
||||
try { await api("/auth/logout", { method: "POST" }); } catch (e) { }
|
||||
location.reload();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue