feat: moderation locking (#5070)

* feat: base locking impl

* feat: lock logic in place in rev endpoint + fetch rev

* feat: frontend impl and finalize

* feat: auto skip if using the moderation queue page

* fix: qa issues

* fix: async state + locking fix

* fix: lint

* fix: fmt

* fix: qa issue

* fix: qa + redirect bug

* fix: lint

* feat: delete all locks endpoint for admins

* fix: dedupe

* fix: fmt

* fix: project redirect move to middleware

* fix: lint
This commit is contained in:
Calum H.
2026-01-12 17:08:30 +00:00
committed by GitHub
parent 915d8c68bf
commit b46f6d0141
21 changed files with 1644 additions and 321 deletions

View File

@@ -0,0 +1,56 @@
import { getProjectTypeForUrlShorthand } from '~/helpers/projects.js'
import { useServerModrinthClient } from '~/server/utils/api-client'
// All valid project type URL segments
const PROJECT_TYPES = ['project', 'mod', 'plugin', 'datapack', 'shader', 'resourcepack', 'modpack']
export default defineNuxtRouteMiddleware(async (to) => {
// Only handle project routes
if (!to.params.id || !PROJECT_TYPES.includes(to.params.type as string)) {
return
}
const authToken = useCookie('auth-token')
const client = useServerModrinthClient({ authToken: authToken.value || undefined })
const tags = useGeneratedState()
try {
const project = await client.labrinth.projects_v2.get(to.params.id as string)
if (!project) {
return
}
// Determine the correct URL type
const correctType = getProjectTypeForUrlShorthand(
project.project_type,
project.loaders,
tags.value,
)
// Preserve the rest of the path (subpages like /versions, /settings, etc.)
const pathParts = to.path.split('/')
pathParts.splice(0, 3) // Remove '', type, and id
const remainder = pathParts.filter((x) => x).join('/')
// Build the canonical path
const canonicalPath = `/${correctType}/${project.slug}${remainder ? `/${remainder}` : ''}`
// Only redirect if the path actually changed
if (to.path !== canonicalPath) {
return navigateTo(
{
path: canonicalPath,
query: to.query,
hash: to.hash,
},
{
redirectCode: 301,
replace: true,
},
)
}
} catch {
// Let the page handle 404s and other errors
}
})