Template
Fix avatar crash when users.image is an IdP URL
Authentik sign-ins write the picture claim URL to users.image, and both avatar components cast that value to a storage ID and passed it to files:getImageUrl, which failed argument validation and took the layout down after sign-in. getUser now returns imageUrl resolved from either a storage ID or a URL, and updateUser only deletes the previous avatar when it was an uploaded file. getImageUrl stays until the new Next image is live.
This commit is contained in:
1 parent
8f09a423d4
commit
55929d8c7f
3 files changed
+20
-15
No files matched your search
@@ -3,7 +3,7 @@
|
||||
import type { Preloaded } from 'convex/react';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { useRef, useState } from 'react';
|
||||
import { useMutation, usePreloadedQuery, useQuery } from 'convex/react';
|
||||
import { useMutation, usePreloadedQuery } from 'convex/react';
|
||||
import { Loader2, Pencil, Upload, XIcon } from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
@@ -48,11 +48,6 @@ export const AvatarUpload = ({ preloadedUser }: AvatarUploadProps) => {
|
||||
const generateUploadUrl = useMutation(api.files.generateUploadUrl);
|
||||
const updateUser = useMutation(api.auth.updateUser);
|
||||
|
||||
const currentImageUrl = useQuery(
|
||||
api.files.getImageUrl,
|
||||
user?.image ? { storageId: user.image as Id<'_storage'> } : 'skip',
|
||||
);
|
||||
|
||||
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const file = event.target.files?.[0] ?? null;
|
||||
if (!file) return;
|
||||
@@ -117,7 +112,7 @@ export const AvatarUpload = ({ preloadedUser }: AvatarUploadProps) => {
|
||||
onClick={() => inputRef.current?.click()}
|
||||
>
|
||||
<BasedAvatar
|
||||
src={currentImageUrl ?? undefined}
|
||||
src={user?.imageUrl}
|
||||
fullName={user?.name}
|
||||
className='h-42 w-42 text-6xl font-semibold'
|
||||
userIconProps={{ size: 100 }}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { resetAnalyticsIdentity, useAnalyticsIdentity } from '@/lib/analytics';
|
||||
import { useAuthActions } from '@convex-dev/auth/react';
|
||||
import { useConvexAuth, useQuery } from 'convex/react';
|
||||
|
||||
import type { Id } from '@gib/backend/convex/_generated/dataModel.js';
|
||||
import { api } from '@gib/backend/convex/_generated/api.js';
|
||||
import {
|
||||
BasedAvatar,
|
||||
@@ -25,10 +24,6 @@ export const AvatarDropdown = () => {
|
||||
const { signOut } = useAuthActions();
|
||||
const user = useQuery(api.auth.getUser, {});
|
||||
useAnalyticsIdentity(user?._id);
|
||||
const currentImageUrl = useQuery(
|
||||
api.files.getImageUrl,
|
||||
user?.image ? { storageId: user.image as Id<'_storage'> } : 'skip',
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -53,7 +48,7 @@ export const AvatarDropdown = () => {
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
<BasedAvatar
|
||||
src={currentImageUrl}
|
||||
src={user?.imageUrl}
|
||||
fullName={user?.name}
|
||||
className='h-9 w-9'
|
||||
fallbackProps={{ className: 'text-sm font-semibold' }}
|
||||
|
||||
Reference in new issue
Block a user