From 185dcde0e1b61f809741ad87f9523d9ea5615081 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 22:10:33 +0000 Subject: [PATCH] fix: make username (account_id) lookups case-insensitive Normalize account_id and product_id to lowercase before DynamoDB queries so that URLs like /ALukach resolve correctly to the /alukach account. Also redirect mixed-case account page URLs to their canonical lowercase form. Closes #299 Co-authored-by: Anthony Lukach --- src/app/(app)/[account_id]/page.tsx | 6 +++++- src/lib/clients/database/accounts.ts | 5 +++-- src/lib/clients/database/products.ts | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/app/(app)/[account_id]/page.tsx b/src/app/(app)/[account_id]/page.tsx index 17c3af41..ee2e73a9 100644 --- a/src/app/(app)/[account_id]/page.tsx +++ b/src/app/(app)/[account_id]/page.tsx @@ -11,7 +11,7 @@ */ import { Metadata } from "next"; -import { notFound } from "next/navigation"; +import { notFound, redirect } from "next/navigation"; import { OrganizationProfilePage } from "@/app/(app)/[account_id]/OrganizationProfilePage"; import { accountsTable, isOrganizationalAccount } from "@/lib/clients/database"; import { IndividualProfilePage } from "./IndividualProfilePage"; @@ -40,6 +40,10 @@ export default async function AccountPage({ params, searchParams }: PageProps) { const { account_id } = await params; const showWelcome = Object.hasOwn(await searchParams, "welcome"); + if (account_id !== account_id.toLowerCase()) { + redirect(`/${account_id.toLowerCase()}`); + } + const account = await accountsTable.fetchById(account_id); if (!account) { notFound(); diff --git a/src/lib/clients/database/accounts.ts b/src/lib/clients/database/accounts.ts index dec8a2c4..15b11a20 100644 --- a/src/lib/clients/database/accounts.ts +++ b/src/lib/clients/database/accounts.ts @@ -20,6 +20,7 @@ class AccountsTable extends BaseTable { model = "accounts"; async fetchById(account_id: string): Promise { + account_id = account_id.toLowerCase(); try { LOGGER.debug(`Trying to fetch account for ID`, { operation: "AccountsTable.fetchById", @@ -60,8 +61,8 @@ class AccountsTable extends BaseTable { ): Promise { const accountBatches: Account[] = []; - // Remove duplicates - account_ids = [...new Set(account_ids)]; + // Remove duplicates and normalize to lowercase + account_ids = [...new Set(account_ids.map((id) => id.toLowerCase()))]; for (let i = 0; i < account_ids.length; i += batchSize) { const batch = account_ids.slice(i, i + batchSize); diff --git a/src/lib/clients/database/products.ts b/src/lib/clients/database/products.ts index 939fa96a..96f9a6d3 100644 --- a/src/lib/clients/database/products.ts +++ b/src/lib/clients/database/products.ts @@ -68,6 +68,7 @@ export class ProductsTable extends BaseTable { products: Product[]; lastEvaluatedKey: any; }> { + account_id = account_id.toLowerCase(); const result = await this.client.send( new QueryCommand({ TableName: this.table, @@ -170,6 +171,8 @@ export class ProductsTable extends BaseTable { account_id: string, product_id: string ): Promise { + account_id = account_id.toLowerCase(); + product_id = product_id.toLowerCase(); try { const [result, account] = await Promise.all([ this.client.send(