fix(auth): drop nonexistent account_blocked column from login lookup
CI / check (push) Successful in 34s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m42s

getLoginUser selected users.account_blocked, which does not exist in the
DB (nor the Drizzle schema). Every credentials authorize() call threw a
SQL error -> NextAuth CallbackRouteError -> 'error=Configuration', so no
login could ever succeed. Remove the phantom column from the query and
LoginUser interface.

Also fix all remaining biome noNonNullAssertion / noExplicitAny lint
warnings so CI's check job (biome:lint) passes and the push deploy runs.
This commit is contained in:
openhands committed 2026-08-01 17:38:43 +02:00
1 parent 8275842e78
commit 22d455da7a
13 files changed
+71 -65

No files matched your search

+3 -3
View File
@@ -58,7 +58,7 @@ export default async function AdminHelpTicketsPage({
.limit(50) .limit(50)
.catch(() => []); .catch(() => []);
const searchOr = [ const searchFilter = or(
like(WebsiteHelpCenterTickets.title, `%${q}%`), like(WebsiteHelpCenterTickets.title, `%${q}%`),
like(WebsiteHelpCenterTickets.content, `%${q}%`), like(WebsiteHelpCenterTickets.content, `%${q}%`),
...(matchingUsers.length > 0 ...(matchingUsers.length > 0
@@ -70,8 +70,8 @@ export default async function AdminHelpTicketsPage({
] ]
: []), : []),
...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []), ...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []),
]; );
conditions.push(or(...searchOr)!); if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
+3 -3
View File
@@ -54,7 +54,7 @@ export default async function CfhListPage({
userIds = []; userIds = [];
} }
const searchOr = [ const searchFilter = or(
like(SupportTickets.issue, `%${q}%`), like(SupportTickets.issue, `%${q}%`),
...(Number.isFinite(asId) && asId > 0 ...(Number.isFinite(asId) && asId > 0
? [eq(SupportTickets.id, asId)] ? [eq(SupportTickets.id, asId)]
@@ -66,8 +66,8 @@ export default async function CfhListPage({
inArray(SupportTickets.modId, userIds), inArray(SupportTickets.modId, userIds),
] ]
: []), : []),
]; );
conditions.push(or(...searchOr)!); if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
+3 -3
View File
@@ -51,7 +51,7 @@ export default async function AdminTicketsDeskPage({
if (parsed.search.trim()) { if (parsed.search.trim()) {
const q = parsed.search.trim(); const q = parsed.search.trim();
const asId = Number(q); const asId = Number(q);
const searchOr = [ const searchFilter = or(
like(WebsiteTicket.subject, `%${q}%`), like(WebsiteTicket.subject, `%${q}%`),
like(WebsiteTicket.category, `%${q}%`), like(WebsiteTicket.category, `%${q}%`),
like(Creator.username, `%${q}%`), like(Creator.username, `%${q}%`),
@@ -59,8 +59,8 @@ export default async function AdminTicketsDeskPage({
...(Number.isFinite(asId) && asId > 0 ...(Number.isFinite(asId) && asId > 0
? [eq(WebsiteTicket.id, asId)] ? [eq(WebsiteTicket.id, asId)]
: []), : []),
]; );
conditions.push(or(...searchOr)!); if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
+10 -11
View File
@@ -90,18 +90,17 @@ export default async function AdminTransactions({
userIds = []; userIds = [];
} }
conditions.push( const searchFilter = or(
or( like(WebsitePaypalTransactions.transactionId, `%${q}%`),
like(WebsitePaypalTransactions.transactionId, `%${q}%`), like(WebsitePaypalTransactions.description, `%${q}%`),
like(WebsitePaypalTransactions.description, `%${q}%`), ...(Number.isFinite(asId) && asId > 0
...(Number.isFinite(asId) && asId > 0 ? [eq(WebsitePaypalTransactions.userId, asId)]
? [eq(WebsitePaypalTransactions.userId, asId)] : []),
: []), ...(userIds.length
...(userIds.length ? [inArray(WebsitePaypalTransactions.userId, userIds)]
? [inArray(WebsitePaypalTransactions.userId, userIds)] : []),
: []),
)!,
); );
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
+6 -6
View File
@@ -32,17 +32,17 @@ export default async function EmulatorTranslationsPage({
const patternFilters = or( const patternFilters = or(
...TRANSLATION_KEY_PATTERNS.map((p) => like(EmulatorSettings.key, `${p}%`)), ...TRANSLATION_KEY_PATTERNS.map((p) => like(EmulatorSettings.key, `${p}%`)),
)!; );
if (!patternFilters) throw new Error("No emulator translation key patterns");
const conditions: SQL[] = [patternFilters]; const conditions: SQL[] = [patternFilters];
if (group) conditions.push(like(EmulatorSettings.key, `${group}.%`)); if (group) conditions.push(like(EmulatorSettings.key, `${group}.%`));
if (search) { if (search) {
conditions.push( const searchFilter = or(
or( like(EmulatorSettings.key, `%${search}%`),
like(EmulatorSettings.key, `%${search}%`), like(EmulatorSettings.value, `%${search}%`),
like(EmulatorSettings.value, `%${search}%`),
)!,
); );
if (searchFilter) conditions.push(searchFilter);
} }
const where = and(...conditions); const where = and(...conditions);
+2 -2
View File
@@ -659,7 +659,7 @@ export const PUT = withAdmin(
// Create the page (only happens once per new category) // Create the page (only happens once per new category)
const catInfo = CATEGORY_PAGE[catKey] || CATEGORY_PAGE.other; const catInfo = CATEGORY_PAGE[catKey] || CATEGORY_PAGE.other;
const parentId = parentPage?.id; const parentId = parentPage.id;
await db.execute(sql` await db.execute(sql`
INSERT INTO catalog_pages (caption_save, caption, page_layout, parent_id, min_rank, order_num, icon_image, enabled, visible, includes, page_headline, page_teaser, page_special, page_text1, page_text2, page_text_details, page_text_teaser) INSERT INTO catalog_pages (caption_save, caption, page_layout, parent_id, min_rank, order_num, icon_image, enabled, visible, includes, page_headline, page_teaser, page_special, page_text1, page_text2, page_text_details, page_text_teaser)
VALUES (${captionSave}, ${catInfo.label}, 'default_3x3', ${parentId}, '1', ${catInfo.order}, ${catInfo.icon}, '1', '1', '', '', '', '', '', '', '', '') VALUES (${captionSave}, ${catInfo.label}, 'default_3x3', ${parentId}, '1', ${catInfo.order}, ${catInfo.icon}, '1', '1', '', '', '', '', '', '', '', '')
@@ -670,7 +670,7 @@ export const PUT = withAdmin(
.where( .where(
and( and(
eq(CatalogPages.captionSave, captionSave), eq(CatalogPages.captionSave, captionSave),
eq(CatalogPages.parentId, parentId!), eq(CatalogPages.parentId, parentId),
), ),
) )
.limit(1); .limit(1);
+2 -1
View File
@@ -68,7 +68,8 @@ export default async function ModCfhListPage({
ors.push(inArray(SupportTickets.reportedId, userIds)); ors.push(inArray(SupportTickets.reportedId, userIds));
ors.push(inArray(SupportTickets.modId, userIds)); ors.push(inArray(SupportTickets.modId, userIds));
} }
conditions.push(or(...ors)!); const searchFilter = or(...ors);
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
+2 -1
View File
@@ -82,7 +82,8 @@ export default async function ModHelpTicketsPage({
if (asId !== null) { if (asId !== null) {
ors.push(eq(WebsiteHelpCenterTickets.id, asId)); ors.push(eq(WebsiteHelpCenterTickets.id, asId));
} }
conditions.push(or(...ors)!); const searchFilter = or(...ors);
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
+2 -1
View File
@@ -69,7 +69,8 @@ export default async function ModTicketsDeskPage({
if (Number.isFinite(asId) && asId > 0) { if (Number.isFinite(asId) && asId > 0) {
ors.push(eq(WebsiteTicket.id, asId)); ors.push(eq(WebsiteTicket.id, asId));
} }
conditions.push(or(...ors)!); const searchFilter = or(...ors);
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
+2 -1
View File
@@ -116,7 +116,8 @@ export default async function ModUsersPage({
if (Number.isFinite(Number(q)) && Number(q) > 0) { if (Number.isFinite(Number(q)) && Number(q) > 0) {
ors.push(eq(User.id, Number(q))); ors.push(eq(User.id, Number(q)));
} }
conditions.push(or(...ors)!); const searchFilter = or(...ors);
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
+10 -2
View File
@@ -5,8 +5,16 @@ export interface StaffActivityFilters {
authorizationOnly?: boolean; authorizationOnly?: boolean;
} }
export function buildStaffActivityWhere(filters: StaffActivityFilters): any { interface StaffActivityWhere {
const where: any = {}; OR?: Array<Record<string, { contains?: string }>>;
userId?: bigint;
action?: { startsWith: string } | { contains: string };
}
export function buildStaffActivityWhere(
filters: StaffActivityFilters,
): StaffActivityWhere {
const where: StaffActivityWhere = {};
if (filters.q?.trim()) if (filters.q?.trim())
where.OR = [ where.OR = [
{ action: { contains: filters.q.trim() } }, { action: { contains: filters.q.trim() } },
+25 -25
View File
@@ -73,7 +73,8 @@ async function fetchCmsCandidates(
? [eq(WebsiteTicket.id, asId)] ? [eq(WebsiteTicket.id, asId)]
: []), : []),
]; ];
conditions.push(or(...searchOr)!); const searchFilter = or(...searchOr);
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
@@ -146,7 +147,8 @@ async function fetchHelpCandidates(
: []), : []),
...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []), ...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []),
]; ];
conditions.push(or(...searchOr)!); const searchFilter = or(...searchOr);
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
@@ -210,16 +212,15 @@ async function countCms(search: string, openOnly: boolean): Promise<number> {
if (openOnly) conditions.push(ne(WebsiteTicket.status, "closed")); if (openOnly) conditions.push(ne(WebsiteTicket.status, "closed"));
if (search) { if (search) {
const asId = Number(search); const asId = Number(search);
conditions.push( const searchFilter = or(
or( like(WebsiteTicket.subject, `%${search}%`),
like(WebsiteTicket.subject, `%${search}%`), like(WebsiteTicket.category, `%${search}%`),
like(WebsiteTicket.category, `%${search}%`), like(Creator.username, `%${search}%`),
like(Creator.username, `%${search}%`), ...(Number.isFinite(asId) && asId > 0
...(Number.isFinite(asId) && asId > 0 ? [eq(WebsiteTicket.id, asId)]
? [eq(WebsiteTicket.id, asId)] : []),
: []),
)!,
); );
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
const rows = await db const rows = await db
@@ -242,21 +243,20 @@ async function countHelp(search: string, openOnly: boolean): Promise<number> {
.where(like(User.username, `%${search}%`)) .where(like(User.username, `%${search}%`))
.limit(50) .limit(50)
.catch(() => []); .catch(() => []);
conditions.push( const searchFilter = or(
or( like(WebsiteHelpCenterTickets.title, `%${search}%`),
like(WebsiteHelpCenterTickets.title, `%${search}%`), like(WebsiteHelpCenterTickets.content, `%${search}%`),
like(WebsiteHelpCenterTickets.content, `%${search}%`), ...(matchingUsers.length > 0
...(matchingUsers.length > 0 ? [
? [ inArray(
inArray( WebsiteHelpCenterTickets.userId,
WebsiteHelpCenterTickets.userId, matchingUsers.map((u) => u.id),
matchingUsers.map((u) => u.id), ),
), ]
] : []),
: []), ...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []),
...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []),
)!,
); );
if (searchFilter) conditions.push(searchFilter);
} }
const where = conditions.length > 0 ? and(...conditions) : undefined; const where = conditions.length > 0 ? and(...conditions) : undefined;
const rows = await db const rows = await db
+1 -6
View File
@@ -21,7 +21,6 @@ interface LoginUser {
mailVerified: string | null; mailVerified: string | null;
twoFactorConfirmedAt: string | null; twoFactorConfirmedAt: string | null;
twoFactorSecret: string | null; twoFactorSecret: string | null;
accountBlocked: string | null;
} }
/** /**
@@ -41,13 +40,11 @@ async function getLoginUser(username: string): Promise<LoginUser | null> {
mail_verified: string | null; mail_verified: string | null;
two_factor_confirmed_at: string | null; two_factor_confirmed_at: string | null;
two_factor_secret: string | null; two_factor_secret: string | null;
account_blocked: string | null;
}>(sql` }>(sql`
SELECT id, username, password, rank, mail, SELECT id, username, password, rank, mail,
mail_verified, mail_verified,
two_factor_confirmed_at, two_factor_confirmed_at,
two_factor_secret, two_factor_secret
account_blocked
FROM users FROM users
WHERE username = ${username} WHERE username = ${username}
LIMIT 1 LIMIT 1
@@ -61,7 +58,6 @@ async function getLoginUser(username: string): Promise<LoginUser | null> {
mail_verified: string | null; mail_verified: string | null;
two_factor_confirmed_at: string | null; two_factor_confirmed_at: string | null;
two_factor_secret: string | null; two_factor_secret: string | null;
account_blocked: string | null;
}>; }>;
return rows.length > 0 return rows.length > 0
? { ? {
@@ -73,7 +69,6 @@ async function getLoginUser(username: string): Promise<LoginUser | null> {
mailVerified: rows[0].mail_verified, mailVerified: rows[0].mail_verified,
twoFactorConfirmedAt: rows[0].two_factor_confirmed_at, twoFactorConfirmedAt: rows[0].two_factor_confirmed_at,
twoFactorSecret: rows[0].two_factor_secret, twoFactorSecret: rows[0].two_factor_secret,
accountBlocked: rows[0].account_blocked,
} }
: null; : null;
}, },