Skip to content

Commit

Permalink
fix: Broken authentication on dev (#215)
Browse files Browse the repository at this point in the history
* fix: Dev authentication

* fix: always truthy check
  • Loading branch information
Anush008 committed Jul 15, 2023
1 parent b9231ad commit c6bf2c8
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 165 deletions.
8 changes: 1 addition & 7 deletions src/App.tsx
@@ -1,25 +1,19 @@
import { useEffect } from "react";
import Start from "./popup/pages/start";
import Home from "./popup/pages/home";
import Loading from "./popup/pages/loading";
import { useAuth } from "./hooks/useAuth";
import { goTo } from "react-chrome-extension-router";

const App = () => {
const { isTokenValid } = useAuth();


useEffect(() => {
if (isTokenValid) {
goTo(Home);
} else {
goTo(Start);
}
}, [isTokenValid]);

return (
<Loading />
);
return <Start />;
};

export default App;
2 changes: 1 addition & 1 deletion src/constants.ts
Expand Up @@ -4,7 +4,7 @@ export const OPEN_SAUCED_API_ENDPOINT = import.meta.env.VITE_OPEN_SAUCED_API_END
export const SUPABASE_LOGIN_URL = `https://${import.meta.env.VITE_OPEN_SAUCED_SUPABASE_ID}.supabase.co/auth/v1/authorize?provider=github&redirect_to=https://${OPEN_SAUCED_INSIGHTS_DOMAIN}/`;


export const SUPABASE_AUTH_COOKIE_NAME = "supabase-auth-token";
export const SUPABASE_AUTH_COOKIE_NAME = import.meta.env.PROD ? "supabase-auth-token" : `sb-${import.meta.env.VITE_OPEN_SAUCED_SUPABASE_ID}-auth-token`;
export const OPEN_SAUCED_AUTH_TOKEN_KEY = "os-access-token";
export const OPEN_SAUCED_OPTED_LOG_OUT_KEY = "opted-log-out";
export const AI_PR_DESCRIPTION_CONFIG_KEY = "ai-pr-description-config";
Expand Down
70 changes: 43 additions & 27 deletions src/hooks/useAuth.ts
@@ -1,49 +1,65 @@
import { useEffect, useState } from "react";
import { OPEN_SAUCED_AUTH_TOKEN_KEY, OPEN_SAUCED_SESSION_ENDPOINT } from "../constants";
import {
OPEN_SAUCED_INSIGHTS_DOMAIN,
OPEN_SAUCED_SESSION_ENDPOINT,
SUPABASE_AUTH_COOKIE_NAME,
} from "../constants";
import { cachedFetch } from "../utils/cache";

const removeTokenFromStorage = async () => new Promise(resolve => {
chrome.storage.sync.remove(OPEN_SAUCED_AUTH_TOKEN_KEY, () => {
resolve(true);
});
});
import {
hasOptedLogOut,
removeAuthTokenFromStorage,
} from "../utils/checkAuthentication";
import setAuthTokenInChromeStorage from "../utils/setAccessToken";

export const useAuth = () => {
const [authToken, setAuthToken] = useState<null | string>(null);
const [user, setUser] = useState<null | { id: string, user_name: string }>(null);
const [isTokenValid, setIsTokenValid] = useState<boolean|null>(null);
const [user, setUser] = useState<null | { id: string; user_name: string }>(
null,
);
const [isTokenValid, setIsTokenValid] = useState<boolean>(false);

useEffect(() => {
chrome.storage.sync.get([OPEN_SAUCED_AUTH_TOKEN_KEY], async result => {
if (result[OPEN_SAUCED_AUTH_TOKEN_KEY]) {
setAuthToken(result[OPEN_SAUCED_AUTH_TOKEN_KEY]);
const authenticate = async () => {
try {
if (await hasOptedLogOut()) {
return;
}
const cookie = await chrome.cookies.get({
name: SUPABASE_AUTH_COOKIE_NAME,
url: `https://${OPEN_SAUCED_INSIGHTS_DOMAIN}`,
});

if (!cookie) {
return removeAuthTokenFromStorage();
}
const token = JSON.parse(decodeURIComponent(cookie.value))[0];

const resp = await cachedFetch(OPEN_SAUCED_SESSION_ENDPOINT, {
const response = await cachedFetch(OPEN_SAUCED_SESSION_ENDPOINT, {
expireInSeconds: 2 * 60 * 60,
headers: {
Authorization: `Bearer ${result[OPEN_SAUCED_AUTH_TOKEN_KEY]}`,
Authorization: `Bearer ${token}`,
Accept: "application/json",
},
});

if (!resp?.ok) {
removeTokenFromStorage().then(() => {
setAuthToken(null);
setUser(null);
setIsTokenValid(false);
return null;
})
.catch(console.error);
} else {
const json = await resp.json();
if (response?.ok) {
const json = await response.json();

setUser(json);
setIsTokenValid(true);
setAuthToken(token);
void setAuthTokenInChromeStorage(token);
} else {
await removeAuthTokenFromStorage();
}
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
}
} else {
setIsTokenValid(false);
}
});
};

void authenticate();
}, []);

return { authToken, user, isTokenValid };
Expand Down
8 changes: 3 additions & 5 deletions src/popup/pages/home.tsx
Expand Up @@ -54,7 +54,7 @@ const Home = () => {
const emojiResponse = await getEmojis();
const emojis = emojiResponse.data;

if (!emojis) {
if (!emojis.length) {
return;
}

Expand Down Expand Up @@ -167,14 +167,12 @@ const Home = () => {
.then(data => chrome.tabs.create(
{ url: "https://www.linkedin.com/in/me/edit/forms/project/new/", active: true },
tab => {
chrome.scripting
void chrome.scripting
.executeScript({
target: { tabId: tab.id! },
func: populateDataToLinkedIn,
args: [data],
})
.then(() => console.log("script injected"))
.catch(err => console.log(err));
});
},

))
Expand Down
46 changes: 2 additions & 44 deletions src/utils/checkAuthentication.ts
@@ -1,57 +1,15 @@
import {
OPEN_SAUCED_AUTH_TOKEN_KEY,
OPEN_SAUCED_OPTED_LOG_OUT_KEY,
SUPABASE_AUTH_COOKIE_NAME,
OPEN_SAUCED_INSIGHTS_DOMAIN,
SUPABASE_LOGIN_URL,
OPEN_SAUCED_OPTED_LOG_OUT_KEY, SUPABASE_LOGIN_URL,
} from "../constants";

export const checkAuthentication = async (
hasOptedLogOut: () => Promise<boolean>,
getCookie: (
details: chrome.cookies.Details,
callback: (cookie: chrome.cookies.Cookie | null) => void
) => void,
checkTokenValidity: (authCookie: any) => Promise<boolean>,
setAccessTokenInChromeStorage: (authCookie: any) => void,
removeAuthTokenFromStorage: () => void,
logError: (error: string) => void,
) => {
if (await hasOptedLogOut()) {
return removeAuthTokenFromStorage();
}

getCookie(
{
name: SUPABASE_AUTH_COOKIE_NAME,
url: `https://${OPEN_SAUCED_INSIGHTS_DOMAIN}`,
},
async cookie => {
if (!cookie) {
return removeAuthTokenFromStorage();
}
try {
const authCookie = JSON.parse(decodeURIComponent(cookie.value))[0];
const isValidToken = await checkTokenValidity(authCookie);

if (!isValidToken) {
return removeAuthTokenFromStorage();
}
setAccessTokenInChromeStorage(authCookie);
} catch (error) {
removeAuthTokenFromStorage();
logError(error as string);
}
},
);
};

export const isLoggedIn = async (): Promise<boolean> => Object.entries(await chrome.storage.sync.get(OPEN_SAUCED_AUTH_TOKEN_KEY)).length !== 0;

export const getAuthToken = async (): Promise<string> => (await chrome.storage.sync.get(OPEN_SAUCED_AUTH_TOKEN_KEY))[OPEN_SAUCED_AUTH_TOKEN_KEY];

export const optLogOut = () => {
void chrome.storage.sync.remove(OPEN_SAUCED_AUTH_TOKEN_KEY);
void removeAuthTokenFromStorage();
void chrome.storage.local.set({ [OPEN_SAUCED_OPTED_LOG_OUT_KEY]: true });
};

Expand Down
13 changes: 1 addition & 12 deletions src/utils/fetchOpenSaucedApiData.ts
@@ -1,8 +1,6 @@
import { cachedFetch } from "./cache";
import {
OPEN_SAUCED_USERS_ENDPOINT,
OPEN_SAUCED_SESSION_ENDPOINT,
OPEN_SAUCED_REPOS_ENDPOINT,
OPEN_SAUCED_USERS_ENDPOINT, OPEN_SAUCED_REPOS_ENDPOINT,
OPEN_SAUCED_USER_INSIGHTS_ENDPOINT,
OPEN_SAUCED_USER_HIGHLIGHTS_ENDPOINT,
OPEN_SAUCED_HIGHLIGHTS_LIST_ENDPOINT,
Expand All @@ -29,15 +27,6 @@ export const isOpenSaucedUser = async (username: string) => {
}
};

export const checkTokenValidity = async (token: string) => {
const response = await fetch(OPEN_SAUCED_SESSION_ENDPOINT, {
method: "GET",
headers: { Authorization: `Bearer ${token}` },
});

return response.status === 200;
};

export const getUserData = async (userName: string, forceRefresh: boolean = false) => cachedFetch(`${OPEN_SAUCED_USERS_ENDPOINT}/${userName}`, {
expireInSeconds: 2 * 60 * 60,
forceRefresh,
Expand Down
4 changes: 2 additions & 2 deletions src/utils/setAccessToken.ts
@@ -1,6 +1,6 @@
import { OPEN_SAUCED_AUTH_TOKEN_KEY } from "../constants";

const setAccessTokenInChromeStorage = async (accessToken: string): Promise<void> => new Promise((resolve, reject) => {
const setAuthTokenInChromeStorage = async (accessToken: string): Promise<void> => new Promise((resolve, reject) => {
chrome.storage.sync.set({ [OPEN_SAUCED_AUTH_TOKEN_KEY]: accessToken }, () => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
Expand All @@ -10,5 +10,5 @@ const setAccessTokenInChromeStorage = async (accessToken: string): Promise<void>
});
});

export default setAccessTokenInChromeStorage;
export default setAuthTokenInChromeStorage;

24 changes: 0 additions & 24 deletions src/worker/background.ts
@@ -1,27 +1,3 @@
import { checkAuthentication, hasOptedLogOut, removeAuthTokenFromStorage } from "../utils/checkAuthentication";
import { SUPABASE_AUTH_COOKIE_NAME, OPEN_SAUCED_INSIGHTS_DOMAIN } from "../constants";
import { setDefaultDescriptionConfig } from "../utils/ai-utils/descriptionconfig";
import { checkTokenValidity } from "../utils/fetchOpenSaucedApiData";
import setAccessTokenInChromeStorage from "../utils/setAccessToken";


const checkUserAuthentication = () => {
void checkAuthentication(hasOptedLogOut, chrome.cookies.get, checkTokenValidity, setAccessTokenInChromeStorage, removeAuthTokenFromStorage, console.error);
};

chrome.cookies.onChanged.addListener(changeInfo => {
if (
changeInfo.cookie.name === SUPABASE_AUTH_COOKIE_NAME ||
changeInfo.cookie.domain === OPEN_SAUCED_INSIGHTS_DOMAIN
) {
checkUserAuthentication();
}
});

chrome.runtime.onInstalled.addListener(() => {
checkUserAuthentication();
});
chrome.runtime.onInstalled.addListener(setDefaultDescriptionConfig);
chrome.runtime.onStartup.addListener(() => {
checkUserAuthentication();
});
43 changes: 0 additions & 43 deletions test/utils/checkAuthentication.test.ts

This file was deleted.

0 comments on commit c6bf2c8

Please sign in to comment.