Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
name-template: "v$NEXT_PATCH_VERSION"
tag-template: "v$NEXT_PATCH_VERSION"

version-resolver:
major:
labels:
- "major"
- "breaking"
minor:
labels:
- "minor"
- "feature"
- "enhancement"
patch:
labels:
- "patch"
- "bug"
default: patch

categories:
- title: "🚀 Features"
labels:
- feature
- enhancement
- title: "🐛 Fixes"
- feat
- title: "🐛 Bug Fixes"
labels:
- bug
- fix
- bugfix
- title: "🛡️ Security"
labels:
- security
- CVE
- CWE
- title: "🛠 Maintenance"
labels:
- chore
Expand All @@ -23,6 +46,37 @@ categories:
labels:
- test
- tests

autolabeler:
- label: "feature"
branch:
- "/feature/.+/"
title:
- "/^feat:.+/"
- label: "bug"
branch:
- "/bug/.+/"
- "/fix/.+/"
title:
- "/^fix:.+/"
- label: "security"
title:
- "/CVE-.+/"
- "/CWE-.+/"
- "/security/i"
- label: "chore"
title:
- "/^chore:.+/"
- label: "documentation"
title:
- "/^docs:.+/"

replacers:
- search: "/CVE-(\\d{4}-\\d+)/g"
replace: "[CVE-$1](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-$1)"
- search: "/CWE-(\\d+)/g"
replace: "[CWE-$1](https://cwe.mitre.org/node/index.html?608?id=$1)"

change-template: "- $TITLE (#$NUMBER) @$AUTHOR"
no-changes-template: "No changes in this release."
template: |
Expand Down
24 changes: 21 additions & 3 deletions frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
{
"extends": ["next/core-web-vitals"],
"extends": [
"next/core-web-vitals"
],
"plugins": [
"@typescript-eslint"
],
"rules": {
"no-unused-vars": "warn",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
],
"no-console": "warn",
"prefer-const": "error"
},
"ignorePatterns": ["node_modules", ".next", "dist", "build"]
"ignorePatterns": [
"node_modules",
".next",
"dist",
"build"
]
}
53 changes: 27 additions & 26 deletions frontend/app/account/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
import { FaMicrosoft } from "react-icons/fa"
import { buildDiscordLoginUrl } from "@/lib/config"
import { RoleBadge } from "@/components/role-badge"
import { logError } from "@/lib/utils/error-handling"

const PREFERENCE_DEFAULTS = {
preferredLanguage: "en",
Expand Down Expand Up @@ -368,7 +369,7 @@ const [subscriptionPreview, setSubscriptionPreview] = useState<AccountSubscripti
}
window.location.href = data.url
} catch (error) {
console.error("Failed to open billing portal:", error)
logError("Failed to open billing portal", error)
setSubscriptionsError(error instanceof Error ? error.message : "Unable to open billing portal.")
} finally {
setRenewingSubscriptionId(null)
Expand Down Expand Up @@ -412,7 +413,7 @@ const profileShareUrl = profileShareSlug
phone: data.phone || prev.phone,
}))
} catch (error) {
console.error("Failed to load contact info:", error)
logError("Failed to load contact info", error)
setContactError("Unable to load contact information")
} finally {
setContactLoading(false)
Expand All @@ -439,7 +440,7 @@ const profileShareUrl = profileShareSlug
}
setContactMessage("Contact information updated")
} catch (error) {
console.error("Failed to save contact info:", error)
logError("Failed to save contact info", error)
setContactError(error instanceof Error ? error.message : "Failed to save contact information")
} finally {
setContactSaving(false)
Expand Down Expand Up @@ -472,7 +473,7 @@ const profileShareUrl = profileShareSlug
avatarUrl: data.avatarUrl ?? prev.avatarUrl,
}))
} catch (error) {
console.error("Failed to load profile settings:", error)
logError("Failed to load profile settings", error)
setProfileSettingsError("Unable to load profile settings")
} finally {
setProfileSettingsLoading(false)
Expand Down Expand Up @@ -513,7 +514,7 @@ const profileShareUrl = profileShareSlug
}))
setProfileMessage("Profile updated successfully.")
} catch (error) {
console.error("Failed to update profile settings:", error)
logError("Failed to update profile settings", error)
setProfileSettingsError(error instanceof Error ? error.message : "Unable to update profile settings.")
} finally {
setProfileSettingsSaving(false)
Expand All @@ -533,7 +534,7 @@ const profileShareUrl = profileShareSlug
const data = await response.json()
setLinkedAccounts(Array.isArray(data.accounts) ? data.accounts : [])
} catch (error) {
console.error("Failed to load linked accounts:", error)
logError("Failed to load linked accounts", error)
setLinkedAccountsError("Unable to load linked accounts")
} finally {
setLinkedAccountsLoading(false)
Expand Down Expand Up @@ -577,7 +578,7 @@ const profileShareUrl = profileShareSlug
setLinkedAccounts(Array.isArray(data.accounts) ? data.accounts : [])
setLinkedAccountForm((prev) => ({ ...prev, handle: "" }))
} catch (error) {
console.error("Failed to add linked account:", error)
logError("Failed to add linked account", error)
setLinkedAccountsError(error instanceof Error ? error.message : "Unable to add linked account")
} finally {
setLinkedAccountSaving(false)
Expand All @@ -604,7 +605,7 @@ const profileShareUrl = profileShareSlug
const data = await response.json()
setLinkedAccounts(Array.isArray(data.accounts) ? data.accounts : [])
} catch (error) {
console.error("Failed to remove linked account:", error)
logError("Failed to remove linked account", error)
setLinkedAccountsError(error instanceof Error ? error.message : "Unable to remove linked account")
} finally {
setLinkedAccountSaving(false)
Expand Down Expand Up @@ -651,7 +652,7 @@ const profileShareUrl = profileShareSlug
})),
)
} catch (error) {
console.error("Failed to load subscriptions:", error)
logError("Failed to load subscriptions", error)
setSubscriptions([])
setSubscriptionsError("Unable to load subscriptions right now.")
} finally {
Expand Down Expand Up @@ -681,11 +682,11 @@ const profileShareUrl = profileShareSlug
try {
window.localStorage.setItem("preferred_language", data.preferredLanguage)
} catch (error) {
console.error("Failed to persist language preference locally:", error)
logError("Failed to persist language preference locally", error)
}
}
} catch (error) {
console.error("Failed to load preferences:", error)
logError("Failed to load preferences", error)
}
}, [])

Expand All @@ -712,11 +713,11 @@ const profileShareUrl = profileShareSlug
try {
window.localStorage.setItem("preferred_language", value)
} catch (error) {
console.error("Failed to persist language preference locally:", error)
logError("Failed to persist language preference locally", error)
}
}
} catch (error) {
console.error("Failed to update language preference:", error)
logError("Failed to update language preference", error)
setLanguageError("Failed to update language")
} finally {
setLanguageSaving(false)
Expand Down Expand Up @@ -752,7 +753,7 @@ const profileShareUrl = profileShareSlug
}
setBillingMessage("Billing details saved.")
} catch (error) {
console.error("Failed to save billing details:", error)
logError("Failed to save billing details", error)
setBillingError("Could not save billing details.")
} finally {
setBillingSaving(false)
Expand All @@ -773,7 +774,7 @@ const profileShareUrl = profileShareSlug
...data,
})
} catch (error) {
console.error("Failed to load notifications:", error)
logError("Failed to load notifications", error)
setNotificationsError("Unable to load notifications")
} finally {
setNotificationsLoading(false)
Expand All @@ -800,7 +801,7 @@ const profileShareUrl = profileShareSlug
throw new Error(payload.error || "Failed to update notifications")
}
} catch (error) {
console.error("Failed to update notifications:", error)
logError("Failed to update notifications", error)
setNotificationsError("Failed to save notification settings")
} finally {
setNotificationsSaving(false)
Expand All @@ -823,7 +824,7 @@ const profileShareUrl = profileShareSlug
...data,
})
} catch (error) {
console.error("Failed to load privacy settings:", error)
logError("Failed to load privacy settings", error)
setPrivacyError("Unable to load privacy settings")
} finally {
setPrivacyLoading(false)
Expand All @@ -850,7 +851,7 @@ const profileShareUrl = profileShareSlug
throw new Error(payload.error || "Failed to update privacy settings")
}
} catch (error) {
console.error("Failed to update privacy settings:", error)
logError("Failed to update privacy settings", error)
setPrivacyError("Failed to save privacy settings")
} finally {
setPrivacySaving(false)
Expand All @@ -873,7 +874,7 @@ const profileShareUrl = profileShareSlug
...data,
})
} catch (error) {
console.error("Failed to load security settings:", error)
logError("Failed to load security settings", error)
setSecurityError("Unable to load security settings")
} finally {
setSecurityLoading(false)
Expand Down Expand Up @@ -908,7 +909,7 @@ const profileShareUrl = profileShareSlug
return fetched[0]?.id ?? prev
})
} catch (error) {
console.error("Failed to load sessions:", error)
logError("Failed to load sessions", error)
setSessionsError("Unable to load active sessions")
} finally {
setSessionsLoading(false)
Expand All @@ -934,7 +935,7 @@ const profileShareUrl = profileShareSlug
setBackupCodes(Array.isArray(data.codes) ? data.codes : [])
setBackupCodesFetched(true)
} catch (error) {
console.error("Failed to load backup codes:", error)
logError("Failed to load backup codes", error)
setBackupCodesError("Unable to fetch backup codes")
} finally {
setBackupCodesLoading(false)
Expand Down Expand Up @@ -980,7 +981,7 @@ const profileShareUrl = profileShareSlug
throw new Error(payload.error || "Failed to update security settings")
}
} catch (error) {
console.error("Failed to update security settings:", error)
logError("Failed to update security settings", error)
setSecurityError("Failed to save security settings")
} finally {
setSecuritySaving(false)
Expand Down Expand Up @@ -1016,7 +1017,7 @@ const profileShareUrl = profileShareSlug
anchor.click()
window.URL.revokeObjectURL(url)
} catch (error) {
console.error("Failed to download export:", error)
logError("Failed to download export", error)
setPrivacyError("Unable to download your data export")
} finally {
setDownloadingData(false)
Expand Down Expand Up @@ -1070,7 +1071,7 @@ const profileShareUrl = profileShareSlug
setBackupCodesVisible(true)
fetchSecurity(formData.discordId)
} catch (error) {
console.error("Failed to regenerate backup codes:", error)
logError("Failed to regenerate backup codes", error)
setBackupCodesError(error instanceof Error ? error.message : "Failed to regenerate backup codes")
} finally {
setBackupCodesLoading(false)
Expand Down Expand Up @@ -1174,7 +1175,7 @@ const profileShareUrl = profileShareSlug
void fetchSubscriptions(resolvedUserId)
void fetchProfileSettings(resolvedUserId)
} catch (error) {
console.error("Auth check failed:", error)
logError("Auth check failed", error)
localStorage.removeItem("discord_token")
localStorage.removeItem("discord_user_id")
if (!cancelled) {
Expand Down Expand Up @@ -1248,7 +1249,7 @@ const profileShareUrl = profileShareSlug
}
fetchSessions(formData.discordId, authToken)
} catch (error) {
console.error("Failed to revoke session:", error)
logError("Failed to revoke session", error)
setSessionsError(error instanceof Error ? error.message : "Unable to revoke session")
}
},
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/api/account/bot-settings/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { emitBotDefaultsUpdate } from "@/lib/server-settings-sync"
import { authorizeRequest } from "@/lib/api-auth"
import { clamp } from "@/lib/math"
import { getApiKeySecrets } from "@/lib/api-keys"
import { logError } from "@/lib/utils/error-handling"

type RouteDeps = {
verifyUser?: typeof verifyRequestForUser
Expand Down Expand Up @@ -65,7 +66,7 @@ export const createBotSettingsHandlers = (deps: RouteDeps = {}) => {
void emitBotDefaultsUpdate(discordId, settings as unknown as Record<string, unknown>)
return NextResponse.json(settings)
} catch (error) {
console.error("[VectoBeat] Failed to update bot settings:", error)
logError("Failed to update bot settings", error)
return NextResponse.json({ error: "Failed to update bot settings" }, { status: 500 })
}
}
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/api/account/contact/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type NextRequest, NextResponse } from "next/server"
import { verifyRequestForUser } from "@/lib/auth"
import { getUserContact, upsertUserContact } from "@/lib/db"
import { logError } from "@/lib/utils/error-handling"

type RouteDeps = {
verifyUser?: typeof verifyRequestForUser
Expand Down Expand Up @@ -48,7 +49,7 @@ export const createContactHandlers = (deps: RouteDeps = {}) => {
const updated = await fetchContact(discordId)
return NextResponse.json(updated)
} catch (error) {
console.error("[VectoBeat] Failed to update contact:", error)
logError("Failed to update contact", error)
return NextResponse.json({ error: "Failed to update contact info" }, { status: 500 })
}
}
Expand Down
Loading
Loading