Spaces:
Running
Running
test cookie
Browse files- app/api/auth/route.ts +1 -3
- hooks/useUser.ts +0 -35
- lib/iframe-storage.ts +0 -90
app/api/auth/route.ts
CHANGED
|
@@ -80,8 +80,6 @@ export async function POST(req: NextRequest) {
|
|
| 80 |
access_token: response.access_token,
|
| 81 |
expires_in: response.expires_in,
|
| 82 |
user,
|
| 83 |
-
// Include fallback flag for iframe contexts
|
| 84 |
-
useLocalStorageFallback: true,
|
| 85 |
},
|
| 86 |
{
|
| 87 |
status: 200,
|
|
@@ -91,7 +89,7 @@ export async function POST(req: NextRequest) {
|
|
| 91 |
}
|
| 92 |
);
|
| 93 |
|
| 94 |
-
// Set HTTP-only cookie
|
| 95 |
const cookieOptions = [
|
| 96 |
`${cookieName}=${response.access_token}`,
|
| 97 |
`Max-Age=${response.expires_in || 3600}`, // Default 1 hour if not provided
|
|
|
|
| 80 |
access_token: response.access_token,
|
| 81 |
expires_in: response.expires_in,
|
| 82 |
user,
|
|
|
|
|
|
|
| 83 |
},
|
| 84 |
{
|
| 85 |
status: 200,
|
|
|
|
| 89 |
}
|
| 90 |
);
|
| 91 |
|
| 92 |
+
// Set HTTP-only cookie
|
| 93 |
const cookieOptions = [
|
| 94 |
`${cookieName}=${response.access_token}`,
|
| 95 |
`Max-Age=${response.expires_in || 3600}`, // Default 1 hour if not provided
|
hooks/useUser.ts
CHANGED
|
@@ -7,13 +7,6 @@ import { useRouter } from "next/navigation";
|
|
| 7 |
import { ProjectType, User } from "@/types";
|
| 8 |
import { api } from "@/lib/api";
|
| 9 |
import { toast } from "sonner";
|
| 10 |
-
import {
|
| 11 |
-
storeAuthDataFallback,
|
| 12 |
-
getAuthDataFallback,
|
| 13 |
-
clearAuthDataFallback,
|
| 14 |
-
isInIframe,
|
| 15 |
-
isMobileDevice
|
| 16 |
-
} from "@/lib/iframe-storage";
|
| 17 |
|
| 18 |
|
| 19 |
export const useUser = (initialData?: {
|
|
@@ -29,13 +22,6 @@ export const useUser = (initialData?: {
|
|
| 29 |
useQuery({
|
| 30 |
queryKey: ["user.me"],
|
| 31 |
queryFn: async () => {
|
| 32 |
-
// Check for fallback data if no initial data provided and we're in iframe
|
| 33 |
-
if (!initialData && isInIframe()) {
|
| 34 |
-
const fallbackData = getAuthDataFallback();
|
| 35 |
-
if (fallbackData.user && fallbackData.token) {
|
| 36 |
-
return { user: fallbackData.user, errCode: null };
|
| 37 |
-
}
|
| 38 |
-
}
|
| 39 |
return { user: initialData?.user || null, errCode: initialData?.errCode || null };
|
| 40 |
},
|
| 41 |
refetchOnWindowFocus: false,
|
|
@@ -73,21 +59,6 @@ export const useUser = (initialData?: {
|
|
| 73 |
|
| 74 |
const openLoginWindow = async () => {
|
| 75 |
setCurrentRoute(window.location.pathname);
|
| 76 |
-
|
| 77 |
-
if (isInIframe()) {
|
| 78 |
-
try {
|
| 79 |
-
const response = await api.get("/auth/login-url");
|
| 80 |
-
const { loginUrl } = response.data;
|
| 81 |
-
|
| 82 |
-
window.open(loginUrl, "_blank", "noopener,noreferrer");
|
| 83 |
-
|
| 84 |
-
toast.info("Login opened in new tab. Please complete authentication and return to this page.");
|
| 85 |
-
return;
|
| 86 |
-
} catch (error) {
|
| 87 |
-
console.error("Failed to open login in new tab:", error);
|
| 88 |
-
}
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
return router.push("/auth");
|
| 92 |
};
|
| 93 |
|
|
@@ -98,10 +69,6 @@ export const useUser = (initialData?: {
|
|
| 98 |
.post("/auth", { code })
|
| 99 |
.then(async (res: any) => {
|
| 100 |
if (res.data) {
|
| 101 |
-
if (res.data.useLocalStorageFallback) {
|
| 102 |
-
storeAuthDataFallback(res.data.access_token, res.data.user);
|
| 103 |
-
}
|
| 104 |
-
|
| 105 |
client.setQueryData(["user.me"], {
|
| 106 |
user: res.data.user,
|
| 107 |
errCode: null,
|
|
@@ -126,14 +93,12 @@ export const useUser = (initialData?: {
|
|
| 126 |
const logout = async () => {
|
| 127 |
try {
|
| 128 |
await api.post("/auth/logout");
|
| 129 |
-
clearAuthDataFallback();
|
| 130 |
removeCurrentRoute();
|
| 131 |
client.clear();
|
| 132 |
toast.success("Logout successful");
|
| 133 |
window.location.reload();
|
| 134 |
} catch (error) {
|
| 135 |
console.error("Logout error:", error);
|
| 136 |
-
clearAuthDataFallback();
|
| 137 |
removeCurrentRoute();
|
| 138 |
client.clear()
|
| 139 |
toast.success("Logout successful");
|
|
|
|
| 7 |
import { ProjectType, User } from "@/types";
|
| 8 |
import { api } from "@/lib/api";
|
| 9 |
import { toast } from "sonner";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
|
| 12 |
export const useUser = (initialData?: {
|
|
|
|
| 22 |
useQuery({
|
| 23 |
queryKey: ["user.me"],
|
| 24 |
queryFn: async () => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
return { user: initialData?.user || null, errCode: initialData?.errCode || null };
|
| 26 |
},
|
| 27 |
refetchOnWindowFocus: false,
|
|
|
|
| 59 |
|
| 60 |
const openLoginWindow = async () => {
|
| 61 |
setCurrentRoute(window.location.pathname);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
return router.push("/auth");
|
| 63 |
};
|
| 64 |
|
|
|
|
| 69 |
.post("/auth", { code })
|
| 70 |
.then(async (res: any) => {
|
| 71 |
if (res.data) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
client.setQueryData(["user.me"], {
|
| 73 |
user: res.data.user,
|
| 74 |
errCode: null,
|
|
|
|
| 93 |
const logout = async () => {
|
| 94 |
try {
|
| 95 |
await api.post("/auth/logout");
|
|
|
|
| 96 |
removeCurrentRoute();
|
| 97 |
client.clear();
|
| 98 |
toast.success("Logout successful");
|
| 99 |
window.location.reload();
|
| 100 |
} catch (error) {
|
| 101 |
console.error("Logout error:", error);
|
|
|
|
| 102 |
removeCurrentRoute();
|
| 103 |
client.clear()
|
| 104 |
toast.success("Logout successful");
|
lib/iframe-storage.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
| 1 |
-
/**
|
| 2 |
-
* Utility for handling storage in iframe contexts
|
| 3 |
-
* Falls back to localStorage when cookies are blocked
|
| 4 |
-
*/
|
| 5 |
-
|
| 6 |
-
export const isInIframe = (): boolean => {
|
| 7 |
-
try {
|
| 8 |
-
return window.self !== window.top;
|
| 9 |
-
} catch {
|
| 10 |
-
return true; // If we can't access window.top, we're likely in an iframe
|
| 11 |
-
}
|
| 12 |
-
};
|
| 13 |
-
|
| 14 |
-
export const isMobileDevice = (): boolean => {
|
| 15 |
-
if (typeof window === 'undefined') return false;
|
| 16 |
-
|
| 17 |
-
// Check user agent for mobile patterns
|
| 18 |
-
const userAgent = window.navigator.userAgent;
|
| 19 |
-
const mobilePattern = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;
|
| 20 |
-
|
| 21 |
-
// Also check for touch capability and screen size
|
| 22 |
-
const hasTouchScreen = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
| 23 |
-
const hasSmallScreen = window.innerWidth <= 768; // Common mobile breakpoint
|
| 24 |
-
|
| 25 |
-
return mobilePattern.test(userAgent) || (hasTouchScreen && hasSmallScreen);
|
| 26 |
-
};
|
| 27 |
-
|
| 28 |
-
export const STORAGE_KEYS = {
|
| 29 |
-
ACCESS_TOKEN: "deepsite-auth-token-fallback",
|
| 30 |
-
USER_DATA: "deepsite-user-data-fallback",
|
| 31 |
-
} as const;
|
| 32 |
-
|
| 33 |
-
export const iframeStorage = {
|
| 34 |
-
setItem: (key: string, value: string): void => {
|
| 35 |
-
try {
|
| 36 |
-
localStorage.setItem(key, value);
|
| 37 |
-
} catch (error) {
|
| 38 |
-
console.warn("Failed to set localStorage item:", error);
|
| 39 |
-
}
|
| 40 |
-
},
|
| 41 |
-
|
| 42 |
-
getItem: (key: string): string | null => {
|
| 43 |
-
try {
|
| 44 |
-
return localStorage.getItem(key);
|
| 45 |
-
} catch (error) {
|
| 46 |
-
console.warn("Failed to get localStorage item:", error);
|
| 47 |
-
return null;
|
| 48 |
-
}
|
| 49 |
-
},
|
| 50 |
-
|
| 51 |
-
removeItem: (key: string): void => {
|
| 52 |
-
try {
|
| 53 |
-
localStorage.removeItem(key);
|
| 54 |
-
} catch (error) {
|
| 55 |
-
console.warn("Failed to remove localStorage item:", error);
|
| 56 |
-
}
|
| 57 |
-
},
|
| 58 |
-
|
| 59 |
-
clear: (): void => {
|
| 60 |
-
try {
|
| 61 |
-
localStorage.removeItem(STORAGE_KEYS.ACCESS_TOKEN);
|
| 62 |
-
localStorage.removeItem(STORAGE_KEYS.USER_DATA);
|
| 63 |
-
} catch (error) {
|
| 64 |
-
console.warn("Failed to clear localStorage items:", error);
|
| 65 |
-
}
|
| 66 |
-
},
|
| 67 |
-
};
|
| 68 |
-
|
| 69 |
-
export const storeAuthDataFallback = (accessToken: string, userData: any): void => {
|
| 70 |
-
if (isInIframe()) {
|
| 71 |
-
iframeStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, accessToken);
|
| 72 |
-
iframeStorage.setItem(STORAGE_KEYS.USER_DATA, JSON.stringify(userData));
|
| 73 |
-
}
|
| 74 |
-
};
|
| 75 |
-
|
| 76 |
-
export const getAuthDataFallback = (): { token: string | null; user: any | null } => {
|
| 77 |
-
if (isInIframe()) {
|
| 78 |
-
const token = iframeStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN);
|
| 79 |
-
const userDataStr = iframeStorage.getItem(STORAGE_KEYS.USER_DATA);
|
| 80 |
-
const user = userDataStr ? JSON.parse(userDataStr) : null;
|
| 81 |
-
return { token, user };
|
| 82 |
-
}
|
| 83 |
-
return { token: null, user: null };
|
| 84 |
-
};
|
| 85 |
-
|
| 86 |
-
export const clearAuthDataFallback = (): void => {
|
| 87 |
-
if (isInIframe()) {
|
| 88 |
-
iframeStorage.clear();
|
| 89 |
-
}
|
| 90 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|