Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | 1x 1x 7x 7x 7x 6x 6x 6x 7x 1x 1x 5x 5x 5x 5x 5x 7x 1x 1x 4x 4x 4x 4x 4x 7x 1x 1x 1x 3x 7x 1x 1x 1x 7x 10x 10x 10x 9x 9x 9x 9x 10x 1x 1x 8x 8x 10x 1x 1x 7x 7x 7x 7x 7x 10x 1x 1x 6x 6x 6x 6x 6x 10x 10x 1x 1x 1x 1x 1x 5x 10x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 10x 1x 1x 1x 3x 3x 3x 3x 3x 10x 3x 3x 3x 3x 3x 3x 10x 2x 2x 2x 10x | import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';
import { getAdminClient } from '@/lib/supabase/admin';
import { createHash } from 'crypto';
export async function GET(_request: NextRequest) {
try {
const supabase = await createClient();
const {
data: { user },
} = await supabase.auth.getUser();
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
// Get user's profile
const { data: profile } = await supabase
.from('profiles')
.select('id')
.eq('user_id', user.id)
.single();
if (!profile) {
return NextResponse.json({ error: 'Profile not found' }, { status: 404 });
}
// Get testimonial requests
const { data: requests, error } = await supabase
.from('testimonial_requests')
.select('*')
.eq('profile_id', profile.id)
.order('created_at', { ascending: false });
if (error) {
console.error('Error fetching requests:', error);
return NextResponse.json({ error: 'Failed to fetch requests' }, { status: 500 });
}
return NextResponse.json({ requests });
} catch (error) {
console.error('Testimonial requests GET error:', error);
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
}
}
export async function POST(request: NextRequest) {
try {
const supabase = await createClient();
const adminClient = getAdminClient();
const {
data: { user },
} = await supabase.auth.getUser();
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const body = await request.json();
const { recipient_email, recipient_name, relationship_context, custom_message } = body;
if (!recipient_email) {
return NextResponse.json({ error: 'Recipient email is required' }, { status: 400 });
}
// Get user's profile
const { data: profile } = await supabase
.from('profiles')
.select('id, subscription_tier, display_name')
.eq('user_id', user.id)
.single();
if (!profile) {
return NextResponse.json({ error: 'Profile not found' }, { status: 404 });
}
// Check rate limit (5 requests per day per profile)
const { data: canRequest, error: rateLimitError } = await adminClient.rpc('check_rate_limit', {
p_key_type: 'profile_requests',
p_key_value: profile.id,
p_limit: 5,
});
if (rateLimitError) {
console.error('Error checking rate limit:', rateLimitError);
// Continue anyway - don't block the request if rate limit check fails
} else if (canRequest === false) {
return NextResponse.json(
{ error: 'Rate limit exceeded. Please try again tomorrow.' },
{ status: 429 }
);
}
// Generate token
const { data: token, error: tokenError } = await adminClient.rpc('generate_request_token');
if (tokenError || !token) {
console.error('Error generating token:', tokenError);
return NextResponse.json({ error: 'Failed to generate request token' }, { status: 500 });
}
const tokenHash = createHash('sha256').update(token).digest('hex');
// Create request
const { data: requestData, error } = await adminClient
.from('testimonial_requests')
.insert({
profile_id: profile.id,
token,
token_hash: tokenHash,
recipient_email,
recipient_name,
relationship_context,
custom_message,
})
.select()
.single();
if (error) {
console.error('Error creating request:', error);
return NextResponse.json({ error: 'Failed to create request' }, { status: 500 });
}
// Increment rate limit (don't fail if this errors)
try {
await adminClient.rpc('increment_rate_limit', {
p_key_type: 'profile_requests',
p_key_value: profile.id,
});
} catch (rateLimitErr) {
console.error('Error incrementing rate limit:', rateLimitErr);
}
// TODO: Send email to recipient with the token link
// For now, return the request with the token for testing
const submitUrl = `${process.env.NEXT_PUBLIC_APP_URL}/testimonial/submit/${token}`;
return NextResponse.json({
request: requestData,
submitUrl,
message: 'Request created successfully',
});
} catch (error) {
console.error('Testimonial request POST error:', error);
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
}
}
|