diff --git a/frontends/nextjs/src/app/api/packages/installed/[packageId]/handlers/patch-installed-package.ts b/frontends/nextjs/src/app/api/packages/installed/[packageId]/handlers/patch-installed-package.ts new file mode 100644 index 000000000..7be35e169 --- /dev/null +++ b/frontends/nextjs/src/app/api/packages/installed/[packageId]/handlers/patch-installed-package.ts @@ -0,0 +1,45 @@ +import { NextResponse } from 'next/server' +import type { NextRequest } from 'next/server' +import { readJson } from '@/lib/api/read-json' +import { getInstalledPackages } from '@/lib/db/packages/get-installed-packages' +import { togglePackageEnabled } from '@/lib/db/packages/toggle-package-enabled' +import type { InstalledPackage } from '@/lib/package-types' + +type UpdateInstalledPackagePayload = { + enabled?: boolean +} + +interface RouteParams { + params: { + packageId: string + } +} + +export async function PATCH(request: NextRequest, { params }: RouteParams) { + try { + const body = await readJson(request) + if (!body || typeof body.enabled !== 'boolean') { + return NextResponse.json({ error: 'Enabled flag is required' }, { status: 400 }) + } + + const installed = await getInstalledPackages() + const existing = installed.find((pkg) => pkg.packageId === params.packageId) + if (!existing) { + return NextResponse.json({ error: 'Package not installed' }, { status: 404 }) + } + + await togglePackageEnabled(params.packageId, body.enabled) + const updated: InstalledPackage = { ...existing, enabled: body.enabled } + + return NextResponse.json({ installed: updated }) + } catch (error) { + console.error('Error updating installed package:', error) + return NextResponse.json( + { + error: 'Failed to update installed package', + details: error instanceof Error ? error.message : 'Unknown error', + }, + { status: 500 } + ) + } +} diff --git a/frontends/nextjs/src/lib/db/auth/get-user-by-email.ts b/frontends/nextjs/src/lib/db/auth/get-user-by-email.ts index b6e2b9dcb..3f19c1b6e 100644 --- a/frontends/nextjs/src/lib/db/auth/get-user-by-email.ts +++ b/frontends/nextjs/src/lib/db/auth/get-user-by-email.ts @@ -1,5 +1,6 @@ import { getAdapter } from '../dbal-client' import type { User } from '../../types/level-types' +import { mapUserRecord } from '../users/map-user-record' /** * Get user by email from DBAL. @@ -22,17 +23,5 @@ export const getUserByEmail = async ( return null } - const userData = record as Record - - return { - id: String(userData.id), - username: String(userData.username), - email: String(userData.email), - role: userData.role as User['role'], - profilePicture: userData.profilePicture ? String(userData.profilePicture) : undefined, - bio: userData.bio ? String(userData.bio) : undefined, - createdAt: Number(userData.createdAt), - tenantId: userData.tenantId ? String(userData.tenantId) : undefined, - isInstanceOwner: Boolean(userData.isInstanceOwner), - } + return mapUserRecord(record as Record) } diff --git a/frontends/nextjs/src/lib/db/auth/get-user-by-username.ts b/frontends/nextjs/src/lib/db/auth/get-user-by-username.ts index 3f03e6c83..3b644fbbc 100644 --- a/frontends/nextjs/src/lib/db/auth/get-user-by-username.ts +++ b/frontends/nextjs/src/lib/db/auth/get-user-by-username.ts @@ -1,5 +1,6 @@ import { getAdapter } from '../dbal-client' import type { User } from '../../types/level-types' +import { mapUserRecord } from '../users/map-user-record' /** * Get user by username from DBAL. @@ -22,17 +23,5 @@ export const getUserByUsername = async ( return null } - const userData = record as Record - - return { - id: String(userData.id), - username: String(userData.username), - email: String(userData.email), - role: userData.role as User['role'], - profilePicture: userData.profilePicture ? String(userData.profilePicture) : undefined, - bio: userData.bio ? String(userData.bio) : undefined, - createdAt: Number(userData.createdAt), - tenantId: userData.tenantId ? String(userData.tenantId) : undefined, - isInstanceOwner: Boolean(userData.isInstanceOwner), - } + return mapUserRecord(record as Record) } diff --git a/frontends/nextjs/src/lib/db/users/get-user-by-id.ts b/frontends/nextjs/src/lib/db/users/get-user-by-id.ts index cc7284625..7c4022608 100644 --- a/frontends/nextjs/src/lib/db/users/get-user-by-id.ts +++ b/frontends/nextjs/src/lib/db/users/get-user-by-id.ts @@ -1,5 +1,6 @@ import { getAdapter } from '../dbal-client' import type { User } from '../../types/level-types' +import { mapUserRecord } from './map-user-record' /** * Get a user by ID from database @@ -15,16 +16,5 @@ export async function getUserById( if (!record) return null - const user = record as any - return { - id: user.id, - username: user.username, - email: user.email, - role: user.role as any, - profilePicture: user.profilePicture || undefined, - bio: user.bio || undefined, - createdAt: Number(user.createdAt), - tenantId: user.tenantId || undefined, - isInstanceOwner: user.isInstanceOwner, - } + return mapUserRecord(record as Record) } diff --git a/frontends/nextjs/src/lib/security/secure-db/operations/verify-credentials.ts b/frontends/nextjs/src/lib/security/secure-db/operations/verify-credentials.ts index 0c09eb717..6c5b0182a 100644 --- a/frontends/nextjs/src/lib/security/secure-db/operations/verify-credentials.ts +++ b/frontends/nextjs/src/lib/security/secure-db/operations/verify-credentials.ts @@ -12,7 +12,7 @@ export async function verifyCredentials( username: string, password: string ): Promise { - const sanitizedUsername = sanitizeInput(username) + const sanitizedUsername = sanitizeInput(username).trim() if (loginAttemptTracker.isLocked(sanitizedUsername)) { return false