Skip to content

Commit

Permalink
✨ Auto refresh token if tab was active (#252)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlueSky-07 authored Dec 2, 2023
1 parent 6ca14a8 commit 42ae5bf
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
14 changes: 14 additions & 0 deletions web/src/components/Menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { Link, useSearchParams, useNavigate } from 'react-router-dom';
import Regex from "../../utils/regex";
import Toast from "../../components/Notification";
import { INamespaceItem, INamespaceList, IHTTPError, IUserSelf, IEndpoint, IVersion } from "../../interfaces";
import { setupAutoRefreshToken, teardownAutoRefreshToken } from "../../utils/refreshToken"

export default function ({ localServer, item, namespace, repository, tag, selfClick }: { localServer: string, item: string, namespace?: string, repository?: string, tag?: string, selfClick?: boolean }) {
const [showProfileMenu, setShowProfileMenu] = useState(false);
Expand Down Expand Up @@ -62,6 +63,19 @@ export default function ({ localServer, item, namespace, repository, tag, selfCl
const errorcode = error.response.data as IHTTPError;
Toast({ level: "warning", title: errorcode.title, message: errorcode.description });
});
setupAutoRefreshToken(localServer, logout);
const visibilitychangeHandler = () => {
if (document.hidden) {
teardownAutoRefreshToken();
} else {
setupAutoRefreshToken(localServer, logout);
}
}
document.addEventListener("visibilitychange", visibilitychangeHandler);

return () => {
document.removeEventListener("visibilitychange", visibilitychangeHandler);
}
}
}, [refresh])

Expand Down
63 changes: 63 additions & 0 deletions web/src/utils/refreshToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright 2023 sigma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import axios from "axios";

let REFRESH_TOKEN_INTERVAL: ReturnType<typeof setInterval> | null;

const REFRESH_TOKEN_INTERVAL_TIMEOUT = 1000; // 10 mins

import { IUserLoginResponse } from "../interfaces";


export function refreshToken(
localServer: string,
onFailed: () => void
) {
let headers: { [key: string]: any } = {
"Authorization": "Bearer " + localStorage.getItem('refresh_token'),
};
let url = localServer + `/api/v1/users/login`;
axios.post(url, {}, {
headers: headers,
})
.then(response => {
if (response?.status === 200) {
const resp = response.data as IUserLoginResponse;
localStorage.setItem("token", resp.token);
localStorage.setItem("refresh_token", resp.refresh_token);
} else {
onFailed()
}
}).catch(err => {
onFailed()
})
}

export function setupAutoRefreshToken(
localServer: string,
onFailed: () => void
) {
if (REFRESH_TOKEN_INTERVAL) return;
REFRESH_TOKEN_INTERVAL = REFRESH_TOKEN_INTERVAL = setInterval(() => {
refreshToken(localServer, onFailed);
}, REFRESH_TOKEN_INTERVAL_TIMEOUT);
}

export function teardownAutoRefreshToken() {
if (!REFRESH_TOKEN_INTERVAL) return;
clearInterval(REFRESH_TOKEN_INTERVAL);
REFRESH_TOKEN_INTERVAL = null;
}

0 comments on commit 42ae5bf

Please sign in to comment.