diff --git a/src/bookmark.tsx b/src/bookmark.tsx index 79e9350..2bc1564 100644 --- a/src/bookmark.tsx +++ b/src/bookmark.tsx @@ -3,7 +3,7 @@ import { Action, ActionPanel, List, Toast, showToast, Cache } from "@raycast/api import { Status, AkkomaError } from "./utils/types"; import apiServer from "./utils/api"; -import { authorize } from "./utils/oauth"; +import { getAccessToken } from "./utils/oauth"; import { statusParser } from "./utils/util"; const cache = new Cache(); @@ -16,7 +16,7 @@ export default function BookmarkCommand() { useEffect(() => { const getBookmark = async () => { try { - await authorize(); + await getAccessToken(); showToast(Toast.Style.Animated, "Loading bookmarks..☆ミ(o*・ω・)ノ."); const newBookmarks = await apiServer.fetchBookmarks(); setBookmarks(newBookmarks); diff --git a/src/my-status.tsx b/src/my-status.tsx index df6ef3d..e28941f 100644 --- a/src/my-status.tsx +++ b/src/my-status.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import { Action, ActionPanel, List, Toast, showToast, Cache } from "@raycast/api"; import { Status, AkkomaError } from "./utils/types"; -import { authorize } from "./utils/oauth"; +import { getAccessToken } from "./utils/oauth"; import apiServer from "./utils/api"; import { statusParser } from "./utils/util"; @@ -16,7 +16,7 @@ export default function ViewStatusCommand() { useEffect(() => { const getBookmark = async () => { try { - await authorize(); + await getAccessToken(); showToast(Toast.Style.Animated, "Loading Status...ε=ε=┌( >_<)┘"); const status = await apiServer.fetchUserStatus(); setStatus(status); diff --git a/src/simple-status.tsx b/src/simple-status.tsx index 69f9233..2373e84 100644 --- a/src/simple-status.tsx +++ b/src/simple-status.tsx @@ -14,7 +14,7 @@ import { } from "@raycast/api"; import apiServer from "./utils/api"; import { AkkomaError, StatusResponse, Preference, StatusRequest } from "./utils/types"; -import { authorize } from "./utils/oauth"; +import { getAccessToken } from "./utils/oauth"; import { dateTimeFormatter } from "./utils/util"; import VisibilityDropdown from "./components/VisibilityDropdown"; @@ -51,11 +51,11 @@ export default function SimpleCommand(props: CommandProps) { useEffect(() => { const init = async () => { try { - await authorize(); - const newFqn = (await LocalStorage.getItem("account-fqn")) ?? ""; + await getAccessToken(); + const fqn = await LocalStorage.getItem("account-fqn") || ""; setState((prevState) => ({ ...prevState, - fqn: newFqn, + fqn: fqn, })); } catch (error) { console.error("Error during authorization or fetching account-fqn:", error); diff --git a/src/utils/oauth.ts b/src/utils/oauth.ts index efbe10d..717b88d 100644 --- a/src/utils/oauth.ts +++ b/src/utils/oauth.ts @@ -44,7 +44,7 @@ const refreshToken = async ( return tokenResponse; }; -export const authorize = async (): Promise => { +export const authorize = async (): Promise => { const { instance } = getPreferenceValues(); const tokenSet = await client.getTokens(); @@ -53,7 +53,8 @@ export const authorize = async (): Promise => { const { client_id, client_secret } = await apiServer.createApp(); await client.setTokens(await refreshToken(client_id, client_secret, tokenSet.refreshToken)); } - return; + const { fqn } = await apiServer.fetchAccountInfo(); + return fqn; } const { client_id, client_secret } = await apiServer.createApp(); @@ -68,4 +69,43 @@ export const authorize = async (): Promise => { const { fqn } = await apiServer.fetchAccountInfo(); await LocalStorage.setItem("account-fqn", fqn); + return fqn; }; + +async function getValidTokens(): Promise { + const tokenSet = await client.getTokens(); + + if (!tokenSet || !tokenSet.accessToken) { + const fqn = await authorize(); + const updatedTokenSet = await client.getTokens(); + if (updatedTokenSet && updatedTokenSet.accessToken) { + await LocalStorage.setItem("account-fqn", fqn); + return updatedTokenSet; + } else { + throw new Error("Failed to get valid access token"); + } + } + + if (tokenSet.refreshToken && tokenSet.isExpired()) { + const { client_id, client_secret } = await apiServer.createApp(); + const refreshedTokens = await refreshToken(client_id, client_secret, tokenSet.refreshToken); + await client.setTokens(refreshedTokens); + const updatedTokenSet = await client.getTokens(); + if (updatedTokenSet && updatedTokenSet.accessToken) { + return updatedTokenSet; + } else { + throw new Error("Failed to refresh access token"); + } + } + + return tokenSet; +} + +export async function getAccessToken(): Promise { + const validTokenSet = await getValidTokens(); + if (validTokenSet && validTokenSet.accessToken) { + return validTokenSet.accessToken; + } else { + throw new Error("Failed to get valid access token"); + } +} \ No newline at end of file