Skip to content

Instantly share code, notes, and snippets.

@SirojbekMaqsudov
Last active April 6, 2024 21:49
Show Gist options
  • Select an option

  • Save SirojbekMaqsudov/0c6a1e690e9e52c5fd54376bd5ced235 to your computer and use it in GitHub Desktop.

Select an option

Save SirojbekMaqsudov/0c6a1e690e9e52c5fd54376bd5ced235 to your computer and use it in GitHub Desktop.

Revisions

  1. SirojbekMaqsudov revised this gist Apr 6, 2024. No changes.
  2. SirojbekMaqsudov revised this gist Apr 6, 2024. No changes.
  3. SirojbekMaqsudov created this gist Apr 6, 2024.
    111 changes: 111 additions & 0 deletions api.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,111 @@
    import axios from "axios";
    import {getCsrfToken, getSession, signOut} from "next-auth/react";

    const refreshToken = async (token) => {
    const response = await fetch(`${process.env.API_URL}/auth/refresh`, {
    method: 'POST',
    headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
    }
    });

    const res = await response.json();
    if (res.code && res.code === 401) {
    await signOut()
    return;
    }

    await updateSession(res.data)

    const reloadSession = () => {
    const event = new Event("visibilitychange");
    document.dispatchEvent(event);
    };
    if (document) reloadSession()

    return res.data;
    };

    const updateSession = async (data) => {
    const session = await getSession();
    const csrfToken = await getCsrfToken();

    const updatedSessionData = { ...session, ...data};

    await fetch(`${process.env.NEXTAUTH_URL}/api/auth/session`, {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    },
    body: JSON.stringify({
    csrfToken: csrfToken,
    data: {
    ...updatedSessionData
    }
    })
    });
    };

    let isRefreshing = false;
    let refreshAndRetryQueue = []

    const Api = () => {
    const instance = axios.create({
    baseURL: process.env.API_URL
    })

    instance.interceptors.request.use(async (request) => {
    const session = await getSession();
    if (session && session.user) {
    request.headers.Authorization = `Bearer ${session.token}`;
    }

    return request;

    });

    instance.interceptors.response.use(
    (response) => response,
    async (error) => {
    const originalRequest = error.config;
    const session = await getSession();

    if (error?.response?.status === 401 && session && session.user) {
    if (!isRefreshing) {
    isRefreshing = true

    try {
    const data = await refreshToken(session.refresh_token);
    originalRequest.headers.Authorization = `Bearer ${data.token}`;

    refreshAndRetryQueue.forEach(({ config, resolve, reject }) => {
    instance.request(config)
    .then(response => resolve(response))
    .catch(err => reject(err))
    })

    refreshAndRetryQueue.length = 0

    return axios(originalRequest);
    }catch (e) {
    console.log(e)
    }finally {
    isRefreshing = false
    }
    }

    return new Promise((resolve, reject) => {
    refreshAndRetryQueue.push({config: originalRequest, resolve, reject})
    })
    }

    return Promise.reject(error);
    }
    );

    return instance
    }


    export default Api()