Audit fixes: VIP self-grant, draft leak, onboarding flag, hero personalization, gated downloads
Deploy GitHub Pages / deploy (push) Canceled after 0s
Deploy GitHub Pages / deploy (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
/* One like per user per post. `likes`/`views` counters live on the post doc;
|
||||
this collection records who liked what so the toggle is idempotent. */
|
||||
const PostLikes: CollectionConfig = {
|
||||
slug: 'post-likes',
|
||||
admin: {
|
||||
useAsTitle: 'id',
|
||||
defaultColumns: ['user', 'post', 'createdAt'],
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
create: ({ req }) => !!req.user,
|
||||
delete: ({ req }) => {
|
||||
// Admins and the like owner can unlike
|
||||
const user = req.user as { id?: number | string; role?: string } | undefined
|
||||
if (user?.role === 'admin') return true
|
||||
return { user: { equals: user?.id } }
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{ name: 'user', type: 'relationship', relationTo: 'users', required: true, index: true },
|
||||
{ name: 'post', type: 'relationship', relationTo: 'posts', required: true, index: true },
|
||||
],
|
||||
hooks: {
|
||||
beforeValidate: [
|
||||
async ({ data, req, operation }) => {
|
||||
if (operation !== 'create' || !data || !req.payload) return data
|
||||
const existing = await req.payload.find({
|
||||
collection: 'post-likes',
|
||||
where: {
|
||||
and: [
|
||||
{ user: { equals: data.user } },
|
||||
{ post: { equals: data.post } },
|
||||
],
|
||||
},
|
||||
limit: 1,
|
||||
})
|
||||
if (existing.docs.length > 0) throw new Error('already-liked')
|
||||
return data
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
export default PostLikes
|
||||
Reference in New Issue
Block a user