Fix displayName undefined in /auth/me and /auth/verify-otp endpoints

- Add custom_name to user_access query in both endpoints
- Compute displayName as customName || originalName
- Include customName, displayName, and originalName in response
- Ensures consistent beneficiary data format across all endpoints
This commit is contained in:
Sergei 2026-01-29 10:52:26 -08:00
parent 869f5d1305
commit 2d7a5336b4

View File

@ -7,40 +7,32 @@ const { supabase } = require('../config/supabase');
const { sendOTPEmail } = require('../services/email');
const storage = require('../services/storage');
// Rate limiter for OTP verification: 5 attempts per 15 minutes per email/IP
// Rate limiter for OTP verification: 5 attempts per 15 minutes per email
const verifyOtpLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5,
keyGenerator: (req) => {
// Use email if provided, otherwise fall back to IP
// Use email only - avoid IP-based limiting issues
const email = req.body?.email?.toLowerCase()?.trim();
if (email) return email;
// Handle IPv6 addresses properly
const ip = req.ip || req.socket?.remoteAddress || 'unknown';
return ip.replace(/^::ffff:/, ''); // Normalize IPv4-mapped IPv6
return email || 'unknown';
},
message: { error: 'Too many verification attempts. Please try again in 15 minutes.' },
standardHeaders: true,
legacyHeaders: false,
validate: { ip: false, xForwardedForHeader: false }, // Disable IP validation
});
// Rate limiter for OTP request: 3 attempts per 15 minutes per email/IP
// Rate limiter for OTP request: 3 attempts per 15 minutes per email
const requestOtpLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 3,
keyGenerator: (req) => {
// Use email if provided, otherwise fall back to IP
// Use email only - avoid IP-based limiting issues
const email = req.body?.email?.toLowerCase()?.trim();
if (email) return email;
// Handle IPv6 addresses properly
const ip = req.ip || req.socket?.remoteAddress || 'unknown';
return ip.replace(/^::ffff:/, ''); // Normalize IPv4-mapped IPv6
return email || 'unknown';
},
message: { error: 'Too many OTP requests. Please try again in 15 minutes.' },
standardHeaders: true,
legacyHeaders: false,
validate: { ip: false, xForwardedForHeader: false }, // Disable IP validation
});
/**
@ -231,6 +223,7 @@ router.post('/verify-otp', verifyOtpLimiter, async (req, res) => {
beneficiary_id,
role,
granted_at,
custom_name,
beneficiaries:beneficiary_id (
id,
email,
@ -246,13 +239,22 @@ router.post('/verify-otp', verifyOtpLimiter, async (req, res) => {
`)
.eq('accessor_id', user.id);
// Форматируем beneficiaries
const beneficiaries = (accessRecords || []).map(record => ({
// Форматируем beneficiaries с displayName
const beneficiaries = (accessRecords || []).map(record => {
const customName = record.custom_name || null;
const originalName = record.beneficiaries?.first_name || null;
const displayName = customName || originalName;
return {
id: record.beneficiary_id,
role: record.role,
grantedAt: record.granted_at,
customName: customName,
displayName: displayName,
originalName: originalName,
...record.beneficiaries
}));
};
});
// Генерируем JWT токен
const token = jwt.sign(
@ -323,6 +325,7 @@ router.get('/me', async (req, res) => {
beneficiary_id,
role,
granted_at,
custom_name,
beneficiaries:beneficiary_id (
id,
email,
@ -338,13 +341,22 @@ router.get('/me', async (req, res) => {
`)
.eq('accessor_id', user.id);
// Форматируем beneficiaries
const beneficiaries = (accessRecords || []).map(record => ({
// Форматируем beneficiaries с displayName
const beneficiaries = (accessRecords || []).map(record => {
const customName = record.custom_name || null;
const originalName = record.beneficiaries?.first_name || null;
const displayName = customName || originalName;
return {
id: record.beneficiary_id,
role: record.role,
grantedAt: record.granted_at,
customName: customName,
displayName: displayName,
originalName: originalName,
...record.beneficiaries
}));
};
});
res.json({
user: {