v.karbovnichy
v.karbovnichy
CCConvex Community
Created by v.karbovnichy on 3/16/2024 in #support-community
[Solved] Sending auth info breaks ws connection to Convex
I have next.js app and trying to connect it to NextAuth and Convex. Pretty much successful so far, current step: sending authorized user info to Convex to be used in queries/mutations. When I configure ConvexProviderWithAuth, and it sends JWT to the ws channel (wss://my-tenant.convex.cloud/api/1.10.0/sync), it gets a response: * {"type":"Authenticate","baseVersion":0,"tokenType":"User","value":{"name":"REDACTED","email":"REDACTED@gmail.com","picture":"https://avatars.githubusercontent.com/u/REDACTED?v=4","sub":"kh74hmtwhk1q4py9mwygh0r3fd6nbney","iat":1710630073,"exp":1713222073,"jti":"a7e096a9-0a84-4cd9-9dd6-e42db6cc011e"}} * {"type":"FatalError","error":"Received Invalid JSON on websocket: invalid type: map, expected a string"} As I understand, Convex did not accept the user info. I don't really know what should I change here, maybe send raw JWT directly? Here are the files:
export default function ConvexClientProvider({
children,
}: {
children: ReactNode;
}) {
return (
<ConvexProviderWithAuth client={convex} useAuth={useAuthFromNextAuth}>
{children}
</ConvexProviderWithAuth>
)
}
export default function ConvexClientProvider({
children,
}: {
children: ReactNode;
}) {
return (
<ConvexProviderWithAuth client={convex} useAuth={useAuthFromNextAuth}>
{children}
</ConvexProviderWithAuth>
)
}
export function useAuthFromNextAuth() {
const { data, status } = useSession();

const fetchAccessToken = useCallback(
async ({ forceRefreshToken }: { forceRefreshToken: boolean }) => {
if (forceRefreshToken) {
const response = await fetch("/api/openid/refresh");
return (await response.json()) as string;
} else {
const response = await fetch("/api/openid/token");
return (await response.json()) as string;
}
},
[]
);

return useMemo(
() => ({
isLoading: status === "loading",
isAuthenticated: !!data,
fetchAccessToken,
}),
[fetchAccessToken, data, status]
);
}
export function useAuthFromNextAuth() {
const { data, status } = useSession();

const fetchAccessToken = useCallback(
async ({ forceRefreshToken }: { forceRefreshToken: boolean }) => {
if (forceRefreshToken) {
const response = await fetch("/api/openid/refresh");
return (await response.json()) as string;
} else {
const response = await fetch("/api/openid/token");
return (await response.json()) as string;
}
},
[]
);

return useMemo(
() => ({
isLoading: status === "loading",
isAuthenticated: !!data,
fetchAccessToken,
}),
[fetchAccessToken, data, status]
);
}
4 replies