@@ -2,6 +2,7 @@ import type { FastifyContextConfig, FastifyInstance, FastifyRequest, FastifyRepl
22import { generateQRBuffer , generateQRSvg } from '../utils/qr.js' ;
33import type { PlatformLink } from '@devcard/shared' ;
44import { getErrorMessage } from '../utils/error.util.js' ;
5+
56type PublicProfileLink = {
67 id : string ;
78 platform : string ;
@@ -11,7 +12,7 @@ type PublicProfileLink = {
1112 followed ?: boolean ;
1213}
1314
14- type UsernamePublicProfileResponse = {
15+ type UsernamePublicProfileResponse = {
1516 username : string ;
1617 displayName : string ;
1718 bio : string | null ;
@@ -59,7 +60,6 @@ type UsernameCardPublicProfileResponse = {
5960 links : PublicProfileCardLink [ ]
6061}
6162
62- // Represents a CardLink record with the joined PlatformLink relation
6363interface CardLinkWithPlatform {
6464 id : string ;
6565 displayOrder : number ;
@@ -94,24 +94,26 @@ export async function publicRoutes(app: FastifyInstance) {
9494
9595 // Try to extract viewer from Authorization header (soft auth)
9696 let viewerId : string | null = null ;
97+ let isSelfView = false ;
9798 try {
9899 if ( request . headers . authorization ) {
99100 const decoded = ( await request . jwtVerify ( ) ) as { id ?: string } ;
100- viewerId = decoded ?. id ?? null ;
101- } else {
102- viewerId = null ; // Unauthenticated viewer
101+ if ( decoded ?. id === user . id ) {
102+ isSelfView = true ;
103+ } else {
104+ viewerId = decoded ?. id ?? null ;
105+ }
103106 }
104107 } catch {
105108 // Ignored if invalid token
106109 }
107110
108111 // Don't track if the owner is viewing their own profile
109- if ( viewerId && viewerId !== user . id ) {
110- // Background view tracking
112+ if ( ! isSelfView && viewerId !== user . id ) {
111113 app . prisma . cardView . create ( {
112114 data : {
113115 ownerId : user . id ,
114- cardId : null , // this is a profile view, not a card view
116+ cardId : null ,
115117 viewerId,
116118 viewerIp : request . ip || null ,
117119 viewerAgent : request . headers [ 'user-agent' ] || null ,
@@ -168,7 +170,6 @@ export async function publicRoutes(app: FastifyInstance) {
168170 }
169171
170172 return response ;
171-
172173 } ) ;
173174
174175 /**
@@ -222,7 +223,6 @@ export async function publicRoutes(app: FastifyInstance) {
222223 }
223224
224225 return response ;
225-
226226 } ) ;
227227
228228 // ─── Public Card View ───
@@ -264,16 +264,21 @@ export async function publicRoutes(app: FastifyInstance) {
264264 }
265265
266266 let viewerId : string | null = null ;
267+ let isSelfView = false ;
267268 try {
268269 if ( request . headers . authorization ) {
269- const decoded = ( await request . jwtVerify ( ) ) as { id ?: string } ;
270- viewerId = decoded ?. id ?? null ;
270+ const decoded = await request . jwtVerify ( ) as any ;
271+ if ( decoded ?. id === user . id ) {
272+ isSelfView = true ;
273+ } else {
274+ viewerId = decoded . id ;
275+ }
271276 }
272- } catch {
277+ } catch ( e ) {
273278 // Ignored if invalid token
274279 }
275280
276- if ( viewerId && viewerId !== user . id ) {
281+ if ( ! isSelfView && viewerId !== user . id ) {
277282 app . prisma . cardView . create ( {
278283 data : {
279284 ownerId : user . id ,
@@ -286,7 +291,6 @@ export async function publicRoutes(app: FastifyInstance) {
286291 } ) . catch ( ( err : unknown ) => app . log . error ( `Failed to log view: ${ getErrorMessage ( err ) } ` ) ) ;
287292 }
288293
289-
290294 const response : UsernameCardPublicProfileResponse = {
291295 title : card . title ,
292296 owner : {
@@ -315,7 +319,7 @@ export async function publicRoutes(app: FastifyInstance) {
315319 app . get ( '/:username/qr' , {
316320 config : {
317321 rateLimit : {
318- max : 50 , // Lower limit for QR generation as it's more resource intensive
322+ max : 50 ,
319323 timeWindow : '1 minute'
320324 }
321325 } as FastifyContextConfig
@@ -327,7 +331,6 @@ export async function publicRoutes(app: FastifyInstance) {
327331 const format = request . query . format || 'png' ;
328332 const size = parseInt ( request . query . size || '400' , 10 ) ;
329333
330- // Verify user exists
331334 const user = await app . prisma . user . findUnique ( {
332335 where : { username } ,
333336 } ) ;
@@ -352,4 +355,4 @@ export async function publicRoutes(app: FastifyInstance) {
352355 . header ( 'Content-Disposition' , `inline; filename="devcard-${ username } .png"` )
353356 . send ( png ) ;
354357 } ) ;
355- }
358+ }
0 commit comments