mirror of
https://github.com/saltbo/zpan.git
synced 2026-09-01 05:44:38 +08:00
fix(api-keys): normalize legacy scope metadata
This commit is contained in:
@@ -622,7 +622,7 @@ func (c *Client) createMatter(
|
||||
onConflict := openapi.CreateObjectJSONBodyOnConflictRename
|
||||
res, err := c.api.CreateObjectWithResponse(ctx, openapi.CreateObjectJSONRequestBody{
|
||||
Name: name,
|
||||
Type: contentType,
|
||||
Type: &contentType,
|
||||
Size: &sizeInt,
|
||||
Parent: &parent,
|
||||
Dirtype: &dirtype,
|
||||
|
||||
@@ -3708,7 +3708,7 @@ type CreateObjectJSONBody struct {
|
||||
Parent *string `json:"parent,omitempty"`
|
||||
Size *int `json:"size,omitempty"`
|
||||
StorageId *string `json:"storageId,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// CreateObjectJSONBodyOnConflict defines parameters for CreateObject.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type ApiKeyScope, ApiKeyTemplate, apiKeyMetadata, parseApiKeyScope } from '@shared/api-key-templates'
|
||||
import { and, eq, inArray, isNull } from 'drizzle-orm'
|
||||
import { and, eq, inArray } from 'drizzle-orm'
|
||||
import { apikey, member } from '../../db/auth-schema'
|
||||
import type { Database } from '../../platform/interface'
|
||||
import { resolveOrganizationOwnerUserId } from './organization-owner'
|
||||
@@ -56,13 +56,22 @@ export async function normalizeLegacyApiKey(
|
||||
}
|
||||
|
||||
export async function normalizeLegacyApiKeysForUser(db: Database, userId: string): Promise<void> {
|
||||
await db
|
||||
.update(apikey)
|
||||
.set({
|
||||
metadata: JSON.stringify(apiKeyMetadata({ mode: 'user-workspaces' })),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(and(eq(apikey.configId, ApiKeyTemplate.WEBDAV), eq(apikey.referenceId, userId), isNull(apikey.metadata)))
|
||||
const webDavKeys = await db
|
||||
.select({ id: apikey.id, metadata: apikey.metadata })
|
||||
.from(apikey)
|
||||
.where(and(eq(apikey.configId, ApiKeyTemplate.WEBDAV), eq(apikey.referenceId, userId)))
|
||||
const legacyWebDavKeyIds = webDavKeys
|
||||
.filter(({ metadata }) => scopeForApiKey(ApiKeyTemplate.WEBDAV, parseMetadata(metadata)) === null)
|
||||
.map(({ id }) => id)
|
||||
if (legacyWebDavKeyIds.length > 0) {
|
||||
await db
|
||||
.update(apikey)
|
||||
.set({
|
||||
metadata: JSON.stringify(apiKeyMetadata({ mode: 'user-workspaces' })),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(inArray(apikey.id, legacyWebDavKeyIds))
|
||||
}
|
||||
|
||||
const ownedOrgs = await db
|
||||
.select({ orgId: member.organizationId })
|
||||
@@ -78,7 +87,7 @@ export async function normalizeLegacyApiKeysForUser(db: Database, userId: string
|
||||
metadata: JSON.stringify(apiKeyMetadata({ mode: 'workspace', orgId })),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(and(inArray(apikey.configId, WORKSPACE_TEMPLATES), eq(apikey.referenceId, orgId), isNull(apikey.metadata)))
|
||||
.where(and(inArray(apikey.configId, WORKSPACE_TEMPLATES), eq(apikey.referenceId, orgId)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,11 +166,16 @@ describe('API keys', () => {
|
||||
const { orgId, userId } = await getUserAndOrg(db)
|
||||
const remoteDownload = await createOrgApiKey(auth, 'remote-download', orgId, userId)
|
||||
const ihost = await createOrgApiKey(auth, 'ihost', orgId, userId)
|
||||
// biome-ignore lint/suspicious/noExplicitAny: better-auth plugin API is not fully typed
|
||||
const webdav = (await (auth.api as any).createApiKey({
|
||||
body: { configId: 'webdav', userId },
|
||||
})) as { id: string }
|
||||
await db.run(sql`
|
||||
UPDATE apikey
|
||||
SET reference_id = ${orgId}, metadata = NULL
|
||||
SET reference_id = ${orgId}, metadata = '{}'
|
||||
WHERE id IN (${remoteDownload.id}, ${ihost.id})
|
||||
`)
|
||||
await db.run(sql`UPDATE apikey SET metadata = '{}' WHERE id = ${webdav.id}`)
|
||||
|
||||
await expect(apiKeys.verifyApiKey(auth, db, remoteDownload.key, 'remote-download')).resolves.toMatchObject({
|
||||
referenceId: userId,
|
||||
@@ -182,8 +187,21 @@ describe('API keys', () => {
|
||||
|
||||
const listResponse = await app.request('/api/auth/api-key/list', { headers })
|
||||
expect(listResponse.status).toBe(200)
|
||||
const listed = (await listResponse.json()) as { apiKeys: Array<{ id: string }> }
|
||||
expect(listed.apiKeys.map((key) => key.id)).toEqual(expect.arrayContaining([remoteDownload.id, ihost.id]))
|
||||
const listed = (await listResponse.json()) as {
|
||||
apiKeys: Array<{ id: string; metadata: { scope: { mode: string; orgId?: string } } }>
|
||||
}
|
||||
expect(listed.apiKeys).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: ihost.id,
|
||||
metadata: { scope: { mode: 'workspace', orgId } },
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: webdav.id,
|
||||
metadata: { scope: { mode: 'user-workspaces' } },
|
||||
}),
|
||||
]),
|
||||
)
|
||||
expect(await getApiKeyRow(db, ihost.id)).toMatchObject({ reference_id: userId })
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user