Compare commits

...

2 Commits

Author SHA1 Message Date
dante01yoon
1174aff0ae fix: make workspace_id optional for profile creation
The workspace ID is only available when teamWorkspacesEnabled is true
and the backend has provisioned workspaces for the user. For users
without workspace context, send the profile creation request without
workspace_id and let the backend resolve it from the auth token.
2026-04-10 06:56:07 +09:00
dante01yoon
a5e323cdaa fix: read workspace ID from store instead of sessionStorage
The createProfile flow read workspace ID directly from sessionStorage,
which is only populated when the teamWorkspaces feature flag is enabled.
For users without the flag, sessionStorage never contains the workspace
entry, causing "Unable to determine current workspace" errors.

Read from workspaceAuthStore.currentWorkspace instead, which is the
canonical source of workspace state.

Fixes the creator profile creation error reported by multiple users.
2026-04-10 06:36:03 +09:00
3 changed files with 45 additions and 44 deletions

View File

@@ -10,6 +10,14 @@ const mockToastErrorHandler = vi.hoisted(() => vi.fn())
const mockResolvedUserInfo = vi.hoisted(() => ({
value: { id: 'user-a' }
}))
const mockCurrentWorkspace = vi.hoisted(() => ({
value: {
id: 'workspace-1',
type: 'team',
name: 'Test Workspace',
role: 'owner'
} as { id: string; type: string; name: string; role: string } | null
}))
vi.mock('@/platform/workflow/sharing/services/comfyHubService', () => ({
useComfyHubService: () => ({
@@ -32,6 +40,14 @@ vi.mock('@/composables/useErrorHandling', () => ({
})
}))
vi.mock('@/platform/workspace/stores/workspaceAuthStore', () => ({
useWorkspaceAuthStore: () => ({
get currentWorkspace() {
return mockCurrentWorkspace.value
}
})
}))
// Must import after vi.mock declarations
const { useComfyHubProfileGate } = await import('./useComfyHubProfileGate')
@@ -41,25 +57,18 @@ const mockProfile: ComfyHubProfile = {
description: 'A test profile'
}
function setCurrentWorkspace(workspaceId: string) {
sessionStorage.setItem(
'Comfy.Workspace.Current',
JSON.stringify({
id: workspaceId,
type: 'team',
name: 'Test Workspace',
role: 'owner'
})
)
}
describe('useComfyHubProfileGate', () => {
let gate: ReturnType<typeof useComfyHubProfileGate>
beforeEach(() => {
vi.clearAllMocks()
mockResolvedUserInfo.value = { id: 'user-a' }
setCurrentWorkspace('workspace-1')
mockCurrentWorkspace.value = {
id: 'workspace-1',
type: 'team',
name: 'Test Workspace',
role: 'owner'
}
mockGetMyProfile.mockResolvedValue(mockProfile)
mockRequestAssetUploadUrl.mockResolvedValue({
uploadUrl: 'https://upload.example.com/avatar.png',
@@ -193,5 +202,22 @@ describe('useComfyHubProfileGate', () => {
expect(requestCallOrder[0]).toBeLessThan(uploadCallOrder[0])
expect(uploadCallOrder[0]).toBeLessThan(createCallOrder[0])
})
it('creates profile without workspace_id when workspace is not available', async () => {
mockCurrentWorkspace.value = null
await gate.createProfile({
username: 'testuser',
name: 'Test User'
})
expect(mockCreateProfile).toHaveBeenCalledWith({
workspaceId: undefined,
username: 'testuser',
displayName: 'Test User',
description: undefined,
avatarToken: undefined
})
})
})
})

View File

@@ -3,7 +3,7 @@ import { ref } from 'vue'
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
import { useErrorHandling } from '@/composables/useErrorHandling'
import { useComfyHubService } from '@/platform/workflow/sharing/services/comfyHubService'
import { WORKSPACE_STORAGE_KEYS } from '@/platform/workspace/workspaceConstants'
import { useWorkspaceAuthStore } from '@/platform/workspace/stores/workspaceAuthStore'
import type { ComfyHubProfile } from '@/schemas/apiSchema'
// TODO: Migrate to a Pinia store for proper singleton state management
@@ -15,34 +15,6 @@ const profile = ref<ComfyHubProfile | null>(null)
const cachedUserId = ref<string | null>(null)
let inflightFetch: Promise<ComfyHubProfile | null> | null = null
function getCurrentWorkspaceId(): string {
const workspaceJson = sessionStorage.getItem(
WORKSPACE_STORAGE_KEYS.CURRENT_WORKSPACE
)
if (!workspaceJson) {
throw new Error('Unable to determine current workspace')
}
let workspace: unknown
try {
workspace = JSON.parse(workspaceJson)
} catch {
throw new Error('Unable to determine current workspace')
}
if (
!workspace ||
typeof workspace !== 'object' ||
!('id' in workspace) ||
typeof workspace.id !== 'string' ||
workspace.id.length === 0
) {
throw new Error('Unable to determine current workspace')
}
return workspace.id
}
export function useComfyHubProfileGate() {
const { resolvedUserInfo } = useCurrentUser()
const { toastErrorHandler } = useErrorHandling()
@@ -122,6 +94,9 @@ export function useComfyHubProfileGate() {
}): Promise<ComfyHubProfile> {
syncCachedProfileWithCurrentUser()
const workspaceAuthStore = useWorkspaceAuthStore()
const workspaceId = workspaceAuthStore.currentWorkspace?.id
let avatarToken: string | undefined
if (data.profilePicture) {
const contentType = data.profilePicture.type || 'application/octet-stream'
@@ -140,7 +115,7 @@ export function useComfyHubProfileGate() {
}
const createdProfile = await createComfyHubProfile({
workspaceId: getCurrentWorkspaceId(),
workspaceId,
username: data.username,
displayName: data.name,
description: data.description,

View File

@@ -12,7 +12,7 @@ type HubThumbnailType = 'image' | 'video' | 'image_comparison'
type ThumbnailTypeInput = HubThumbnailType | 'imageComparison'
interface CreateProfileInput {
workspaceId: string
workspaceId?: string
username: string
displayName?: string
description?: string