fix(auth): drop nonexistent account_blocked column from login lookup
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:
1 parent
8275842e78
commit
22d455da7a
13 files changed
+71
-65
No files matched your search
@@ -58,7 +58,7 @@ export default async function AdminHelpTicketsPage({
|
||||
.limit(50)
|
||||
.catch(() => []);
|
||||
|
||||
const searchOr = [
|
||||
const searchFilter = or(
|
||||
like(WebsiteHelpCenterTickets.title, `%${q}%`),
|
||||
like(WebsiteHelpCenterTickets.content, `%${q}%`),
|
||||
...(matchingUsers.length > 0
|
||||
@@ -70,8 +70,8 @@ export default async function AdminHelpTicketsPage({
|
||||
]
|
||||
: []),
|
||||
...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []),
|
||||
];
|
||||
conditions.push(or(...searchOr)!);
|
||||
);
|
||||
if (searchFilter) conditions.push(searchFilter);
|
||||
}
|
||||
|
||||
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
|
||||
@@ -54,7 +54,7 @@ export default async function CfhListPage({
|
||||
userIds = [];
|
||||
}
|
||||
|
||||
const searchOr = [
|
||||
const searchFilter = or(
|
||||
like(SupportTickets.issue, `%${q}%`),
|
||||
...(Number.isFinite(asId) && asId > 0
|
||||
? [eq(SupportTickets.id, asId)]
|
||||
@@ -66,8 +66,8 @@ export default async function CfhListPage({
|
||||
inArray(SupportTickets.modId, userIds),
|
||||
]
|
||||
: []),
|
||||
];
|
||||
conditions.push(or(...searchOr)!);
|
||||
);
|
||||
if (searchFilter) conditions.push(searchFilter);
|
||||
}
|
||||
|
||||
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
|
||||
@@ -51,7 +51,7 @@ export default async function AdminTicketsDeskPage({
|
||||
if (parsed.search.trim()) {
|
||||
const q = parsed.search.trim();
|
||||
const asId = Number(q);
|
||||
const searchOr = [
|
||||
const searchFilter = or(
|
||||
like(WebsiteTicket.subject, `%${q}%`),
|
||||
like(WebsiteTicket.category, `%${q}%`),
|
||||
like(Creator.username, `%${q}%`),
|
||||
@@ -59,8 +59,8 @@ export default async function AdminTicketsDeskPage({
|
||||
...(Number.isFinite(asId) && asId > 0
|
||||
? [eq(WebsiteTicket.id, asId)]
|
||||
: []),
|
||||
];
|
||||
conditions.push(or(...searchOr)!);
|
||||
);
|
||||
if (searchFilter) conditions.push(searchFilter);
|
||||
}
|
||||
|
||||
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
|
||||
@@ -90,18 +90,17 @@ export default async function AdminTransactions({
|
||||
userIds = [];
|
||||
}
|
||||
|
||||
conditions.push(
|
||||
or(
|
||||
like(WebsitePaypalTransactions.transactionId, `%${q}%`),
|
||||
like(WebsitePaypalTransactions.description, `%${q}%`),
|
||||
...(Number.isFinite(asId) && asId > 0
|
||||
? [eq(WebsitePaypalTransactions.userId, asId)]
|
||||
: []),
|
||||
...(userIds.length
|
||||
? [inArray(WebsitePaypalTransactions.userId, userIds)]
|
||||
: []),
|
||||
)!,
|
||||
const searchFilter = or(
|
||||
like(WebsitePaypalTransactions.transactionId, `%${q}%`),
|
||||
like(WebsitePaypalTransactions.description, `%${q}%`),
|
||||
...(Number.isFinite(asId) && asId > 0
|
||||
? [eq(WebsitePaypalTransactions.userId, asId)]
|
||||
: []),
|
||||
...(userIds.length
|
||||
? [inArray(WebsitePaypalTransactions.userId, userIds)]
|
||||
: []),
|
||||
);
|
||||
if (searchFilter) conditions.push(searchFilter);
|
||||
}
|
||||
|
||||
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
|
||||
@@ -32,17 +32,17 @@ export default async function EmulatorTranslationsPage({
|
||||
|
||||
const patternFilters = or(
|
||||
...TRANSLATION_KEY_PATTERNS.map((p) => like(EmulatorSettings.key, `${p}%`)),
|
||||
)!;
|
||||
);
|
||||
if (!patternFilters) throw new Error("No emulator translation key patterns");
|
||||
|
||||
const conditions: SQL[] = [patternFilters];
|
||||
if (group) conditions.push(like(EmulatorSettings.key, `${group}.%`));
|
||||
if (search) {
|
||||
conditions.push(
|
||||
or(
|
||||
like(EmulatorSettings.key, `%${search}%`),
|
||||
like(EmulatorSettings.value, `%${search}%`),
|
||||
)!,
|
||||
const searchFilter = or(
|
||||
like(EmulatorSettings.key, `%${search}%`),
|
||||
like(EmulatorSettings.value, `%${search}%`),
|
||||
);
|
||||
if (searchFilter) conditions.push(searchFilter);
|
||||
}
|
||||
const where = and(...conditions);
|
||||
|
||||
|
||||
@@ -659,7 +659,7 @@ export const PUT = withAdmin(
|
||||
|
||||
// Create the page (only happens once per new category)
|
||||
const catInfo = CATEGORY_PAGE[catKey] || CATEGORY_PAGE.other;
|
||||
const parentId = parentPage?.id;
|
||||
const parentId = parentPage.id;
|
||||
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)
|
||||
VALUES (${captionSave}, ${catInfo.label}, 'default_3x3', ${parentId}, '1', ${catInfo.order}, ${catInfo.icon}, '1', '1', '', '', '', '', '', '', '', '')
|
||||
@@ -670,7 +670,7 @@ export const PUT = withAdmin(
|
||||
.where(
|
||||
and(
|
||||
eq(CatalogPages.captionSave, captionSave),
|
||||
eq(CatalogPages.parentId, parentId!),
|
||||
eq(CatalogPages.parentId, parentId),
|
||||
),
|
||||
)
|
||||
.limit(1);
|
||||
|
||||
@@ -68,7 +68,8 @@ export default async function ModCfhListPage({
|
||||
ors.push(inArray(SupportTickets.reportedId, 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;
|
||||
|
||||
@@ -82,7 +82,8 @@ export default async function ModHelpTicketsPage({
|
||||
if (asId !== null) {
|
||||
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;
|
||||
|
||||
@@ -69,7 +69,8 @@ export default async function ModTicketsDeskPage({
|
||||
if (Number.isFinite(asId) && asId > 0) {
|
||||
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;
|
||||
|
||||
@@ -116,7 +116,8 @@ export default async function ModUsersPage({
|
||||
if (Number.isFinite(Number(q)) && Number(q) > 0) {
|
||||
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;
|
||||
|
||||
|
||||
@@ -5,8 +5,16 @@ export interface StaffActivityFilters {
|
||||
authorizationOnly?: boolean;
|
||||
}
|
||||
|
||||
export function buildStaffActivityWhere(filters: StaffActivityFilters): any {
|
||||
const where: any = {};
|
||||
interface StaffActivityWhere {
|
||||
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())
|
||||
where.OR = [
|
||||
{ action: { contains: filters.q.trim() } },
|
||||
|
||||
@@ -73,7 +73,8 @@ async function fetchCmsCandidates(
|
||||
? [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;
|
||||
@@ -146,7 +147,8 @@ async function fetchHelpCandidates(
|
||||
: []),
|
||||
...(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;
|
||||
@@ -210,16 +212,15 @@ async function countCms(search: string, openOnly: boolean): Promise<number> {
|
||||
if (openOnly) conditions.push(ne(WebsiteTicket.status, "closed"));
|
||||
if (search) {
|
||||
const asId = Number(search);
|
||||
conditions.push(
|
||||
or(
|
||||
like(WebsiteTicket.subject, `%${search}%`),
|
||||
like(WebsiteTicket.category, `%${search}%`),
|
||||
like(Creator.username, `%${search}%`),
|
||||
...(Number.isFinite(asId) && asId > 0
|
||||
? [eq(WebsiteTicket.id, asId)]
|
||||
: []),
|
||||
)!,
|
||||
const searchFilter = or(
|
||||
like(WebsiteTicket.subject, `%${search}%`),
|
||||
like(WebsiteTicket.category, `%${search}%`),
|
||||
like(Creator.username, `%${search}%`),
|
||||
...(Number.isFinite(asId) && asId > 0
|
||||
? [eq(WebsiteTicket.id, asId)]
|
||||
: []),
|
||||
);
|
||||
if (searchFilter) conditions.push(searchFilter);
|
||||
}
|
||||
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
const rows = await db
|
||||
@@ -242,21 +243,20 @@ async function countHelp(search: string, openOnly: boolean): Promise<number> {
|
||||
.where(like(User.username, `%${search}%`))
|
||||
.limit(50)
|
||||
.catch(() => []);
|
||||
conditions.push(
|
||||
or(
|
||||
like(WebsiteHelpCenterTickets.title, `%${search}%`),
|
||||
like(WebsiteHelpCenterTickets.content, `%${search}%`),
|
||||
...(matchingUsers.length > 0
|
||||
? [
|
||||
inArray(
|
||||
WebsiteHelpCenterTickets.userId,
|
||||
matchingUsers.map((u) => u.id),
|
||||
),
|
||||
]
|
||||
: []),
|
||||
...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []),
|
||||
)!,
|
||||
const searchFilter = or(
|
||||
like(WebsiteHelpCenterTickets.title, `%${search}%`),
|
||||
like(WebsiteHelpCenterTickets.content, `%${search}%`),
|
||||
...(matchingUsers.length > 0
|
||||
? [
|
||||
inArray(
|
||||
WebsiteHelpCenterTickets.userId,
|
||||
matchingUsers.map((u) => u.id),
|
||||
),
|
||||
]
|
||||
: []),
|
||||
...(asId !== null ? [eq(WebsiteHelpCenterTickets.id, asId)] : []),
|
||||
);
|
||||
if (searchFilter) conditions.push(searchFilter);
|
||||
}
|
||||
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
const rows = await db
|
||||
|
||||
+1
-6
@@ -21,7 +21,6 @@ interface LoginUser {
|
||||
mailVerified: string | null;
|
||||
twoFactorConfirmedAt: string | null;
|
||||
twoFactorSecret: string | null;
|
||||
accountBlocked: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,13 +40,11 @@ async function getLoginUser(username: string): Promise<LoginUser | null> {
|
||||
mail_verified: string | null;
|
||||
two_factor_confirmed_at: string | null;
|
||||
two_factor_secret: string | null;
|
||||
account_blocked: string | null;
|
||||
}>(sql`
|
||||
SELECT id, username, password, rank, mail,
|
||||
mail_verified,
|
||||
two_factor_confirmed_at,
|
||||
two_factor_secret,
|
||||
account_blocked
|
||||
two_factor_secret
|
||||
FROM users
|
||||
WHERE username = ${username}
|
||||
LIMIT 1
|
||||
@@ -61,7 +58,6 @@ async function getLoginUser(username: string): Promise<LoginUser | null> {
|
||||
mail_verified: string | null;
|
||||
two_factor_confirmed_at: string | null;
|
||||
two_factor_secret: string | null;
|
||||
account_blocked: string | null;
|
||||
}>;
|
||||
return rows.length > 0
|
||||
? {
|
||||
@@ -73,7 +69,6 @@ async function getLoginUser(username: string): Promise<LoginUser | null> {
|
||||
mailVerified: rows[0].mail_verified,
|
||||
twoFactorConfirmedAt: rows[0].two_factor_confirmed_at,
|
||||
twoFactorSecret: rows[0].two_factor_secret,
|
||||
accountBlocked: rows[0].account_blocked,
|
||||
}
|
||||
: null;
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user