Newer
Older
smart-home-server / webclient / src / api / auth.js
const STORAGE_KEY = "shserv_access_token";
const STORAGE_KEY_EXPIRES = "shserv_expires_at";

let _accessToken = null;

/**
 * Set the current OAuth access token for Bearer authentication.
 * Persists to localStorage so the token survives page reloads.
 * @param {string|null} token
 * @param {number|null} expiresInSeconds — optional lifetime for proactive refresh
 */
export function setAccessToken(token, expiresInSeconds = null) {
  _accessToken = token || null;
  try {
    if (_accessToken) {
      localStorage.setItem(STORAGE_KEY, _accessToken);
      if (expiresInSeconds != null && expiresInSeconds > 0) {
        const expiresAt = Date.now() + expiresInSeconds * 1000;
        localStorage.setItem(STORAGE_KEY_EXPIRES, String(expiresAt));
      }
    } else {
      localStorage.removeItem(STORAGE_KEY);
      localStorage.removeItem(STORAGE_KEY_EXPIRES);
    }
  } catch {
    // localStorage may be unavailable (private mode, etc.)
  }
}

/**
 * Get the current access token.
 * Falls back to localStorage if the in-memory value was lost (e.g. page reload).
 * @returns {string|null}
 */
export function getAccessToken() {
  if (_accessToken) {
    return _accessToken;
  }
  try {
    return localStorage.getItem(STORAGE_KEY) || null;
  } catch {
    return null;
  }
}

/**
 * Get the stored token expiration timestamp (ms since epoch).
 * @returns {number|null}
 */
export function getExpiresAt() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY_EXPIRES);
    return raw ? Number(raw) : null;
  } catch {
    return null;
  }
}

/**
 * Clear the stored access token (memory + localStorage).
 */
export function clearAccessToken() {
  _accessToken = null;
  try {
    localStorage.removeItem(STORAGE_KEY);
    localStorage.removeItem(STORAGE_KEY_EXPIRES);
  } catch {
    // ignore
  }
}