const db = require('../db'); const { decodeBool, canProfileBeBlocked } = require('./permissions'); // Portiert aus main.lua mapProfile() function mapProfile(row) { if (!row) return null; const profile = { id: row.id, account_id: row.account_id, profile_type: row.profile_type, handle: row.handle, display_name: row.display_name, avatar_url: row.avatar_url || '', banner_url: row.banner_url || '', bio: row.bio || '', location: row.location || '', email_contact: row.email_contact || '', phone_contact: row.phone_contact || '', is_verified: decodeBool(row.is_verified), is_lifeinvader_staff: decodeBool(row.is_lifeinvader_staff), is_active: row.is_active === undefined || row.is_active === null || decodeBool(row.is_active), is_locked: decodeBool(row.is_locked), can_post: decodeBool(row.can_post), can_edit_profile: decodeBool(row.can_edit_profile), can_be_blocked: canProfileBeBlocked(row.profile_type, row.is_lifeinvader_staff), }; if (row.followers_count !== undefined) profile.followers_count = Number(row.followers_count) || 0; if (row.following_count !== undefined) profile.following_count = Number(row.following_count) || 0; return profile; } // Alle Profile, auf die der Account zugreifen kann (eigene + Mitgliedschaften) async function getAccessibleProfiles(account) { const profiles = []; const seen = new Set(); const ownRows = await db.q( `SELECT p.*, 1 AS can_post, 1 AS can_edit_profile FROM bleeter_profiles p WHERE p.account_id = ? AND p.is_active = 1 AND p.is_locked = 0 ORDER BY FIELD(p.profile_type, 'private','small_business','company','authority','lifeinvader'), p.display_name`, [account.id] ); for (const row of ownRows) { const profile = mapProfile(row); profiles.push(profile); seen.add(profile.id); } const memberRows = await db.q( `SELECT p.*, m.can_post, m.can_edit_profile FROM bleeter_profile_members m JOIN bleeter_profiles p ON p.id = m.profile_id WHERE m.char_id = ? AND p.is_active = 1 AND p.is_locked = 0 ORDER BY p.display_name`, [account.char_id] ); for (const row of memberRows) { if (!seen.has(row.id)) { const profile = mapProfile(row); profiles.push(profile); seen.add(profile.id); } } return profiles; } // Das aktuell handelnde Profil (per profileId vom Client, sonst erstes). // Gibt { profile, profiles } zurueck. profile=null wenn kein Profil vorhanden. async function resolveActingProfile(account, profileId) { const profiles = await getAccessibleProfiles(account); let profile = null; if (profileId) { profile = profiles.find(p => Number(p.id) === Number(profileId)) || null; } if (!profile) profile = profiles[0] || null; return { profile, profiles }; } // Zielprofil fuer Follow/Block/Moderation laden. // includeLocked=true fuer Moderationsaktionen. async function findTargetProfile(payload, includeLocked = false) { const id = Number(payload && (payload.targetId || payload.profileId)); const handle = payload && payload.handle ? String(payload.handle).toLowerCase() : null; let row = null; if (id) { row = await db.q1('SELECT * FROM bleeter_profiles WHERE id = ?', [id]); } else if (handle) { row = await db.q1('SELECT * FROM bleeter_profiles WHERE handle = ?', [handle]); } if (!row) return null; if (!decodeBool(row.is_active)) return null; if (!includeLocked && decodeBool(row.is_locked)) return null; return mapProfile(row); } module.exports = { mapProfile, getAccessibleProfiles, resolveActingProfile, findTargetProfile };