Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision 4c127830f939c716f037d2e743e8b9f8a8881492)
+++ src/services/ActivityPubService.js	(revision 8ad17845c70fe0c28f24c02668b8d85500158d4c)
@@ -1025,5 +1025,8 @@
   const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
   if (!base || !site || !site.slug) return { error: 'config' };
-  const actorUrl = await webfingerResolve(handle);
+  // Accept either an @user@host handle (WebFinger) or a profile/actor URL directly
+  // (the authorize_interaction Follow flow passes a URL).
+  const s = String(handle || '').trim();
+  const actorUrl = /^https?:\/\//i.test(s) ? (safeUrl(s) || null) : await webfingerResolve(s);
   if (!actorUrl) return { error: 'not_found' };
   const actor = await fetchActor(actorUrl).catch(() => null);
@@ -1039,4 +1042,17 @@
   console.log('[AP] follow', site.slug, '→', actor.id);
   return { ok: true, name: ai.name, handle: ai.handle };
+}
+
+// Resolve a profile URL or @handle to a followable remote actor (for the
+// authorize_interaction "Follow" flow). Returns display fields + inbox, or null
+// when it isn't a reachable actor (e.g. the input was a post, not a profile).
+export async function resolveRemoteActor(input) {
+  const s = String(input || '').trim();
+  const actorUrl = /^https?:\/\//i.test(s) ? (safeUrl(s) || null) : await webfingerResolve(s);
+  if (!actorUrl) return null;
+  const actor = await fetchActor(actorUrl).catch(() => null);
+  if (!actor || !actor.id || !actor.inbox) return null;
+  const ai = actorInfo(actor, actor.id);
+  return { actor_uri: actor.id, actor_name: ai.name, actor_handle: ai.handle, actor_url: ai.url, actor_icon: ai.icon, inbox: actor.inbox };
 }
 
@@ -1162,5 +1178,5 @@
   getInteractions, getInteractionById, buildReplyNote, getOutboxNote, deliverReply, resolveRemoteNote,
   listOutbox, deliverOutboxDelete,
-  webfingerResolve, followActor, unfollowActor, listFollowing, getTimeline, sendInteraction,
+  webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, getTimeline, sendInteraction,
   getNotifications, listBlocks, isBlockedAny, blockTarget, unblock,
   deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker,
