token usage tightened with revocation
This commit is contained in:
+54
-9
@@ -10,6 +10,7 @@ const otpInput = document.getElementById('otp');
|
||||
const session = document.getElementById('logged-in');
|
||||
const sessionSummary = document.getElementById('session-summary');
|
||||
const signOutButton = document.getElementById('sign-out');
|
||||
const sessionStore = browser.storage.session;
|
||||
|
||||
const t = window.linklogI18n;
|
||||
|
||||
@@ -49,15 +50,18 @@ function setStatus(message, isError = false) {
|
||||
}
|
||||
|
||||
async function loadSettings() {
|
||||
const settings = await browser.storage.local.get(['backendUrl', 'email', 'username', 'accessToken']);
|
||||
const [settings, sessionSettings] = await Promise.all([
|
||||
browser.storage.local.get(['backendUrl', 'email', 'username']),
|
||||
sessionStore.get(['accessToken', 'refreshToken', 'tokenExpiresAt', 'deviceId']),
|
||||
]);
|
||||
backendUrlInput.value = settings.backendUrl || '';
|
||||
emailInput.value = settings.email || '';
|
||||
|
||||
if (settings.accessToken && settings.backendUrl && await hasBackendPermission(settings.backendUrl)) {
|
||||
if (sessionSettings.accessToken && settings.backendUrl && await hasBackendPermission(settings.backendUrl)) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${settings.backendUrl}/api/auth/me`,
|
||||
{headers: {Authorization: `Bearer ${settings.accessToken}`}},
|
||||
{headers: {Authorization: `Bearer ${sessionSettings.accessToken}`}},
|
||||
);
|
||||
if (response.ok) {
|
||||
const user = await response.json();
|
||||
@@ -84,7 +88,32 @@ function showLoggedOut() {
|
||||
}
|
||||
|
||||
async function clearSession() {
|
||||
await browser.storage.local.remove(['accessToken', 'tokenType', 'tokenExpiresAt', 'refreshToken']);
|
||||
await Promise.all([
|
||||
sessionStore.remove(['accessToken', 'refreshToken', 'tokenExpiresAt', 'deviceId']),
|
||||
browser.storage.local.remove(['accessToken', 'tokenType', 'tokenExpiresAt', 'refreshToken', 'deviceId']),
|
||||
]);
|
||||
}
|
||||
|
||||
async function refreshAccessToken(settings) {
|
||||
if (!settings.backendUrl || !settings.refreshToken || !settings.deviceId) return null;
|
||||
try {
|
||||
const response = await fetch(`${settings.backendUrl}/api/auth/refresh`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({refresh_token: settings.refreshToken, device_id: settings.deviceId}),
|
||||
});
|
||||
if (!response.ok) {
|
||||
await clearSession();
|
||||
return null;
|
||||
}
|
||||
const data = await response.json();
|
||||
const refreshed = {accessToken: data.access_token, refreshToken: data.refresh_token,
|
||||
tokenExpiresAt: data.expires_at, deviceId: data.device_id || settings.deviceId};
|
||||
await sessionStore.set(refreshed);
|
||||
return refreshed;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveSettingsAndLogin(event) {
|
||||
@@ -116,14 +145,29 @@ async function saveSettingsAndLogin(event) {
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
if (response.status === 401) {
|
||||
const refreshed = await refreshAccessToken({...settings, ...sessionSettings});
|
||||
if (refreshed) {
|
||||
const retry = await fetch(`${settings.backendUrl}/api/auth/me`, {
|
||||
headers: {Authorization: `Bearer ${refreshed.accessToken}`},
|
||||
});
|
||||
if (retry.ok) {
|
||||
const user = await retry.json();
|
||||
showLoggedIn(user.username || settings.email, settings.backendUrl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
await browser.storage.local.set({
|
||||
backendUrl,
|
||||
email,
|
||||
username: data.user?.username || email,
|
||||
});
|
||||
await sessionStore.set({
|
||||
accessToken: data.access_token,
|
||||
tokenType: data.token_type,
|
||||
tokenExpiresAt: data.expires_at,
|
||||
refreshToken: data.refresh_token,
|
||||
tokenExpiresAt: data.expires_at,
|
||||
deviceId: data.device_id || `device-${crypto.randomUUID()}`,
|
||||
});
|
||||
|
||||
showLoggedIn(data.user?.username || email, backendUrl);
|
||||
@@ -136,13 +180,14 @@ async function saveSettingsAndLogin(event) {
|
||||
}
|
||||
|
||||
async function signOut() {
|
||||
const settings = await browser.storage.local.get(['accessToken']);
|
||||
const settings = await browser.storage.local.get(['backendUrl']);
|
||||
const sessionSettings = await sessionStore.get(['accessToken']);
|
||||
const backendUrl = normalizeBackendOrigin(backendUrlInput.value.trim());
|
||||
if (settings.accessToken && await hasBackendPermission(backendUrl)) {
|
||||
if (sessionSettings.accessToken && settings.backendUrl && await hasBackendPermission(backendUrl)) {
|
||||
await fetch(`${backendUrl}/api/auth/logout`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ token: settings.accessToken }),
|
||||
body: JSON.stringify({ token: sessionSettings.accessToken }),
|
||||
}).catch(() => undefined);
|
||||
}
|
||||
await clearSession();
|
||||
|
||||
Reference in New Issue
Block a user